diff --git a/.github/classifier.yml b/.github/classifier.yml index 330cc3d0aa1..e7a79f7b64c 100644 --- a/.github/classifier.yml +++ b/.github/classifier.yml @@ -81,7 +81,7 @@ hot-exit: [], html: [], install-update: [], - integrated-terminal: [ Tyriar ], + integrated-terminal: [], integration-test: [], intellisense-config: [], issue-reporter: [ RMacfarlane ], diff --git a/.gitignore b/.gitignore index 68834eb43ad..160c42ed74b 100644 --- a/.gitignore +++ b/.gitignore @@ -18,9 +18,11 @@ out-vscode-min/ out-vscode-reh/ out-vscode-reh-min/ out-vscode-reh-pkg/ +out-vscode-reh-web/ +out-vscode-reh-web-min/ +out-vscode-reh-web-pkg/ out-vscode-web/ out-vscode-web-min/ -out-vscode-web-pkg/ src/vs/server resources/server build/node_modules diff --git a/build/.cachesalt b/build/.cachesalt index 56a6051ca2b..105ce86ae3c 100644 --- a/build/.cachesalt +++ b/build/.cachesalt @@ -1 +1 @@ -1 \ No newline at end of file +2019-07-11T05:47:05.444Z diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index d8b2c009c4a..b712e072849 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -6,8 +6,8 @@ steps: - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 inputs: - keyfile: '.build/commit' - targetfolder: '.build, **/out-build, **/out-vscode-min, **/out-vscode-reh-min, **/out-vscode-web-min' + keyfile: 'build/.cachesalt, .build/commit' + targetfolder: '.build, out-build, out-vscode-min, out-vscode-reh-min, out-vscode-reh-web-min' vstsFeed: 'npm-vscode' platformIndependent: true alias: 'Compilation' @@ -89,9 +89,7 @@ steps: VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ yarn gulp vscode-reh-darwin-min-ci VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ - yarn gulp vscode-web-darwin-min-ci - AZURE_STORAGE_ACCESS_KEY="$(ticino-storage-key)" \ - yarn gulp upload-vscode-sourcemaps + yarn gulp vscode-reh-web-darwin-min-ci displayName: Build - script: | diff --git a/build/azure-pipelines/darwin/publish.sh b/build/azure-pipelines/darwin/publish.sh index 6bc80ce04e8..fa453bcaff5 100755 --- a/build/azure-pipelines/darwin/publish.sh +++ b/build/azure-pipelines/darwin/publish.sh @@ -30,7 +30,7 @@ node build/azure-pipelines/common/publish.js \ ../vscode-server-darwin.zip # publish hockeyapp symbols -node build/azure-pipelines/common/symbols.js "$VSCODE_MIXIN_PASSWORD" "$VSCODE_HOCKEYAPP_TOKEN" "$VSCODE_ARCH" "$VSCODE_HOCKEYAPP_ID_MACOS" +node build/azure-pipelines/common/symbols.js "$VSCODE_MIXIN_PASSWORD" "$VSCODE_HOCKEYAPP_TOKEN" x64 "$VSCODE_HOCKEYAPP_ID_MACOS" # upload configuration yarn gulp upload-vscode-configuration diff --git a/build/azure-pipelines/linux/product-build-linux-multiarch.yml b/build/azure-pipelines/linux/product-build-linux-multiarch.yml index c4e1e05e502..dff5ae2ceaf 100644 --- a/build/azure-pipelines/linux/product-build-linux-multiarch.yml +++ b/build/azure-pipelines/linux/product-build-linux-multiarch.yml @@ -6,8 +6,8 @@ steps: - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 inputs: - keyfile: '.build/commit' - targetfolder: '.build, **/out-build, **/out-vscode-min, **/out-vscode-reh-min, **/out-vscode-web-min' + keyfile: 'build/.cachesalt, .build/commit' + targetfolder: '.build, out-build, out-vscode-min, out-vscode-reh-min, out-vscode-reh-web-min' vstsFeed: 'npm-vscode' platformIndependent: true alias: 'Compilation' diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index 76c86e32323..e97f5cfdeff 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -6,8 +6,8 @@ steps: - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 inputs: - keyfile: '.build/commit' - targetfolder: '.build, **/out-build, **/out-vscode-min, **/out-vscode-reh-min, **/out-vscode-web-min' + keyfile: 'build/.cachesalt, .build/commit' + targetfolder: '.build, out-build, out-vscode-min, out-vscode-reh-min, out-vscode-reh-web-min' vstsFeed: 'npm-vscode' platformIndependent: true alias: 'Compilation' @@ -34,8 +34,6 @@ steps: - script: | set -e - export npm_config_arch="$(VSCODE_ARCH)" - cat << EOF > ~/.netrc machine github.com login vscode @@ -86,22 +84,22 @@ steps: - script: | set -e VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ - yarn gulp vscode-linux-$VSCODE_ARCH-min-ci + yarn gulp vscode-linux-x64-min-ci VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ - yarn gulp vscode-reh-linux-$VSCODE_ARCH-min-ci + yarn gulp vscode-reh-linux-x64-min-ci VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ - yarn gulp vscode-web-linux-$VSCODE_ARCH-min-ci + yarn gulp vscode-reh-web-linux-x64-min-ci displayName: Build - script: | set -e - yarn gulp "electron-$(VSCODE_ARCH)" + yarn gulp "electron-x64" # xvfb seems to be crashing often, let's make sure it's always up service xvfb start DISPLAY=:10 ./scripts/test.sh --build --tfs "Unit Tests" - # yarn smoketest -- --build "$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)" + # yarn smoketest -- --build "$(agent.builddirectory)/VSCode-linux-x64" displayName: Run unit tests condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) @@ -117,7 +115,7 @@ steps: - task: PublishPipelineArtifact@0 displayName: 'Publish Pipeline Artifact' inputs: - artifactName: snap-$(VSCODE_ARCH) + artifactName: snap-x64 targetPath: .build/linux/snap-tarball - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 diff --git a/build/azure-pipelines/linux/publish.sh b/build/azure-pipelines/linux/publish.sh index a6b48389d58..5fc86d02d60 100755 --- a/build/azure-pipelines/linux/publish.sh +++ b/build/azure-pipelines/linux/publish.sh @@ -4,7 +4,7 @@ REPO="$(pwd)" ROOT="$REPO/.." # Publish tarball -PLATFORM_LINUX="linux-$VSCODE_ARCH" +PLATFORM_LINUX="linux-x64" BUILDNAME="VSCode-$PLATFORM_LINUX" BUILD="$ROOT/$BUILDNAME" BUILD_VERSION="$(date +%s)" @@ -19,24 +19,22 @@ rm -rf $ROOT/code-*.tar.* node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "$PLATFORM_LINUX" archive-unsigned "$TARBALL_FILENAME" "$VERSION" true "$TARBALL_PATH" # Publish Remote Extension Host -if [[ "$VSCODE_ARCH" != "ia32" ]]; then - LEGACY_SERVER_BUILD_NAME="vscode-reh-$PLATFORM_LINUX" - SERVER_BUILD_NAME="vscode-server-$PLATFORM_LINUX" - SERVER_TARBALL_FILENAME="vscode-server-$PLATFORM_LINUX.tar.gz" - SERVER_TARBALL_PATH="$ROOT/$SERVER_TARBALL_FILENAME" +LEGACY_SERVER_BUILD_NAME="vscode-reh-$PLATFORM_LINUX" +SERVER_BUILD_NAME="vscode-server-$PLATFORM_LINUX" +SERVER_TARBALL_FILENAME="vscode-server-$PLATFORM_LINUX.tar.gz" +SERVER_TARBALL_PATH="$ROOT/$SERVER_TARBALL_FILENAME" - rm -rf $ROOT/vscode-server-*.tar.* - (cd $ROOT && mv $LEGACY_SERVER_BUILD_NAME $SERVER_BUILD_NAME && tar -czf $SERVER_TARBALL_PATH $SERVER_BUILD_NAME) +rm -rf $ROOT/vscode-server-*.tar.* +(cd $ROOT && mv $LEGACY_SERVER_BUILD_NAME $SERVER_BUILD_NAME && tar --owner=0 --group=0 -czf $SERVER_TARBALL_PATH $SERVER_BUILD_NAME) - node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "server-$PLATFORM_LINUX" archive-unsigned "$SERVER_TARBALL_FILENAME" "$VERSION" true "$SERVER_TARBALL_PATH" -fi +node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "server-$PLATFORM_LINUX" archive-unsigned "$SERVER_TARBALL_FILENAME" "$VERSION" true "$SERVER_TARBALL_PATH" # Publish hockeyapp symbols -node build/azure-pipelines/common/symbols.js "$VSCODE_MIXIN_PASSWORD" "$VSCODE_HOCKEYAPP_TOKEN" "$VSCODE_ARCH" "$VSCODE_HOCKEYAPP_ID_LINUX64" +node build/azure-pipelines/common/symbols.js "$VSCODE_MIXIN_PASSWORD" "$VSCODE_HOCKEYAPP_TOKEN" "x64" "$VSCODE_HOCKEYAPP_ID_LINUX64" # Publish DEB -yarn gulp "vscode-linux-$VSCODE_ARCH-build-deb" -PLATFORM_DEB="linux-deb-$VSCODE_ARCH" +yarn gulp "vscode-linux-x64-build-deb" +PLATFORM_DEB="linux-deb-x64" DEB_ARCH="amd64" DEB_FILENAME="$(ls $REPO/.build/linux/deb/$DEB_ARCH/deb/)" DEB_PATH="$REPO/.build/linux/deb/$DEB_ARCH/deb/$DEB_FILENAME" @@ -44,8 +42,8 @@ DEB_PATH="$REPO/.build/linux/deb/$DEB_ARCH/deb/$DEB_FILENAME" node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "$PLATFORM_DEB" package "$DEB_FILENAME" "$VERSION" true "$DEB_PATH" # Publish RPM -yarn gulp "vscode-linux-$VSCODE_ARCH-build-rpm" -PLATFORM_RPM="linux-rpm-$VSCODE_ARCH" +yarn gulp "vscode-linux-x64-build-rpm" +PLATFORM_RPM="linux-rpm-x64" RPM_ARCH="x86_64" RPM_FILENAME="$(ls $REPO/.build/linux/rpm/$RPM_ARCH/ | grep .rpm)" RPM_PATH="$REPO/.build/linux/rpm/$RPM_ARCH/$RPM_FILENAME" @@ -53,10 +51,10 @@ RPM_PATH="$REPO/.build/linux/rpm/$RPM_ARCH/$RPM_FILENAME" node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "$PLATFORM_RPM" package "$RPM_FILENAME" "$VERSION" true "$RPM_PATH" # Publish Snap -yarn gulp "vscode-linux-$VSCODE_ARCH-prepare-snap" +yarn gulp "vscode-linux-x64-prepare-snap" # Pack snap tarball artifact, in order to preserve file perms mkdir -p $REPO/.build/linux/snap-tarball -SNAP_TARBALL_PATH="$REPO/.build/linux/snap-tarball/snap-$VSCODE_ARCH.tar.gz" +SNAP_TARBALL_PATH="$REPO/.build/linux/snap-tarball/snap-x64.tar.gz" rm -rf $SNAP_TARBALL_PATH (cd .build/linux && tar -czf $SNAP_TARBALL_PATH snap) diff --git a/build/azure-pipelines/linux/snap-build-linux.yml b/build/azure-pipelines/linux/snap-build-linux.yml index 9dbe920b87b..4c3f602e8ce 100644 --- a/build/azure-pipelines/linux/snap-build-linux.yml +++ b/build/azure-pipelines/linux/snap-build-linux.yml @@ -16,7 +16,7 @@ steps: - task: DownloadPipelineArtifact@0 displayName: 'Download Pipeline Artifact' inputs: - artifactName: snap-$(VSCODE_ARCH) + artifactName: snap-x64 targetPath: .build/linux/snap-tarball - script: | @@ -31,14 +31,13 @@ steps: # Define variables REPO="$(pwd)" - ARCH="$(VSCODE_ARCH)" - SNAP_ROOT="$REPO/.build/linux/snap/$ARCH" + SNAP_ROOT="$REPO/.build/linux/snap/x64" # Install build dependencies (cd build && yarn) # Unpack snap tarball artifact, in order to preserve file perms - SNAP_TARBALL_PATH="$REPO/.build/linux/snap-tarball/snap-$ARCH.tar.gz" + SNAP_TARBALL_PATH="$REPO/.build/linux/snap-tarball/snap-x64.tar.gz" (cd .build/linux && tar -xzf $SNAP_TARBALL_PATH) # Create snap package @@ -52,4 +51,4 @@ steps: # Publish snap package AZURE_DOCUMENTDB_MASTERKEY="$(builds-docdb-key-readwrite)" \ AZURE_STORAGE_ACCESS_KEY_2="$(vscode-storage-key)" \ - node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "linux-snap-$ARCH" package "$SNAP_FILENAME" "$VERSION" true "$SNAP_PATH" \ No newline at end of file + node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "linux-snap-x64" package "$SNAP_FILENAME" "$VERSION" true "$SNAP_PATH" \ No newline at end of file diff --git a/build/azure-pipelines/product-build.yml b/build/azure-pipelines/product-build.yml index 0c4dba0333a..469494c7d58 100644 --- a/build/azure-pipelines/product-build.yml +++ b/build/azure-pipelines/product-build.yml @@ -10,15 +10,12 @@ jobs: - job: Compile pool: vmImage: 'Ubuntu-16.04' - variables: - VSCODE_ARCH: x64 container: vscode-x64 steps: - template: product-compile.yml - job: Windows condition: and(succeeded(), eq(variables['VSCODE_COMPILE_ONLY'], 'false'), eq(variables['VSCODE_BUILD_WIN32'], 'true')) - timeoutInMinutes: 120 pool: vmImage: VS2017-Win2016 variables: @@ -30,7 +27,6 @@ jobs: - job: Windows32 condition: and(succeeded(), eq(variables['VSCODE_COMPILE_ONLY'], 'false'), eq(variables['VSCODE_BUILD_WIN32_32BIT'], 'true')) - timeoutInMinutes: 120 pool: vmImage: VS2017-Win2016 variables: @@ -42,11 +38,8 @@ jobs: - job: Linux condition: and(succeeded(), eq(variables['VSCODE_COMPILE_ONLY'], 'false'), eq(variables['VSCODE_BUILD_LINUX'], 'true')) - timeoutInMinutes: 120 pool: vmImage: 'Ubuntu-16.04' - variables: - VSCODE_ARCH: x64 container: vscode-x64 dependsOn: - Compile @@ -55,11 +48,8 @@ jobs: - job: LinuxSnap condition: and(succeeded(), eq(variables['VSCODE_COMPILE_ONLY'], 'false'), eq(variables['VSCODE_BUILD_LINUX'], 'true')) - timeoutInMinutes: 120 pool: vmImage: 'Ubuntu-16.04' - variables: - VSCODE_ARCH: x64 container: snapcraft dependsOn: Linux steps: @@ -67,7 +57,6 @@ jobs: - job: LinuxArmhf condition: and(succeeded(), eq(variables['VSCODE_COMPILE_ONLY'], 'false'), eq(variables['VSCODE_BUILD_LINUX_ARMHF'], 'true'), ne(variables['VSCODE_QUALITY'], 'stable')) - timeoutInMinutes: 120 pool: vmImage: 'Ubuntu-16.04' variables: @@ -79,7 +68,6 @@ jobs: - job: LinuxAlpine condition: and(succeeded(), eq(variables['VSCODE_COMPILE_ONLY'], 'false'), eq(variables['VSCODE_BUILD_LINUX_ALPINE'], 'true'), ne(variables['VSCODE_QUALITY'], 'stable')) - timeoutInMinutes: 120 pool: vmImage: 'Ubuntu-16.04' variables: @@ -89,9 +77,19 @@ jobs: steps: - template: linux/product-build-linux-multiarch.yml +- job: LinuxWeb + condition: and(succeeded(), eq(variables['VSCODE_COMPILE_ONLY'], 'false'), eq(variables['VSCODE_BUILD_WEB'], 'true')) + pool: + vmImage: 'Ubuntu-16.04' + variables: + VSCODE_ARCH: x64 + dependsOn: + - Compile + steps: + - template: web/product-build-web.yml + - job: macOS condition: and(succeeded(), eq(variables['VSCODE_COMPILE_ONLY'], 'false'), eq(variables['VSCODE_BUILD_MACOS'], 'true')) - timeoutInMinutes: 120 pool: vmImage: macOS 10.13 dependsOn: diff --git a/build/azure-pipelines/product-compile.yml b/build/azure-pipelines/product-compile.yml index 5b425f60fb6..e5105326e7b 100644 --- a/build/azure-pipelines/product-compile.yml +++ b/build/azure-pipelines/product-compile.yml @@ -6,8 +6,8 @@ steps: - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 inputs: - keyfile: '.build/commit' - targetfolder: '.build, **/out-build, **/out-vscode-min, **/out-vscode-reh-min, **/out-vscode-web-min' + keyfile: 'build/.cachesalt, .build/commit' + targetfolder: '.build, out-build, out-vscode-min, out-vscode-reh-min, out-vscode-reh-web-min' vstsFeed: 'npm-vscode' platformIndependent: true alias: 'Compilation' @@ -31,8 +31,6 @@ steps: - script: | set -e - export npm_config_arch="$(VSCODE_ARCH)" - cat << EOF > ~/.netrc machine github.com login vscode @@ -105,14 +103,21 @@ steps: yarn gulp compile-extensions-build yarn gulp minify-vscode yarn gulp minify-vscode-reh - yarn gulp minify-vscode-web + yarn gulp minify-vscode-reh-web displayName: Compile condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true')) +- script: | + set -e + AZURE_STORAGE_ACCESS_KEY="$(ticino-storage-key)" \ + node build/azure-pipelines/upload-sourcemaps + displayName: Upload sourcemaps + condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true')) + - task: 1ESLighthouseEng.PipelineArtifactCaching.SaveCacheV1.SaveCache@1 inputs: - keyfile: '.build/commit' - targetfolder: '.build, **/out-build, **/out-vscode-min, **/out-vscode-reh-min, **/out-vscode-web-min' + keyfile: 'build/.cachesalt, .build/commit' + targetfolder: '.build, out-build, out-vscode-min, out-vscode-reh-min, out-vscode-reh-web-min' vstsFeed: 'npm-vscode' platformIndependent: true alias: 'Compilation' diff --git a/build/azure-pipelines/upload-sourcemaps.js b/build/azure-pipelines/upload-sourcemaps.js new file mode 100644 index 00000000000..ac3bd55a7f5 --- /dev/null +++ b/build/azure-pipelines/upload-sourcemaps.js @@ -0,0 +1,39 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +const path = require('path'); +const es = require('event-stream'); +const azure = require('gulp-azure-storage'); +const vfs = require('vinyl-fs'); +const util = require('../lib/util'); +const root = path.dirname(path.dirname(__dirname)); +const commit = util.getVersion(root); + +function main() { + const vs = vfs.src('out-vscode-min/**/*.map', { base: 'out-vscode-min' }) // client source-maps only + .pipe(es.mapSync(f => { + f.path = `${f.base}/core/${f.relative}`; + return f; + })); + + const extensionsOut = vfs.src(['.build/extensions/**/*.js.map', '!**/node_modules/**'], { base: '.build' }); + + return es.merge(vs, extensionsOut) + .pipe(es.through(function (data) { + // debug + console.log('Uploading Sourcemap', data.relative); + this.emit('data', data); + })) + .pipe(azure.upload({ + account: process.env.AZURE_STORAGE_ACCOUNT, + key: process.env.AZURE_STORAGE_ACCESS_KEY, + container: 'sourcemaps', + prefix: commit + '/' + })); +} + +main(); \ No newline at end of file diff --git a/build/azure-pipelines/web/product-build-web.yml b/build/azure-pipelines/web/product-build-web.yml new file mode 100644 index 00000000000..7c65dc982f0 --- /dev/null +++ b/build/azure-pipelines/web/product-build-web.yml @@ -0,0 +1,96 @@ +steps: +- script: | + mkdir -p .build + echo -n $BUILD_SOURCEVERSION > .build/commit + displayName: Prepare cache flag + +- task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 + inputs: + keyfile: 'build/.cachesalt, .build/commit' + targetfolder: '.build, out-build, out-vscode-min, out-vscode-reh-min, out-vscode-reh-web-min' + vstsFeed: 'npm-vscode' + platformIndependent: true + alias: 'Compilation' + +- script: | + set -e + exit 1 + displayName: Check RestoreCache + condition: and(succeeded(), ne(variables['CacheRestored-Compilation'], 'true')) + +- task: NodeTool@0 + inputs: + versionSpec: "10.15.1" + +- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2 + inputs: + versionSpec: "1.10.1" + +- task: AzureKeyVault@1 + displayName: 'Azure Key Vault: Get Secrets' + inputs: + azureSubscription: 'vscode-builds-subscription' + KeyVaultName: vscode + +- script: | + set -e + cat << EOF > ~/.netrc + machine github.com + login vscode + password $(github-distro-mixin-password) + EOF + + git config user.email "vscode@microsoft.com" + git config user.name "VSCode" + displayName: Prepare tooling + +- script: | + set -e + git remote add distro "https://github.com/$(VSCODE_MIXIN_REPO).git" + git fetch distro + git merge $(node -p "require('./package.json').distro") + displayName: Merge distro + +# - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 +# inputs: +# keyfile: 'build/.cachesalt, .yarnrc, remote/.yarnrc, **/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock' +# targetfolder: '**/node_modules, !**/node_modules/**/node_modules' +# vstsFeed: 'npm-vscode' + +- script: | + set -e + CHILD_CONCURRENCY=1 yarn --frozen-lockfile + displayName: Install dependencies + # condition: and(succeeded(), ne(variables['CacheRestored'], 'true')) + +# - task: 1ESLighthouseEng.PipelineArtifactCaching.SaveCacheV1.SaveCache@1 +# inputs: +# keyfile: 'build/.cachesalt, .yarnrc, remote/.yarnrc, **/yarn.lock, !**/node_modules/**/yarn.lock, !**/.*/**/yarn.lock' +# targetfolder: '**/node_modules, !**/node_modules/**/node_modules' +# vstsFeed: 'npm-vscode' +# condition: and(succeeded(), ne(variables['CacheRestored'], 'true')) + +# - script: | +# set -e +# yarn postinstall +# displayName: Run postinstall scripts +# condition: and(succeeded(), eq(variables['CacheRestored'], 'true')) + +- script: | + set -e + node build/azure-pipelines/mixin + displayName: Mix in quality + +- script: | + set -e + VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ + yarn gulp vscode-web-min-ci + displayName: Build + +- script: | + set -e + AZURE_DOCUMENTDB_MASTERKEY="$(builds-docdb-key-readwrite)" \ + AZURE_STORAGE_ACCESS_KEY_2="$(vscode-storage-key)" \ + VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ + ./build/azure-pipelines/web/publish.sh + displayName: Publish diff --git a/build/azure-pipelines/web/publish.sh b/build/azure-pipelines/web/publish.sh new file mode 100755 index 00000000000..9d662fcfe8b --- /dev/null +++ b/build/azure-pipelines/web/publish.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +set -e +REPO="$(pwd)" +ROOT="$REPO/.." + +# Publish Web Client +WEB_BUILD_NAME="vscode-web" +WEB_TARBALL_FILENAME="vscode-web.tar.gz" +WEB_TARBALL_PATH="$ROOT/$WEB_TARBALL_FILENAME" + +rm -rf $ROOT/vscode-web.tar.* + +(cd $ROOT && tar --owner=0 --group=0 -czf $WEB_TARBALL_PATH $WEB_BUILD_NAME) + +node build/azure-pipelines/common/publish.js "$VSCODE_QUALITY" "web-standalone" archive-unsigned "$WEB_TARBALL_FILENAME" "$VERSION" true "$WEB_TARBALL_PATH" diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index fc14cc0abec..66583616c6d 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -6,8 +6,8 @@ steps: - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 inputs: - keyfile: '.build/commit' - targetfolder: '.build, **/out-build, **/out-vscode-min, **/out-vscode-reh-min, **/out-vscode-web-min' + keyfile: 'build/.cachesalt, .build/commit' + targetfolder: '.build, out-build, out-vscode-min, out-vscode-reh-min, out-vscode-reh-web-min' vstsFeed: 'npm-vscode' platformIndependent: true alias: 'Compilation' @@ -98,7 +98,7 @@ steps: $env:VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" exec { yarn gulp "vscode-win32-$env:VSCODE_ARCH-min-ci" } exec { yarn gulp "vscode-reh-win32-$env:VSCODE_ARCH-min-ci" } - exec { yarn gulp "vscode-web-win32-$env:VSCODE_ARCH-min-ci" } + exec { yarn gulp "vscode-reh-web-win32-$env:VSCODE_ARCH-min-ci" } exec { yarn gulp "vscode-win32-$env:VSCODE_ARCH-inno-updater" } displayName: Build diff --git a/build/gulpfile.reh.js b/build/gulpfile.reh.js index 8828a0d394f..8784602db3e 100644 --- a/build/gulpfile.reh.js +++ b/build/gulpfile.reh.js @@ -43,11 +43,11 @@ gulp.task('vscode-reh-linux-x64-min', noop); gulp.task('vscode-reh-linux-armhf-min', noop); gulp.task('vscode-reh-linux-alpine-min', noop); -gulp.task('vscode-web-win32-ia32-min', noop); -gulp.task('vscode-web-win32-x64-min', noop); -gulp.task('vscode-web-darwin-min', noop); -gulp.task('vscode-web-linux-x64-min', noop); -gulp.task('vscode-web-linux-alpine-min', noop); +gulp.task('vscode-reh-web-win32-ia32-min', noop); +gulp.task('vscode-reh-web-win32-x64-min', noop); +gulp.task('vscode-reh-web-darwin-min', noop); +gulp.task('vscode-reh-web-linux-x64-min', noop); +gulp.task('vscode-reh-web-linux-alpine-min', noop); function getNodeVersion() { const yarnrc = fs.readFileSync(path.join(REPO_ROOT, 'remote', '.yarnrc'), 'utf8'); diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index a3478121f28..99bd930a91c 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -63,7 +63,7 @@ const vscodeResources = [ 'out-build/bootstrap-amd.js', 'out-build/bootstrap-window.js', 'out-build/paths.js', - 'out-build/vs/**/*.{svg,png,cur,html}', + 'out-build/vs/**/*.{svg,png,html}', '!out-build/vs/code/browser/**/*.html', 'out-build/vs/base/common/performance.js', 'out-build/vs/base/node/languagePacks.js', @@ -86,12 +86,6 @@ const vscodeResources = [ '!**/test/**' ]; -const BUNDLED_FILE_HEADER = [ - '/*!--------------------------------------------------------', - ' * Copyright (C) Microsoft Corporation. All rights reserved.', - ' *--------------------------------------------------------*/' -].join('\n'); - const optimizeVSCodeTask = task.define('optimize-vscode', task.series( util.rimraf('out-vscode'), common.optimizeTask({ @@ -99,7 +93,6 @@ const optimizeVSCodeTask = task.define('optimize-vscode', task.series( entryPoints: vscodeEntryPoints, resources: vscodeResources, loaderConfig: common.loaderConfig(nodeModules), - header: BUNDLED_FILE_HEADER, out: 'out-vscode', bundleInfo: undefined }) @@ -265,16 +258,14 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op const src = gulp.src(out + '/**', { base: '.' }) .pipe(rename(function (path) { path.dirname = path.dirname.replace(new RegExp('^' + out), 'out'); })) - .pipe(util.setExecutableBit(['**/*.sh'])) - .pipe(filter(['**', '!**/*.js.map'])); - - const root = path.resolve(path.join(__dirname, '..')); + .pipe(util.setExecutableBit(['**/*.sh'])); const extensions = gulp.src('.build/extensions/**', { base: '.build', dot: true }); - const sources = es.merge(src, extensions); + + const sources = es.merge(src, extensions) + .pipe(filter(['**', '!**/*.js.map'], { dot: true })); let version = packageJson.version; - // @ts-ignore JSON checking: quality is optional const quality = product.quality; if (quality && quality !== 'stable') { @@ -309,6 +300,7 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op const telemetry = gulp.src('.build/telemetry/**', { base: '.build/telemetry', dot: true }); + const root = path.resolve(path.join(__dirname, '..')); const dependenciesSrc = _.flatten(productionDependencies.map(d => path.relative(root, d.path)).map(d => [`${d}/**`, `!${d}/**/{test,tests}/**`])); const deps = gulp.src(dependenciesSrc, { base: '.', dot: true }) @@ -535,32 +527,6 @@ gulp.task('vscode-translations-import', function () { })); }); -// Sourcemaps - -gulp.task('upload-vscode-sourcemaps', () => { - const vs = gulp.src('out-vscode-min/**/*.map', { base: 'out-vscode-min' }) // client source-maps only - .pipe(es.mapSync(f => { - f.path = `${f.base}/core/${f.relative}`; - return f; - })); - - const extensionsOut = gulp.src(['extensions/**/out/**/*.map', '!extensions/**/node_modules/**'], { base: '.' }); - const extensionsDist = gulp.src(['extensions/**/dist/**/*.map', '!extensions/**/node_modules/**'], { base: '.' }); - - return es.merge(vs, extensionsOut, extensionsDist) - .pipe(es.through(function (data) { - // debug - console.log('Uploading Sourcemap', data.relative); - this.emit('data', data); - })) - .pipe(azure.upload({ - account: process.env.AZURE_STORAGE_ACCOUNT, - key: process.env.AZURE_STORAGE_ACCESS_KEY, - container: 'sourcemaps', - prefix: commit + '/' - })); -}); - // This task is only run for the MacOS build const generateVSCodeConfigurationTask = task.define('generate-vscode-configuration', () => { return new Promise((resolve, reject) => { diff --git a/build/gulpfile.vscode.web.js b/build/gulpfile.vscode.web.js new file mode 100644 index 00000000000..11da75e482d --- /dev/null +++ b/build/gulpfile.vscode.web.js @@ -0,0 +1,151 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +const gulp = require('gulp'); +const path = require('path'); +const es = require('event-stream'); +const util = require('./lib/util'); +const task = require('./lib/task'); +const common = require('./lib/optimize'); +const product = require('../product.json'); +const rename = require('gulp-rename'); +const filter = require('gulp-filter'); +const json = require('gulp-json-editor'); +const _ = require('underscore'); +const deps = require('./dependencies'); +const vfs = require('vinyl-fs'); +const packageJson = require('../package.json'); +const { compileBuildTask } = require('./gulpfile.compile'); + +const REPO_ROOT = path.dirname(__dirname); +const commit = util.getVersion(REPO_ROOT); +const BUILD_ROOT = path.dirname(REPO_ROOT); +const WEB_FOLDER = path.join(REPO_ROOT, 'remote', 'web'); + +const productionDependencies = deps.getProductionDependencies(WEB_FOLDER); + +const nodeModules = Object.keys(product.dependencies || {}) + .concat(_.uniq(productionDependencies.map(d => d.name))); + +const vscodeWebResources = [ + + // Workbench + 'out-build/vs/{base,platform,editor,workbench}/**/*.{svg,png,html}', + 'out-build/vs/base/browser/ui/octiconLabel/octicons/**', + 'out-build/vs/**/markdown.css', + + // Webview + 'out-build/vs/workbench/contrib/webview/browser/pre/*.js', + + // Excludes + '!out-build/vs/**/{node,electron-browser,electron-main}/**', + '!out-build/vs/editor/standalone/**', + '!out-build/vs/workbench/**/*-tb.png', + '!**/test/**' +]; + +const buildfile = require('../src/buildfile'); + +const vscodeWebEntryPoints = [ + buildfile.workbenchWeb, + buildfile.serviceWorker, + buildfile.keyboardMaps, + buildfile.base +]; + +const optimizeVSCodeWebTask = task.define('optimize-vscode-web', task.series( + util.rimraf('out-vscode-web'), + common.optimizeTask({ + src: 'out-build', + entryPoints: _.flatten(vscodeWebEntryPoints), + otherSources: [], + resources: vscodeWebResources, + loaderConfig: common.loaderConfig(nodeModules), + out: 'out-vscode-web', + bundleInfo: undefined + }) +)); + +const minifyVSCodeWebTask = task.define('minify-vscode-web', task.series( + optimizeVSCodeWebTask, + util.rimraf('out-vscode-web-min'), + common.minifyTask('out-vscode-web', `https://ticino.blob.core.windows.net/sourcemaps/${commit}/core`) +)); +gulp.task(minifyVSCodeWebTask); + +function packageTask(sourceFolderName, destinationFolderName) { + const destination = path.join(BUILD_ROOT, destinationFolderName); + + return () => { + const src = gulp.src(sourceFolderName + '/**', { base: '.' }) + .pipe(rename(function (path) { path.dirname = path.dirname.replace(new RegExp('^' + sourceFolderName), 'out'); })) + .pipe(filter(['**', '!**/*.js.map'])); + + const sources = es.merge(src); + + let version = packageJson.version; + const quality = product.quality; + + if (quality && quality !== 'stable') { + version += '-' + quality; + } + + const name = product.nameShort; + const packageJsonStream = gulp.src(['remote/web/package.json'], { base: 'remote/web' }) + .pipe(json({ name, version })); + + const date = new Date().toISOString(); + + const productJsonStream = gulp.src(['product.json'], { base: '.' }) + .pipe(json({ commit, date })); + + const license = gulp.src(['remote/LICENSE'], { base: 'remote' }); + + const dependenciesSrc = _.flatten(productionDependencies.map(d => path.relative(REPO_ROOT, d.path)).map(d => [`${d}/**`, `!${d}/**/{test,tests}/**`, `!${d}/.bin/**`])); + + const deps = gulp.src(dependenciesSrc, { base: 'remote/web', dot: true }) + .pipe(filter(['**', '!**/package-lock.json'])) + .pipe(util.cleanNodeModules(path.join(__dirname, '.nativeignore'))); + + const favicon = gulp.src('resources/server/favicon.ico', { base: 'resources/server' }); + + let all = es.merge( + packageJsonStream, + productJsonStream, + license, + sources, + deps, + favicon + ); + + let result = all + .pipe(util.skipDirectories()) + .pipe(util.fixWin32DirectoryPermissions()); + + return result.pipe(vfs.dest(destination)); + }; +} + +const dashed = (str) => (str ? `-${str}` : ``); + +['', 'min'].forEach(minified => { + const sourceFolderName = `out-vscode-web${dashed(minified)}`; + const destinationFolderName = `vscode-web`; + + const vscodeWebTaskCI = task.define(`vscode-web${dashed(minified)}-ci`, task.series( + minified ? minifyVSCodeWebTask : optimizeVSCodeWebTask, + util.rimraf(path.join(BUILD_ROOT, destinationFolderName)), + packageTask(sourceFolderName, destinationFolderName) + )); + gulp.task(vscodeWebTaskCI); + + const vscodeWebTask = task.define(`vscode-web${dashed(minified)}`, task.series( + compileBuildTask, + vscodeWebTaskCI + )); + gulp.task(vscodeWebTask); +}); \ No newline at end of file diff --git a/build/lib/extensions.js b/build/lib/extensions.js index e12f8f14568..a73f8cf5864 100644 --- a/build/lib/extensions.js +++ b/build/lib/extensions.js @@ -111,12 +111,6 @@ function fromLocalWebpack(extensionPath) { data.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, function (_m, g1) { return `\n//# sourceMappingURL=${sourceMappingURLBase}/extensions/${path.basename(extensionPath)}/${relativeOutputPath}/${g1}`; }), 'utf8'); - if (/\.js\.map$/.test(data.path)) { - if (!fs.existsSync(path.dirname(data.path))) { - fs.mkdirSync(path.dirname(data.path)); - } - fs.writeFileSync(data.path, data.contents); - } this.emit('data', data); })); }); @@ -195,20 +189,21 @@ function packageLocalExtensionsStream() { }) .filter(({ name }) => excludedExtensions.indexOf(name) === -1) .filter(({ name }) => builtInExtensions.every(b => b.name !== name)); - return es.merge(gulp.src('extensions/node_modules/**', { base: '.' }), ...localExtensionDescriptions.map(extension => { + const nodeModules = gulp.src('extensions/node_modules/**', { base: '.' }); + const localExtensions = localExtensionDescriptions.map(extension => { return fromLocal(extension.path) .pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`)); - })) - .pipe(util2.setExecutableBit(['**/*.sh'])) - .pipe(filter(['**', '!**/*.js.map'])); + }); + return es.merge(nodeModules, ...localExtensions) + .pipe(util2.setExecutableBit(['**/*.sh'])); } exports.packageLocalExtensionsStream = packageLocalExtensionsStream; function packageMarketplaceExtensionsStream() { - return es.merge(builtInExtensions.map(extension => { + const extensions = builtInExtensions.map(extension => { return fromMarketplace(extension.name, extension.version, extension.metadata) .pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`)); - })) - .pipe(util2.setExecutableBit(['**/*.sh'])) - .pipe(filter(['**', '!**/*.js.map'])); + }); + return es.merge(extensions) + .pipe(util2.setExecutableBit(['**/*.sh'])); } exports.packageMarketplaceExtensionsStream = packageMarketplaceExtensionsStream; diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts index 381d56e2abb..94bc81c15df 100644 --- a/build/lib/extensions.ts +++ b/build/lib/extensions.ts @@ -130,12 +130,6 @@ function fromLocalWebpack(extensionPath: string): Stream { return `\n//# sourceMappingURL=${sourceMappingURLBase}/extensions/${path.basename(extensionPath)}/${relativeOutputPath}/${g1}`; }), 'utf8'); - if (/\.js\.map$/.test(data.path)) { - if (!fs.existsSync(path.dirname(data.path))) { - fs.mkdirSync(path.dirname(data.path)); - } - fs.writeFileSync(data.path, data.contents); - } this.emit('data', data); })); }); @@ -237,22 +231,22 @@ export function packageLocalExtensionsStream(): NodeJS.ReadWriteStream { .filter(({ name }) => excludedExtensions.indexOf(name) === -1) .filter(({ name }) => builtInExtensions.every(b => b.name !== name)); - return es.merge( - gulp.src('extensions/node_modules/**', { base: '.' }), - ...localExtensionDescriptions.map(extension => { - return fromLocal(extension.path) - .pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`)); - }) - ) - .pipe(util2.setExecutableBit(['**/*.sh'])) - .pipe(filter(['**', '!**/*.js.map'])); + const nodeModules = gulp.src('extensions/node_modules/**', { base: '.' }); + const localExtensions = localExtensionDescriptions.map(extension => { + return fromLocal(extension.path) + .pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`)); + }); + + return es.merge(nodeModules, ...localExtensions) + .pipe(util2.setExecutableBit(['**/*.sh'])); } export function packageMarketplaceExtensionsStream(): NodeJS.ReadWriteStream { - return es.merge(builtInExtensions.map(extension => { + const extensions = builtInExtensions.map(extension => { return fromMarketplace(extension.name, extension.version, extension.metadata) .pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`)); - })) - .pipe(util2.setExecutableBit(['**/*.sh'])) - .pipe(filter(['**', '!**/*.js.map'])); + }); + + return es.merge(extensions) + .pipe(util2.setExecutableBit(['**/*.sh'])); } diff --git a/build/lib/optimize.js b/build/lib/optimize.js index e4783e18569..2b59d926838 100644 --- a/build/lib/optimize.js +++ b/build/lib/optimize.js @@ -111,12 +111,17 @@ function toBundleStream(src, bundledFileHeader, bundles) { return toConcatStream(src, bundledFileHeader, bundle.sources, bundle.dest); })); } +const DEFAULT_FILE_HEADER = [ + '/*!--------------------------------------------------------', + ' * Copyright (C) Microsoft Corporation. All rights reserved.', + ' *--------------------------------------------------------*/' +].join('\n'); function optimizeTask(opts) { const src = opts.src; const entryPoints = opts.entryPoints; const resources = opts.resources; const loaderConfig = opts.loaderConfig; - const bundledFileHeader = opts.header; + const bundledFileHeader = opts.header || DEFAULT_FILE_HEADER; const bundleLoader = (typeof opts.bundleLoader === 'undefined' ? true : opts.bundleLoader); const out = opts.out; return function () { diff --git a/build/lib/optimize.ts b/build/lib/optimize.ts index d15659ca6ea..6bf1233c303 100644 --- a/build/lib/optimize.ts +++ b/build/lib/optimize.ts @@ -154,7 +154,7 @@ export interface IOptimizeTaskOpts { /** * (basically the Copyright treatment) */ - header: string; + header?: string; /** * (emit bundleInfo.json file) */ @@ -169,12 +169,18 @@ export interface IOptimizeTaskOpts { languages?: Language[]; } +const DEFAULT_FILE_HEADER = [ + '/*!--------------------------------------------------------', + ' * Copyright (C) Microsoft Corporation. All rights reserved.', + ' *--------------------------------------------------------*/' +].join('\n'); + export function optimizeTask(opts: IOptimizeTaskOpts): () => NodeJS.ReadWriteStream { const src = opts.src; const entryPoints = opts.entryPoints; const resources = opts.resources; const loaderConfig = opts.loaderConfig; - const bundledFileHeader = opts.header; + const bundledFileHeader = opts.header || DEFAULT_FILE_HEADER; const bundleLoader = (typeof opts.bundleLoader === 'undefined' ? true : opts.bundleLoader); const out = opts.out; diff --git a/build/lib/watch/package.json b/build/lib/watch/package.json index 3afffdec7d3..b26f589ce0d 100644 --- a/build/lib/watch/package.json +++ b/build/lib/watch/package.json @@ -6,6 +6,6 @@ "private": true, "license": "MIT", "devDependencies": { - "gulp-watch": "^4.3.9" + "gulp-watch": "5.0.1" } } diff --git a/build/lib/watch/yarn.lock b/build/lib/watch/yarn.lock index 0f2ac1e204d..f7d5d976b1f 100644 --- a/build/lib/watch/yarn.lock +++ b/build/lib/watch/yarn.lock @@ -7,23 +7,29 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== -ajv@^4.9.1: - version "4.11.8" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" - integrity sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY= +ansi-colors@1.1.0, ansi-colors@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" + integrity sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA== dependencies: - co "^4.6.0" - json-stable-stringify "^1.0.1" + ansi-wrap "^0.1.0" + +ansi-gray@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" + integrity sha1-KWLPVOyXksSFEKPetSRDaGHvclE= + dependencies: + ansi-wrap "0.1.0" ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= +ansi-wrap@0.1.0, ansi-wrap@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" + integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768= anymatch@^1.3.0: version "1.3.2" @@ -33,6 +39,14 @@ anymatch@^1.3.0: micromatch "^2.1.5" normalize-path "^2.0.0" +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + aproba@^1.0.3: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" @@ -53,97 +67,69 @@ arr-diff@^2.0.0: dependencies: arr-flatten "^1.0.1" -arr-flatten@^1.0.1: +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.0.1, arr-flatten@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== -array-differ@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" - integrity sha1-7/UuN1gknTO+QCuLuOVkuytdQDE= - -array-uniq@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= array-unique@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= -asn1@~0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" - integrity sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y= +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= -assert-plus@1.0.0, assert-plus@^1.0.0: +assign-symbols@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= -assert-plus@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" - integrity sha1-104bh+ev/A24qttwIfP+SBAasjQ= +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== -async-each@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" - integrity sha1-GdOGodntxufByF04iu28xW0zYC0= - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -aws-sign2@~0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" - integrity sha1-FDQt0428yU0OW4fXY81jYSwOeU8= - -aws4@^1.2.1: - version "1.6.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" - integrity sha1-g+9cqGCysy5KDe7e6MdxudtXRx4= +atob@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= -bcrypt-pbkdf@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" - integrity sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40= +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== dependencies: - tweetnacl "^0.14.3" - -beeper@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/beeper/-/beeper-1.1.1.tgz#e6d5ea8c5dad001304a70b22638447f69cb2f809" - integrity sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak= + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" binary-extensions@^1.0.0: version "1.10.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.10.0.tgz#9aeb9a6c5e88638aad171e167f5900abe24835d0" integrity sha1-muuabF6IY4qtFx4Wf1kAq+JINdA= -block-stream@*: - version "0.0.9" - resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" - integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= - dependencies: - inherits "~2.0.0" - -boom@2.x.x: - version "2.10.1" - resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" - integrity sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8= - dependencies: - hoek "2.x.x" - brace-expansion@^1.1.7: version "1.1.8" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" @@ -161,64 +147,127 @@ braces@^1.8.2: preserve "^0.2.0" repeat-element "^1.1.2" -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -chalk@^1.0.0, chalk@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" -chokidar@^1.6.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" - integrity sha1-eY5ol3gVHIB2tLNg5e3SjNortGg= +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== dependencies: - anymatch "^1.3.0" - async-each "^1.0.0" - glob-parent "^2.0.0" - inherits "^2.0.1" + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +chokidar@^2.0.0: + version "2.1.6" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.6.tgz#b6cad653a929e244ce8a834244164d241fa954c5" + integrity sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" is-binary-path "^1.0.0" - is-glob "^2.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" path-is-absolute "^1.0.0" - readdirp "^2.0.0" + readdirp "^2.2.1" + upath "^1.1.1" optionalDependencies: - fsevents "^1.0.0" + fsevents "^1.2.7" + +chownr@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.2.tgz#a18f1e0b269c8a6a5d3c86eb298beb14c3dd7bf6" + integrity sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A== + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +clone-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" + integrity sha1-4+JbIHrE5wGvch4staFnksrD3Fg= clone-stats@^0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" integrity sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE= +clone-stats@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" + integrity sha1-s3gt/4u1R04Yuba/D9/ngvh3doA= + clone@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.3.tgz#298d7e2231660f40c003c2ed3140decf3f53085f" integrity sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8= -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= +clone@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= + +cloneable-readable@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.3.tgz#120a00cb053bfb63a222e709f9683ea2e11d8cec" + integrity sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ== + dependencies: + inherits "^2.0.1" + process-nextick-args "^2.0.0" + readable-stream "^2.3.5" code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= -combined-stream@^1.0.5, combined-stream@~1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" - integrity sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk= +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= dependencies: - delayed-stream "~1.0.0" + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-support@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== concat-map@0.0.1: version "0.0.1" @@ -230,46 +279,61 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0: resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= -core-util-is@1.0.2, core-util-is@~1.0.0: +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= -cryptiles@2.x.x: - version "2.0.5" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" - integrity sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g= - dependencies: - boom "2.x.x" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -dateformat@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.2.0.tgz#4065e2013cf9fb916ddfd82efb506ad4c6769062" - integrity sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI= - -debug@^2.2.0: +debug@^2.2.0, debug@^2.3.3: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" -deep-extend@~0.4.0: - version "0.4.2" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" - integrity sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8= +debug@^3.2.6: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" -delayed-stream@~1.0.0: +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" delegates@^1.0.0: version "1.0.0" @@ -281,25 +345,6 @@ detect-libc@^1.0.2: resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.2.tgz#71ad5d204bf17a6a6ca8f450c61454066ef461e1" integrity sha1-ca1dIEvxempsqPRQxhRUBm70YeE= -duplexer2@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" - integrity sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds= - dependencies: - readable-stream "~1.1.9" - -ecc-jsbn@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" - integrity sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU= - dependencies: - jsbn "~0.1.0" - -escape-string-regexp@^1.0.2: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - expand-brackets@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" @@ -307,6 +352,19 @@ expand-brackets@^0.1.4: dependencies: is-posix-bracket "^0.1.0" +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + expand-range@^1.8.1: version "1.8.2" resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" @@ -314,10 +372,20 @@ expand-range@^1.8.1: dependencies: fill-range "^2.1.0" -extend@~3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" - integrity sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ= +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" extglob@^0.3.1: version "0.3.2" @@ -326,17 +394,27 @@ extglob@^0.3.1: dependencies: is-extglob "^1.0.0" -extsprintf@1.3.0, extsprintf@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -fancy-log@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.0.tgz#45be17d02bb9917d60ccffd4995c999e6c8c9948" - integrity sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg= +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== dependencies: - chalk "^1.1.1" + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +fancy-log@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.2.tgz#f41125e3d84f2e7d89a43d06d958c8f78be16be1" + integrity sha1-9BEl49hPLn2JpD0G2VjI94vha+E= + dependencies: + ansi-gray "^0.1.1" + color-support "^1.1.3" time-stamp "^1.0.0" filename-regex@^2.0.0: @@ -355,6 +433,16 @@ fill-range@^2.1.0: repeat-element "^1.1.2" repeat-string "^1.5.2" +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + first-chunk-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz#1bdecdb8e083c0664b91945581577a43a9f31d70" @@ -362,7 +450,7 @@ first-chunk-stream@^2.0.0: dependencies: readable-stream "^2.0.2" -for-in@^1.0.1: +for-in@^1.0.1, for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= @@ -374,51 +462,32 @@ for-own@^0.1.4: dependencies: for-in "^1.0.1" -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - -form-data@~2.1.1: - version "2.1.4" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" - integrity sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE= +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.5" - mime-types "^2.1.12" + map-cache "^0.2.2" + +fs-minipass@^1.2.5: + version "1.2.6" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.6.tgz#2c5cc30ded81282bfe8a0d7c7c1853ddeb102c07" + integrity sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ== + dependencies: + minipass "^2.2.1" fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.3.tgz#11f82318f5fe7bb2cd22965a108e9306208216d8" - integrity sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q== +fsevents@^1.2.7: + version "1.2.9" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.9.tgz#3f5ed66583ccd6f400b5a00db6f7e861363e388f" + integrity sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw== dependencies: - nan "^2.3.0" - node-pre-gyp "^0.6.39" - -fstream-ignore@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" - integrity sha1-nDHa40dnAY/h0kmyTa2mfQktoQU= - dependencies: - fstream "^1.0.0" - inherits "2" - minimatch "^3.0.0" - -fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: - version "1.0.11" - resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" - integrity sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE= - dependencies: - graceful-fs "^4.1.2" - inherits "~2.0.0" - mkdirp ">=0.5 0" - rimraf "2" + nan "^2.12.1" + node-pre-gyp "^0.12.0" gauge@~2.7.3: version "2.7.4" @@ -434,12 +503,10 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= glob-base@^0.3.0: version "0.3.0" @@ -456,7 +523,7 @@ glob-parent@^2.0.0: dependencies: is-glob "^2.0.0" -glob-parent@^3.0.1: +glob-parent@^3.0.1, glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= @@ -476,120 +543,83 @@ glob@^7.0.5: once "^1.3.0" path-is-absolute "^1.0.0" -glogg@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.0.tgz#7fe0f199f57ac906cf512feead8f90ee4a284fc5" - integrity sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U= - dependencies: - sparkles "^1.0.0" +graceful-fs@^4.1.11: + version "4.2.0" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.0.tgz#8d8fdc73977cb04104721cb53666c1ca64cd328b" + integrity sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg== graceful-fs@^4.1.2: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg= -gulp-util@^3.0.7: - version "3.0.8" - resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f" - integrity sha1-AFTh50RQLifATBh8PsxQXdVLu08= - dependencies: - array-differ "^1.0.0" - array-uniq "^1.0.2" - beeper "^1.0.0" - chalk "^1.0.0" - dateformat "^2.0.0" - fancy-log "^1.1.0" - gulplog "^1.0.0" - has-gulplog "^0.1.0" - lodash._reescape "^3.0.0" - lodash._reevaluate "^3.0.0" - lodash._reinterpolate "^3.0.0" - lodash.template "^3.0.0" - minimist "^1.1.0" - multipipe "^0.1.2" - object-assign "^3.0.0" - replace-ext "0.0.1" - through2 "^2.0.0" - vinyl "^0.5.0" - -gulp-watch@^4.3.9: - version "4.3.11" - resolved "https://registry.yarnpkg.com/gulp-watch/-/gulp-watch-4.3.11.tgz#162fc563de9fc770e91f9a7ce3955513a9a118c0" - integrity sha1-Fi/FY96fx3DpH5p845VVE6mhGMA= +gulp-watch@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/gulp-watch/-/gulp-watch-5.0.1.tgz#83d378752f5bfb46da023e73c17ed1da7066215d" + integrity sha512-HnTSBdzAOFIT4wmXYPDUn783TaYAq9bpaN05vuZNP5eni3z3aRx0NAKbjhhMYtcq76x4R1wf4oORDGdlrEjuog== dependencies: + ansi-colors "1.1.0" anymatch "^1.3.0" - chokidar "^1.6.1" + chokidar "^2.0.0" + fancy-log "1.3.2" glob-parent "^3.0.1" - gulp-util "^3.0.7" object-assign "^4.1.0" path-is-absolute "^1.0.1" + plugin-error "1.0.1" readable-stream "^2.2.2" slash "^1.0.0" - vinyl "^1.2.0" + vinyl "^2.1.0" vinyl-file "^2.0.0" -gulplog@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/gulplog/-/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5" - integrity sha1-4oxNRdBey77YGDY86PnFkmIp/+U= - dependencies: - glogg "^1.0.0" - -har-schema@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" - integrity sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4= - -har-validator@~4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" - integrity sha1-M0gdDxu/9gDdID11gSpqX7oALio= - dependencies: - ajv "^4.9.1" - har-schema "^1.0.5" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= - dependencies: - ansi-regex "^2.0.0" - -has-gulplog@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/has-gulplog/-/has-gulplog-0.1.0.tgz#6414c82913697da51590397dafb12f22967811ce" - integrity sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4= - dependencies: - sparkles "^1.0.0" - has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= -hawk@3.1.3, hawk@~3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" - integrity sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ= +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= dependencies: - boom "2.x.x" - cryptiles "2.x.x" - hoek "2.x.x" - sntp "1.x.x" + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" -hoek@2.x.x: - version "2.16.3" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" - integrity sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0= - -http-signature@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" - integrity sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8= +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= dependencies: - assert-plus "^0.2.0" - jsprim "^1.2.2" - sshpk "^1.7.0" + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +iconv-lite@^0.4.4: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ignore-walk@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" + integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== + dependencies: + minimatch "^3.0.4" inflight@^1.0.4: version "1.0.6" @@ -599,16 +629,35 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@^2.0.1, inherits@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= +inherits@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + ini@~1.3.0: version "1.3.4" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" integrity sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4= +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + is-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" @@ -621,6 +670,38 @@ is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + is-dotfile@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" @@ -633,17 +714,24 @@ is-equal-shallow@^0.1.3: dependencies: is-primitive "^2.0.0" -is-extendable@^0.1.1: +is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + is-extglob@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= -is-extglob@^2.1.0: +is-extglob@^2.1.0, is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= @@ -669,6 +757,13 @@ is-glob@^3.1.0: dependencies: is-extglob "^2.1.0" +is-glob@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + is-number@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" @@ -683,6 +778,13 @@ is-number@^3.0.0: dependencies: kind-of "^3.0.2" +is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + is-posix-bracket@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" @@ -693,20 +795,15 @@ is-primitive@^2.0.0: resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - is-utf8@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== isarray@1.0.0, isarray@~1.0.0: version "1.0.0" @@ -720,49 +817,12 @@ isobject@^2.0.0: dependencies: isarray "1.0.0" -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - -json-stable-stringify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" - integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= - dependencies: - jsonify "~0.0.0" - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - -jsonify@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -kind-of@^3.0.2: +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= @@ -776,104 +836,27 @@ kind-of@^4.0.0: dependencies: is-buffer "^1.1.5" -lodash._basecopy@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" - integrity sha1-jaDmqHbPNEwK2KVIghEd08XHyjY= +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== -lodash._basetostring@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz#d1861d877f824a52f669832dcaf3ee15566a07d5" - integrity sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U= +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== -lodash._basevalues@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7" - integrity sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc= +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= -lodash._getnative@^3.0.0: - version "3.9.1" - resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" - integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U= - -lodash._isiterateecall@^3.0.0: - version "3.0.9" - resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" - integrity sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw= - -lodash._reescape@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._reescape/-/lodash._reescape-3.0.0.tgz#2b1d6f5dfe07c8a355753e5f27fac7f1cde1616a" - integrity sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo= - -lodash._reevaluate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz#58bc74c40664953ae0b124d806996daca431e2ed" - integrity sha1-WLx0xAZklTrgsSTYBpltrKQx4u0= - -lodash._reinterpolate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" - integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= - -lodash._root@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" - integrity sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI= - -lodash.escape@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-3.2.0.tgz#995ee0dc18c1b48cc92effae71a10aab5b487698" - integrity sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg= +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= dependencies: - lodash._root "^3.0.0" - -lodash.isarguments@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" - integrity sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo= - -lodash.isarray@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" - integrity sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U= - -lodash.keys@^3.0.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" - integrity sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo= - dependencies: - lodash._getnative "^3.0.0" - lodash.isarguments "^3.0.0" - lodash.isarray "^3.0.0" - -lodash.restparam@^3.0.0: - version "3.6.1" - resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" - integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU= - -lodash.template@^3.0.0: - version "3.6.2" - resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-3.6.2.tgz#f8cdecc6169a255be9098ae8b0c53d378931d14f" - integrity sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8= - dependencies: - lodash._basecopy "^3.0.0" - lodash._basetostring "^3.0.0" - lodash._basevalues "^3.0.0" - lodash._isiterateecall "^3.0.0" - lodash._reinterpolate "^3.0.0" - lodash.escape "^3.0.0" - lodash.keys "^3.0.0" - lodash.restparam "^3.0.0" - lodash.templatesettings "^3.0.0" - -lodash.templatesettings@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz#fb307844753b66b9f1afa54e262c745307dba8e5" - integrity sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU= - dependencies: - lodash._reinterpolate "^3.0.0" - lodash.escape "^3.0.0" + object-visit "^1.0.0" micromatch@^2.1.5: version "2.3.11" @@ -894,19 +877,26 @@ micromatch@^2.1.5: parse-glob "^3.0.4" regex-cache "^0.4.2" -mime-db@~1.30.0: - version "1.30.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" - integrity sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE= - -mime-types@^2.1.12, mime-types@~2.1.7: - version "2.1.17" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" - integrity sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo= +micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== dependencies: - mime-db "~1.30.0" + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" -minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4: +minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -918,12 +908,35 @@ minimist@0.0.8: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= -minimist@^1.1.0, minimist@^1.2.0: +minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= -"mkdirp@>=0.5 0", mkdirp@^0.5.1: +minipass@^2.2.1, minipass@^2.3.5: + version "2.3.5" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" + integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" + integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== + dependencies: + minipass "^2.2.1" + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@^0.5.0, mkdirp@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= @@ -935,34 +948,57 @@ ms@2.0.0: resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= -multipipe@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/multipipe/-/multipipe-0.1.2.tgz#2a8f2ddf70eed564dff2d57f1e1a137d9f05078b" - integrity sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s= +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +nan@^2.12.1: + version "2.14.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" + integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== dependencies: - duplexer2 "0.0.2" + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" -nan@^2.3.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.7.0.tgz#d95bf721ec877e08db276ed3fc6eb78f9083ad46" - integrity sha1-2Vv3IeyHfgjbJ27T/G63j5CDrUY= +needle@^2.2.1: + version "2.4.0" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.0.tgz#6833e74975c444642590e15a750288c5f939b57c" + integrity sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg== + dependencies: + debug "^3.2.6" + iconv-lite "^0.4.4" + sax "^1.2.4" -node-pre-gyp@^0.6.39: - version "0.6.39" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz#c00e96860b23c0e1420ac7befc5044e1d78d8649" - integrity sha512-OsJV74qxnvz/AMGgcfZoDaeDXKD3oY3QVIbBmwszTFkRisTSXbMQyn4UWzUMOtA5SVhrBZOTp0wcoSBgfMfMmQ== +node-pre-gyp@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149" + integrity sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A== dependencies: detect-libc "^1.0.2" - hawk "3.1.3" mkdirp "^0.5.1" + needle "^2.2.1" nopt "^4.0.1" + npm-packlist "^1.1.6" npmlog "^4.0.2" - rc "^1.1.7" - request "2.81.0" + rc "^1.2.7" rimraf "^2.6.1" semver "^5.3.0" - tar "^2.2.1" - tar-pack "^3.4.0" + tar "^4" nopt@^4.0.1: version "4.0.1" @@ -972,13 +1008,31 @@ nopt@^4.0.1: abbrev "1" osenv "^0.1.4" -normalize-path@^2.0.0, normalize-path@^2.0.1: +normalize-path@^2.0.0, normalize-path@^2.0.1, normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= dependencies: remove-trailing-separator "^1.0.1" +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-bundled@^1.0.1: + version "1.0.6" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd" + integrity sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g== + +npm-packlist@^1.1.6: + version "1.4.4" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.4.tgz#866224233850ac534b63d1a6e76050092b5d2f44" + integrity sha512-zTLo8UcVYtDU3gdeaFu2Xu0n0EvelfHDGuqtNIn5RO7yQj4H1TqNdBc/yZjxnWA0PVB8D3Woyp0i5B43JwQ6Vw== + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + npmlog@^4.0.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" @@ -994,21 +1048,27 @@ number-is-nan@^1.0.0: resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= -oauth-sign@~0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" - integrity sha1-Rqarfwrq2N6unsBWV4C31O/rnUM= - -object-assign@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2" - integrity sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I= - object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + object.omit@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" @@ -1017,7 +1077,14 @@ object.omit@^2.0.0: for-own "^0.1.4" is-extendable "^0.1.1" -once@^1.3.0, once@^1.3.3: +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= @@ -1052,6 +1119,11 @@ parse-glob@^3.0.4: is-extglob "^1.0.0" is-glob "^2.0.0" +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + path-dirname@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" @@ -1062,11 +1134,6 @@ path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -performance-now@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" - integrity sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU= - pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -1084,26 +1151,36 @@ pinkie@^2.0.0: resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= +plugin-error@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-1.0.1.tgz#77016bd8919d0ac377fdcdd0322328953ca5781c" + integrity sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA== + dependencies: + ansi-colors "^1.0.1" + arr-diff "^4.0.0" + arr-union "^3.1.0" + extend-shallow "^3.0.2" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= +process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + process-nextick-args@~1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" integrity sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M= -punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= - -qs@~6.4.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" - integrity sha1-E+JtKK1rD/qpExLNO/cI7TUecjM= - randomatic@^1.1.3: version "1.1.7" resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" @@ -1112,17 +1189,17 @@ randomatic@^1.1.3: is-number "^3.0.0" kind-of "^4.0.0" -rc@^1.1.7: - version "1.2.2" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.2.tgz#d8ce9cb57e8d64d9c7badd9876c7c34cbe3c7077" - integrity sha1-2M6ctX6NZNnHut2YdsfDTL48cHc= +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== dependencies: - deep-extend "~0.4.0" + deep-extend "^0.6.0" ini "~1.3.0" minimist "^1.2.0" strip-json-comments "~2.0.1" -readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2: +readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.2.2: version "2.3.3" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" integrity sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ== @@ -1135,25 +1212,27 @@ readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable string_decoder "~1.0.3" util-deprecate "~1.0.1" -readable-stream@~1.1.9: - version "1.1.14" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" - integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= +readable-stream@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== dependencies: core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" -readdirp@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" - integrity sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg= +readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== dependencies: - graceful-fs "^4.1.2" - minimatch "^3.0.2" + graceful-fs "^4.1.11" + micromatch "^3.1.10" readable-stream "^2.0.2" - set-immediate-shim "^1.0.1" regex-cache@^0.4.2: version "0.4.4" @@ -1162,6 +1241,14 @@ regex-cache@^0.4.2: dependencies: is-equal-shallow "^0.1.3" +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" @@ -1172,7 +1259,7 @@ repeat-element@^1.1.2: resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" integrity sha1-7wiaF40Ug7quTZPrmLT55OEdmQo= -repeat-string@^1.5.2: +repeat-string@^1.5.2, repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= @@ -1182,46 +1269,55 @@ replace-ext@0.0.1: resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" integrity sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ= -request@2.81.0: - version "2.81.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" - integrity sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA= - dependencies: - aws-sign2 "~0.6.0" - aws4 "^1.2.1" - caseless "~0.12.0" - combined-stream "~1.0.5" - extend "~3.0.0" - forever-agent "~0.6.1" - form-data "~2.1.1" - har-validator "~4.2.1" - hawk "~3.1.3" - http-signature "~1.1.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.7" - oauth-sign "~0.8.1" - performance-now "^0.2.0" - qs "~6.4.0" - safe-buffer "^5.0.1" - stringstream "~0.0.4" - tough-cookie "~2.3.0" - tunnel-agent "^0.6.0" - uuid "^3.0.0" +replace-ext@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" + integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs= -rimraf@2, rimraf@^2.5.1, rimraf@^2.6.1: +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +rimraf@^2.6.1: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== dependencies: glob "^7.0.5" -safe-buffer@^5.0.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@^5.1.2: + version "5.2.0" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" + integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" integrity sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg== +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + semver@^5.3.0: version "5.4.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" @@ -1232,10 +1328,15 @@ set-blocking@~2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= -set-immediate-shim@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" - integrity sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E= +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" signal-exit@^3.0.0: version "3.0.2" @@ -1247,32 +1348,71 @@ slash@^1.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= -sntp@1.x.x: - version "1.0.9" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" - integrity sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg= +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== dependencies: - hoek "2.x.x" + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" -sparkles@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.0.tgz#1acbbfb592436d10bbe8f785b7cc6f82815012c3" - integrity sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM= - -sshpk@^1.7.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" - integrity sha1-US322mKHFEMW3EwY/hzx2UBzm+M= +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - dashdash "^1.12.0" - getpass "^0.1.1" - optionalDependencies: - bcrypt-pbkdf "^1.0.0" - ecc-jsbn "~0.1.1" - jsbn "~0.1.0" - tweetnacl "~0.14.0" + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +source-map-resolve@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== + dependencies: + atob "^2.1.1" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" string-width@^1.0.1, string-width@^1.0.2: version "1.0.2" @@ -1283,11 +1423,6 @@ string-width@^1.0.1, string-width@^1.0.2: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= - string_decoder@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" @@ -1295,10 +1430,12 @@ string_decoder@~1.0.3: dependencies: safe-buffer "~5.1.0" -stringstream@~0.0.4: - version "0.0.5" - resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" - integrity sha1-TkhM1N5aC7vuGORjB3EKioFiGHg= +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" @@ -1327,90 +1464,87 @@ strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= - -tar-pack@^3.4.0: - version "3.4.1" - resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.1.tgz#e1dbc03a9b9d3ba07e896ad027317eb679a10a1f" - integrity sha512-PPRybI9+jM5tjtCbN2cxmmRU7YmqT3Zv/UDy48tAh2XRkLa9bAORtSWLkVc13+GJF+cdTh1yEnHEk3cpTaL5Kg== +tar@^4: + version "4.4.10" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.10.tgz#946b2810b9a5e0b26140cf78bea6b0b0d689eba1" + integrity sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA== dependencies: - debug "^2.2.0" - fstream "^1.0.10" - fstream-ignore "^1.0.5" - once "^1.3.3" - readable-stream "^2.1.4" - rimraf "^2.5.1" - tar "^2.2.1" - uid-number "^0.0.6" - -tar@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" - integrity sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE= - dependencies: - block-stream "*" - fstream "^1.0.2" - inherits "2" - -through2@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" - integrity sha1-AARWmzfHx0ujnEPzzteNGtlBQL4= - dependencies: - readable-stream "^2.1.5" - xtend "~4.0.1" + chownr "^1.1.1" + fs-minipass "^1.2.5" + minipass "^2.3.5" + minizlib "^1.2.1" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.3" time-stamp@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM= -tough-cookie@~2.3.0: - version "2.3.3" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" - integrity sha1-C2GKVWW23qkL80JdBNVe3EdadWE= +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= dependencies: - punycode "^1.4.1" + kind-of "^3.0.2" -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= dependencies: - safe-buffer "^5.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" -uid-number@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" - integrity sha1-DqEOgDXo61uOREnwbaHHMGY7qoE= +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +upath@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.2.tgz#3db658600edaeeccbe6db5e684d67ee8c2acd068" + integrity sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q== + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -uuid@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" - integrity sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g== - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - vinyl-file@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/vinyl-file/-/vinyl-file-2.0.0.tgz#a7ebf5ffbefda1b7d18d140fcb07b223efb6751a" @@ -1423,16 +1557,7 @@ vinyl-file@^2.0.0: strip-bom-stream "^2.0.0" vinyl "^1.1.0" -vinyl@^0.5.0: - version "0.5.3" - resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.5.3.tgz#b0455b38fc5e0cf30d4325132e461970c2091cde" - integrity sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4= - dependencies: - clone "^1.0.0" - clone-stats "^0.0.1" - replace-ext "0.0.1" - -vinyl@^1.1.0, vinyl@^1.2.0: +vinyl@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-1.2.0.tgz#5c88036cf565e5df05558bfc911f8656df218884" integrity sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ= @@ -1441,6 +1566,18 @@ vinyl@^1.1.0, vinyl@^1.2.0: clone-stats "^0.0.1" replace-ext "0.0.1" +vinyl@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.0.tgz#d85b07da96e458d25b2ffe19fece9f2caa13ed86" + integrity sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg== + dependencies: + clone "^2.1.1" + clone-buffer "^1.0.0" + clone-stats "^1.0.0" + cloneable-readable "^1.0.0" + remove-trailing-separator "^1.0.1" + replace-ext "^1.0.0" + wide-align@^1.1.0: version "1.1.2" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710" @@ -1453,7 +1590,7 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -xtend@~4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" - integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= +yallist@^3.0.0, yallist@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" + integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== diff --git a/build/npm/postinstall.js b/build/npm/postinstall.js index 80a4f0eeb5c..cd41092192c 100644 --- a/build/npm/postinstall.js +++ b/build/npm/postinstall.js @@ -35,6 +35,8 @@ yarnInstall('extensions'); // node modules shared by all extensions yarnInstall('remote'); // node modules used by vscode server +yarnInstall('remote/web'); // node modules used by vscode web + const allExtensionFolders = fs.readdirSync('extensions'); const extensions = allExtensionFolders.filter(e => { try { diff --git a/extensions/css/.vscodeignore b/extensions/css/.vscodeignore index 0a622e7e300..52ebcbd68b2 100644 --- a/extensions/css/.vscodeignore +++ b/extensions/css/.vscodeignore @@ -1,2 +1,3 @@ test/** cgmanifest.json +.vscode \ No newline at end of file diff --git a/extensions/debug-server-ready/.vscodeignore b/extensions/debug-server-ready/.vscodeignore index 36e8b0714fa..609d4c28b22 100644 --- a/extensions/debug-server-ready/.vscodeignore +++ b/extensions/debug-server-ready/.vscodeignore @@ -2,4 +2,5 @@ src/** tsconfig.json out/** extension.webpack.config.js -yarn.lock \ No newline at end of file +yarn.lock +.vscode \ No newline at end of file diff --git a/extensions/emmet/.vscodeignore b/extensions/emmet/.vscodeignore index 50d0ee883e6..573d91ebe6b 100644 --- a/extensions/emmet/.vscodeignore +++ b/extensions/emmet/.vscodeignore @@ -6,3 +6,4 @@ extension.webpack.config.js CONTRIBUTING.md cgmanifest.json yarn.lock +.vscode \ No newline at end of file diff --git a/extensions/markdown-language-features/cgmanifest.json b/extensions/markdown-language-features/cgmanifest.json deleted file mode 100644 index 71df78ef41f..00000000000 --- a/extensions/markdown-language-features/cgmanifest.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "registrations": [ - { - "component": { - "type": "git", - "git": { - "name": "textmate/markdown.tmbundle", - "repositoryUrl": "https://github.com/textmate/markdown.tmbundle", - "commitHash": "11cf764606cb2cde54badb5d0e5a0758a8871c4b" - } - }, - "licenseDetail": [ - "Copyright (c) markdown.tmbundle authors", - "", - "If not otherwise specified (see below), files in this repository fall under the following license:", - "", - "Permission to copy, use, modify, sell and distribute this", - "software is granted. This software is provided \"as is\" without", - "express or implied warranty, and with no claim as to its", - "suitability for any purpose.", - "", - "An exception is made for files in readable text which contain their own license information,", - "or files where an accompanying file exists (in the same directory) with a \"-license\" suffix added", - "to the base-name name of the original file, and an extension of txt, html, or similar. For example", - "\"tidy\" is accompanied by \"tidy-license.txt\"." - ], - "license": "TextMate Bundle License", - "version": "0.0.0" - } - ], - "version": 1 -} \ No newline at end of file diff --git a/extensions/php/.vscodeignore b/extensions/php/.vscodeignore index 98efc0327fb..5da0ed79e46 100644 --- a/extensions/php/.vscodeignore +++ b/extensions/php/.vscodeignore @@ -4,3 +4,4 @@ out/test/** src/** tsconfig.json cgmanifest.json +.vscode \ No newline at end of file diff --git a/extensions/python/.vscodeignore b/extensions/python/.vscodeignore index f10f292ed55..4d5a14fc91e 100644 --- a/extensions/python/.vscodeignore +++ b/extensions/python/.vscodeignore @@ -3,3 +3,4 @@ src/** tsconfig.json extension.webpack.config.js cgmanifest.json +.vscode \ No newline at end of file diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts index ad07fc997ad..c0e300439be 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts @@ -270,27 +270,6 @@ suite('window namespace tests', () => { window.createTerminal({ name: 'c', virtualProcess }); }); - test('should get dimensions event when shown', (done) => { - const reg1 = window.onDidOpenTerminal(term => { - reg1.dispose(); - equal(terminal, term); - term.show(); - }); - const virtualProcess: TerminalVirtualProcess = { - onDidWrite: new EventEmitter().event, - setDimensions: dimensions => { - ok(dimensions.columns > 0); - ok(dimensions.rows > 0); - const reg2 = window.onDidCloseTerminal(() => { - reg2.dispose(); - done(); - }); - terminal.dispose(); - } - }; - const terminal = window.createTerminal({ name: 'foo', virtualProcess }); - }); - test('should fire Terminal.onData on write', (done) => { const reg1 = window.onDidOpenTerminal(term => { equal(terminal, term); @@ -313,6 +292,26 @@ suite('window namespace tests', () => { const terminal = window.createTerminal({ name: 'foo', virtualProcess }); }); + test('should fire provide dimensions on start as the terminal has been shown', (done) => { + const reg1 = window.onDidOpenTerminal(term => { + equal(terminal, term); + reg1.dispose(); + }); + const virtualProcess: TerminalVirtualProcess = { + onDidWrite: new EventEmitter().event, + start: (dimensions) => { + ok(dimensions!.columns > 0); + ok(dimensions!.rows > 0); + const reg3 = window.onDidCloseTerminal(() => { + reg3.dispose(); + done(); + }); + terminal.dispose(); + } + }; + const terminal = window.createTerminal({ name: 'foo', virtualProcess }); + }); + test('should respect dimension overrides', (done) => { const reg1 = window.onDidOpenTerminal(term => { equal(terminal, term); diff --git a/extensions/yaml/.gitignore b/extensions/yaml/.gitignore deleted file mode 100644 index 3c3629e647f..00000000000 --- a/extensions/yaml/.gitignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/package.json b/package.json index 616ad5fc534..30a031ec455 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "code-oss-dev", "version": "1.37.0", - "distro": "4d4ca170652edf13efd5916e009bdc9c0d4d1103", + "distro": "a76f8ddb784119243aa004071cea17c5a74b1e60", "author": { "name": "Microsoft Corporation" }, @@ -29,7 +29,6 @@ }, "dependencies": { "applicationinsights": "1.0.8", - "getmac": "1.4.1", "graceful-fs": "4.1.11", "http-proxy-agent": "^2.1.0", "https-proxy-agent": "^2.2.1", @@ -157,4 +156,4 @@ "windows-mutex": "0.2.1", "windows-process-tree": "0.2.4" } -} +} \ No newline at end of file diff --git a/remote/web/.yarnrc b/remote/web/.yarnrc new file mode 100644 index 00000000000..b28191e6bae --- /dev/null +++ b/remote/web/.yarnrc @@ -0,0 +1,3 @@ +disturl "http://nodejs.org/dist" +target "10.11.0" +runtime "node" diff --git a/remote/web/package.json b/remote/web/package.json new file mode 100644 index 00000000000..38f730e7dab --- /dev/null +++ b/remote/web/package.json @@ -0,0 +1,11 @@ +{ + "name": "vscode-web", + "version": "0.0.0", + "dependencies": { + "onigasm-umd": "^2.2.2", + "vscode-textmate": "^4.1.1", + "xterm": "3.15.0-beta67", + "xterm-addon-search": "0.2.0-beta2", + "xterm-addon-web-links": "0.1.0-beta10" + } + } \ No newline at end of file diff --git a/remote/web/yarn.lock b/remote/web/yarn.lock new file mode 100644 index 00000000000..3f790e1f281 --- /dev/null +++ b/remote/web/yarn.lock @@ -0,0 +1,42 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +nan@^2.14.0: + version "2.14.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" + integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== + +onigasm-umd@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/onigasm-umd/-/onigasm-umd-2.2.2.tgz#b989d762df61f899a3052ac794a50bd93fe20257" + integrity sha512-v2eMOJu7iE444L2iJN+U6s6s5S0y7oj/N0DAkrd6wokRtTVoq/v/yaDI1lIqFrTeJbNtqNzYvguDF5yNzW3Rvw== + +oniguruma@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/oniguruma/-/oniguruma-7.2.0.tgz#c9a59c1ea7b9fe67e237a02e02139b638856f3af" + integrity sha512-bh+ZLdykY1sdIx8jBp2zpLbVFDBc3XmKH4Ceo2lijNaN1WhEqtnpqFlmtCbRuDB17nJ58RAUStVwfW8e8uEbnA== + dependencies: + nan "^2.14.0" + +vscode-textmate@^4.1.1: + version "4.2.2" + resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-4.2.2.tgz#0b4dabc69a6fba79a065cb6b615f66eac07c8f4c" + integrity sha512-1U4ih0E/KP1zNK/EbpUqyYtI7PY+Ccd2nDGTtiMR/UalLFnmaYkwoWhN1oI7B91ptBN8NdVwWuvyUnvJAulCUw== + dependencies: + oniguruma "^7.2.0" + +xterm-addon-search@0.2.0-beta2: + version "0.2.0-beta2" + resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.2.0-beta2.tgz#c3173f0a6f207ee9f1848849174ee5d6b6ce8262" + integrity sha512-XEcwi2TeFGk2MuIFjiI/OpVXSNO5dGQBvHH3o+9KzqG3ooVqhhDqzwxs092QGNcNCGh8hGn/PWZiczaBBnKm/g== + +xterm-addon-web-links@0.1.0-beta10: + version "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-beta67: + version "3.15.0-beta67" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.15.0-beta67.tgz#71973e174bdc08df620945eecd3f87912f1ac550" + integrity sha512-qLfo9GHVlu/IxgDI3vRGObWZM7UL4eLhMfjZhprx2aXNMpzmrOW6l3JDRsCjUWm93EoVavbULtnDhGSiTlKitQ== diff --git a/src/vs/base/browser/ui/dialog/dialog.ts b/src/vs/base/browser/ui/dialog/dialog.ts index 6dc7d9ee067..a33545b641e 100644 --- a/src/vs/base/browser/ui/dialog/dialog.ts +++ b/src/vs/base/browser/ui/dialog/dialog.ts @@ -15,7 +15,7 @@ import { ButtonGroup, IButtonStyles } from 'vs/base/browser/ui/button/button'; import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; import { Action } from 'vs/base/common/actions'; import { mnemonicButtonLabel } from 'vs/base/common/labels'; -import { isMacintosh } from 'vs/base/common/platform'; +import { isMacintosh, isLinux } from 'vs/base/common/platform'; export interface IDialogOptions { cancelId?: number; @@ -97,9 +97,9 @@ export class Dialog extends Disposable { clearNode(this.buttonsContainer); let focusedButton = 0; - this.buttonGroup = new ButtonGroup(this.buttonsContainer, this.buttons.length, { title: true }); + const buttonGroup = this.buttonGroup = new ButtonGroup(this.buttonsContainer, this.buttons.length, { title: true }); const buttonMap = this.rearrangeButtons(this.buttons, this.options.cancelId); - this.buttonGroup.buttons.forEach((button, index) => { + buttonGroup.buttons.forEach((button, index) => { button.label = mnemonicButtonLabel(buttonMap[index].label, true); this._register(button.onDidClick(e => { @@ -115,18 +115,16 @@ export class Dialog extends Disposable { } let eventHandled = false; - if (this.buttonGroup) { - if (evt.equals(KeyMod.Shift | KeyCode.Tab) || evt.equals(KeyCode.LeftArrow)) { - focusedButton = focusedButton + this.buttonGroup.buttons.length - 1; - focusedButton = focusedButton % this.buttonGroup.buttons.length; - this.buttonGroup.buttons[focusedButton].focus(); - eventHandled = true; - } else if (evt.equals(KeyCode.Tab) || evt.equals(KeyCode.RightArrow)) { - focusedButton++; - focusedButton = focusedButton % this.buttonGroup.buttons.length; - this.buttonGroup.buttons[focusedButton].focus(); - eventHandled = true; - } + if (evt.equals(KeyMod.Shift | KeyCode.Tab) || evt.equals(KeyCode.LeftArrow)) { + focusedButton = focusedButton + buttonGroup.buttons.length - 1; + focusedButton = focusedButton % buttonGroup.buttons.length; + buttonGroup.buttons[focusedButton].focus(); + eventHandled = true; + } else if (evt.equals(KeyCode.Tab) || evt.equals(KeyCode.RightArrow)) { + focusedButton++; + focusedButton = focusedButton % buttonGroup.buttons.length; + buttonGroup.buttons[focusedButton].focus(); + eventHandled = true; } if (eventHandled) { @@ -192,7 +190,11 @@ export class Dialog extends Disposable { show(this.element); // Focus first element - this.buttonGroup.buttons[focusedButton].focus(); + buttonMap.forEach((value, index) => { + if (value.index === focusedButton) { + buttonGroup.buttons[index].focus(); + } + }); }); } @@ -243,7 +245,8 @@ export class Dialog extends Disposable { buttonMap.push({ label: button, index: index }); }); - if (isMacintosh) { + // macOS/linux: reverse button order + if (isMacintosh || isLinux) { if (cancelId !== undefined) { const cancelButton = buttonMap.splice(cancelId, 1)[0]; buttonMap.reverse(); diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index 0e0a4df34bc..7e4aa5fb5b4 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -329,6 +329,7 @@ export function mightProducePrintableCharacter(event: IKeyboardEvent): boolean { return (event.keyCode >= KeyCode.KEY_A && event.keyCode <= KeyCode.KEY_Z) || (event.keyCode >= KeyCode.KEY_0 && event.keyCode <= KeyCode.KEY_9) + || (event.keyCode >= KeyCode.NUMPAD_0 && event.keyCode <= KeyCode.NUMPAD_9) || (event.keyCode >= KeyCode.US_SEMICOLON && event.keyCode <= KeyCode.US_QUOTE); } diff --git a/src/vs/base/browser/ui/sash/sash.ts b/src/vs/base/browser/ui/sash/sash.ts index 3e0efee82c9..70ddb045301 100644 --- a/src/vs/base/browser/ui/sash/sash.ts +++ b/src/vs/base/browser/ui/sash/sash.ts @@ -212,7 +212,13 @@ export class Sash extends Disposable { return; } - const iframes = getElementsByTagName('iframe'); + // Select both iframes and webviews; internally Electron nests an iframe + // in its component, but this isn't queryable. + const iframes = [ + ...getElementsByTagName('iframe'), + ...getElementsByTagName('webview'), + ]; + for (const iframe of iframes) { iframe.style.pointerEvents = 'none'; // disable mouse events on iframes as long as we drag the sash } @@ -280,7 +286,6 @@ export class Sash extends Disposable { dispose(disposables); - const iframes = getElementsByTagName('iframe'); for (const iframe of iframes) { iframe.style.pointerEvents = 'auto'; } diff --git a/src/vs/base/browser/ui/splitview/splitview.css b/src/vs/base/browser/ui/splitview/splitview.css index 7479f5178d7..6fb8f1c61d0 100644 --- a/src/vs/base/browser/ui/splitview/splitview.css +++ b/src/vs/base/browser/ui/splitview/splitview.css @@ -41,6 +41,10 @@ position: relative; } +.monaco-split-view2 > .split-view-container > .split-view-view:not(.visible) { + display: none; +} + .monaco-split-view2.vertical > .split-view-container > .split-view-view { width: 100%; } diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index fc104cc5543..278366152b4 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -47,7 +47,9 @@ export interface IView { readonly maximumSize: number; readonly onDidChange: Event; readonly priority?: LayoutPriority; + readonly snap?: boolean; layout(size: number, orientation: Orientation): void; + setVisible?(visible: boolean): void; } interface ISashEvent { @@ -57,12 +59,79 @@ interface ISashEvent { alt: boolean; } -interface IViewItem { - view: IView; - size: number; - container: HTMLElement; - disposable: IDisposable; - layout(): void; +abstract class ViewItem { + + set size(size: number) { + this._size = size; + } + + get size(): number { + return this._size; + } + + private cachedSize: number | undefined = undefined; + + get visible(): boolean { + return typeof this.cachedSize === 'undefined'; + } + + set visible(visible: boolean) { + if (visible === this.visible) { + return; + } + + if (visible) { + this.size = this.cachedSize!; + this.cachedSize = undefined; + } else { + this.cachedSize = this.size; + this.size = 0; + } + + dom.toggleClass(this.container, 'visible', visible); + + if (this.view.setVisible) { + this.view.setVisible(visible); + } + } + + get minimumSize(): number { return this.visible ? this.view.minimumSize : 0; } + get viewMinimumSize(): number { return this.view.minimumSize; } + get maximumSize(): number { return this.visible ? this.view.maximumSize : 0; } + get viewMaximumSize(): number { return this.view.maximumSize; } + get priority(): LayoutPriority | undefined { return this.view.priority; } + get snap(): boolean { return !!this.view.snap; } + + constructor(protected container: HTMLElement, private view: IView, private _size: number, private disposable: IDisposable) { + dom.addClass(container, 'visible'); + } + + abstract layout(): void; + + layoutView(orientation: Orientation): void { + this.view.layout(this.size, orientation); + } + + dispose(): IView { + this.disposable.dispose(); + return this.view; + } +} + +class VerticalViewItem extends ViewItem { + + layout(): void { + this.container.style.height = `${this.size}px`; + this.layoutView(Orientation.VERTICAL); + } +} + +class HorizontalViewItem extends ViewItem { + + layout(): void { + this.container.style.width = `${this.size}px`; + this.layoutView(Orientation.HORIZONTAL); + } } interface ISashItem { @@ -78,6 +147,8 @@ interface ISashDragState { minDelta: number; maxDelta: number; alt: boolean; + snapIndex: number | undefined; + snapLimitDelta: number | undefined; disposable: IDisposable; } @@ -104,7 +175,7 @@ export class SplitView extends Disposable { private size = 0; private contentSize = 0; private proportions: undefined | number[] = undefined; - private viewItems: IViewItem[] = []; + private viewItems: ViewItem[] = []; private sashItems: ISashItem[] = []; private sashDragState: ISashDragState; private state: State = State.Idle; @@ -122,11 +193,11 @@ export class SplitView extends Disposable { } get minimumSize(): number { - return this.viewItems.reduce((r, item) => r + item.view.minimumSize, 0); + return this.viewItems.reduce((r, item) => r + item.minimumSize, 0); } get maximumSize(): number { - return this.length === 0 ? Number.POSITIVE_INFINITY : this.viewItems.reduce((r, item) => r + item.view.maximumSize, 0); + return this.length === 0 ? Number.POSITIVE_INFINITY : this.viewItems.reduce((r, item) => r + item.maximumSize, 0); } private _orthogonalStartSash: Sash | undefined; @@ -201,15 +272,6 @@ export class SplitView extends Disposable { const containerDisposable = toDisposable(() => this.viewContainer.removeChild(container)); const disposable = combinedDisposable(onChangeDisposable, containerDisposable); - const layoutContainer = this.orientation === Orientation.VERTICAL - ? () => item.container.style.height = `${item.size}px` - : () => item.container.style.width = `${item.size}px`; - - const layout = () => { - layoutContainer(); - item.view.layout(item.size, this.orientation); - }; - let viewSize: number; if (typeof size === 'number') { @@ -220,7 +282,10 @@ export class SplitView extends Disposable { viewSize = view.minimumSize; } - const item: IViewItem = { view, container, size: viewSize, layout, disposable }; + const item = this.orientation === Orientation.VERTICAL + ? new VerticalViewItem(container, view, viewSize, disposable) + : new HorizontalViewItem(container, view, viewSize, disposable); + this.viewItems.splice(index, 0, item); // Add sash @@ -280,7 +345,7 @@ export class SplitView extends Disposable { // Remove view const viewItem = this.viewItems.splice(index, 1)[0]; - viewItem.disposable.dispose(); + const view = viewItem.dispose(); // Remove sash if (this.viewItems.length >= 1) { @@ -296,7 +361,7 @@ export class SplitView extends Disposable { this.distributeViewSizes(); } - return viewItem.view; + return view; } moveView(from: number, to: number): void { @@ -327,6 +392,27 @@ export class SplitView extends Disposable { this.addView(fromView, toSize, to); } + isViewVisible(index: number): boolean { + if (index < 0 || index >= this.viewItems.length) { + throw new Error('Index out of bounds'); + } + + const viewItem = this.viewItems[index]; + return viewItem.visible; + } + + setViewVisible(index: number, visible: boolean): void { + if (index < 0 || index >= this.viewItems.length) { + throw new Error('Index out of bounds'); + } + + const viewItem = this.viewItems[index]; + viewItem.visible = visible; + + this.distributeEmptySpace(index); + this.layoutViews(); + } + private relayout(lowPriorityIndex?: number, highPriorityIndex?: number): void { const contentSize = this.viewItems.reduce((r, i) => r + i.size, 0); const lowPriorityIndexes = typeof lowPriorityIndex === 'number' ? [lowPriorityIndex] : undefined; @@ -344,14 +430,14 @@ export class SplitView extends Disposable { if (!this.proportions) { const indexes = range(this.viewItems.length); - const lowPriorityIndexes = indexes.filter(i => this.viewItems[i].view.priority === LayoutPriority.Low); - const highPriorityIndexes = indexes.filter(i => this.viewItems[i].view.priority === LayoutPriority.High); + const lowPriorityIndexes = indexes.filter(i => this.viewItems[i].priority === LayoutPriority.Low); + const highPriorityIndexes = indexes.filter(i => this.viewItems[i].priority === LayoutPriority.High); this.resize(this.viewItems.length - 1, size - previousSize, undefined, lowPriorityIndexes, highPriorityIndexes); } else { for (let i = 0; i < this.viewItems.length; i++) { const item = this.viewItems[i]; - item.size = clamp(Math.round(this.proportions[i] * size), item.view.minimumSize, item.view.maximumSize); + item.size = clamp(Math.round(this.proportions[i] * size), item.minimumSize, item.maximumSize); } } @@ -391,35 +477,72 @@ export class SplitView extends Disposable { if (isLastSash) { const viewItem = this.viewItems[index]; - minDelta = (viewItem.view.minimumSize - viewItem.size) / 2; - maxDelta = (viewItem.view.maximumSize - viewItem.size) / 2; + minDelta = (viewItem.minimumSize - viewItem.size) / 2; + maxDelta = (viewItem.maximumSize - viewItem.size) / 2; } else { const viewItem = this.viewItems[index + 1]; - minDelta = (viewItem.size - viewItem.view.maximumSize) / 2; - maxDelta = (viewItem.size - viewItem.view.minimumSize) / 2; + minDelta = (viewItem.size - viewItem.maximumSize) / 2; + maxDelta = (viewItem.size - viewItem.minimumSize) / 2; } } - this.sashDragState = { start, current: start, index, sizes, minDelta, maxDelta, alt, disposable }; + let snapIndex: number | undefined; + let snapLimitDelta: number | undefined; + + if (!alt) { + const upIndexes = range(index, -1); + const downIndexes = range(index + 1, this.viewItems.length); + const minDeltaUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].minimumSize - sizes[i]), 0); + const maxDeltaUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].maximumSize - sizes[i]), 0); + const maxDeltaDown = downIndexes.length === 0 ? Number.POSITIVE_INFINITY : downIndexes.reduce((r, i) => r + (sizes[i] - this.viewItems[i].minimumSize), 0); + const minDeltaDown = downIndexes.length === 0 ? Number.NEGATIVE_INFINITY : downIndexes.reduce((r, i) => r + (sizes[i] - this.viewItems[i].maximumSize), 0); + const minDelta = Math.max(minDeltaUp, minDeltaDown); + const maxDelta = Math.min(maxDeltaDown, maxDeltaUp); + + const snapBefore = this.viewItems[index].snap; + const snapAfter = this.viewItems[index + 1].snap; + + if (snapBefore && snapAfter) { + snapIndex = index + 1 < (this.viewItems.length - index - 1) ? index : index + 1; + } else if (snapBefore) { + snapIndex = index; + } else if (snapAfter) { + snapIndex = index + 1; + } + + if (typeof snapIndex === 'number') { + if (this.viewItems[snapIndex].visible) { + snapLimitDelta = snapIndex === index + ? minDelta - (this.viewItems[index].viewMinimumSize / 2) + : maxDelta + (this.viewItems[index + 1].viewMinimumSize / 2); + } else { + snapLimitDelta = snapIndex === index + ? minDelta + (this.viewItems[index].viewMinimumSize / 2) + : maxDelta - (this.viewItems[index + 1].viewMinimumSize / 2); + } + } + } + + this.sashDragState = { start, current: start, index, sizes, minDelta, maxDelta, alt, snapIndex, snapLimitDelta, disposable }; }; resetSashDragState(start, alt); } private onSashChange({ current }: ISashEvent): void { - const { index, start, sizes, alt, minDelta, maxDelta } = this.sashDragState; + const { index, start, sizes, alt, minDelta, maxDelta, snapIndex, snapLimitDelta } = this.sashDragState; this.sashDragState.current = current; const delta = current - start; - const newDelta = this.resize(index, delta, sizes, undefined, undefined, minDelta, maxDelta); + const newDelta = this.resize(index, delta, sizes, undefined, undefined, minDelta, maxDelta, snapIndex, snapLimitDelta); if (alt) { const isLastSash = index === this.sashItems.length - 1; const newSizes = this.viewItems.map(i => i.size); const viewItemIndex = isLastSash ? index : index + 1; const viewItem = this.viewItems[viewItemIndex]; - const newMinDelta = viewItem.size - viewItem.view.maximumSize; - const newMaxDelta = viewItem.size - viewItem.view.minimumSize; + const newMinDelta = viewItem.size - viewItem.maximumSize; + const newMaxDelta = viewItem.size - viewItem.minimumSize; const resizeIndex = isLastSash ? index - 1 : index + 1; this.resize(resizeIndex, -newDelta, newSizes, undefined, undefined, newMinDelta, newMaxDelta); @@ -435,7 +558,7 @@ export class SplitView extends Disposable { this.saveProportions(); } - private onViewChange(item: IViewItem, size: number | undefined): void { + private onViewChange(item: ViewItem, size: number | undefined): void { const index = this.viewItems.indexOf(item); if (index < 0 || index >= this.viewItems.length) { @@ -443,7 +566,7 @@ export class SplitView extends Disposable { } size = typeof size === 'number' ? size : item.size; - size = clamp(size, item.view.minimumSize, item.view.maximumSize); + size = clamp(size, item.minimumSize, item.maximumSize); if (this.inverseAltBehavior && index > 0) { // In this case, we want the view to grow or shrink both sides equally @@ -470,13 +593,13 @@ export class SplitView extends Disposable { const item = this.viewItems[index]; size = Math.round(size); - size = clamp(size, item.view.minimumSize, item.view.maximumSize); + size = clamp(size, item.minimumSize, item.maximumSize); let delta = size - item.size; if (delta !== 0 && index < this.viewItems.length - 1) { const downIndexes = range(index + 1, this.viewItems.length); - const collapseDown = downIndexes.reduce((r, i) => r + (this.viewItems[i].size - this.viewItems[i].view.minimumSize), 0); - const expandDown = downIndexes.reduce((r, i) => r + (this.viewItems[i].view.maximumSize - this.viewItems[i].size), 0); + const collapseDown = downIndexes.reduce((r, i) => r + (this.viewItems[i].size - this.viewItems[i].minimumSize), 0); + const expandDown = downIndexes.reduce((r, i) => r + (this.viewItems[i].maximumSize - this.viewItems[i].size), 0); const deltaDown = clamp(delta, -expandDown, collapseDown); this.resize(index, deltaDown); @@ -485,8 +608,8 @@ export class SplitView extends Disposable { if (delta !== 0 && index > 0) { const upIndexes = range(index - 1, -1); - const collapseUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].size - this.viewItems[i].view.minimumSize), 0); - const expandUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].view.maximumSize - this.viewItems[i].size), 0); + const collapseUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].size - this.viewItems[i].minimumSize), 0); + const expandUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].maximumSize - this.viewItems[i].size), 0); const deltaUp = clamp(-delta, -collapseUp, expandUp); this.resize(index - 1, deltaUp); @@ -521,7 +644,9 @@ export class SplitView extends Disposable { lowPriorityIndexes?: number[], highPriorityIndexes?: number[], overloadMinDelta: number = Number.NEGATIVE_INFINITY, - overloadMaxDelta: number = Number.POSITIVE_INFINITY + overloadMaxDelta: number = Number.POSITIVE_INFINITY, + snapIndex?: number, + snapLimitDelta?: number ): number { if (index < 0 || index >= this.viewItems.length) { return 0; @@ -550,18 +675,28 @@ export class SplitView extends Disposable { const downItems = downIndexes.map(i => this.viewItems[i]); const downSizes = downIndexes.map(i => sizes[i]); - const minDeltaUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].view.minimumSize - sizes[i]), 0); - const maxDeltaUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].view.maximumSize - sizes[i]), 0); - const maxDeltaDown = downIndexes.length === 0 ? Number.POSITIVE_INFINITY : downIndexes.reduce((r, i) => r + (sizes[i] - this.viewItems[i].view.minimumSize), 0); - const minDeltaDown = downIndexes.length === 0 ? Number.NEGATIVE_INFINITY : downIndexes.reduce((r, i) => r + (sizes[i] - this.viewItems[i].view.maximumSize), 0); + const minDeltaUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].minimumSize - sizes[i]), 0); + const maxDeltaUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].maximumSize - sizes[i]), 0); + const maxDeltaDown = downIndexes.length === 0 ? Number.POSITIVE_INFINITY : downIndexes.reduce((r, i) => r + (sizes[i] - this.viewItems[i].minimumSize), 0); + const minDeltaDown = downIndexes.length === 0 ? Number.NEGATIVE_INFINITY : downIndexes.reduce((r, i) => r + (sizes[i] - this.viewItems[i].maximumSize), 0); const minDelta = Math.max(minDeltaUp, minDeltaDown, overloadMinDelta); const maxDelta = Math.min(maxDeltaDown, maxDeltaUp, overloadMaxDelta); + if (typeof snapIndex === 'number' && typeof snapLimitDelta === 'number') { + const snapView = this.viewItems[snapIndex]; + + snapView.visible = snapIndex === index + ? delta >= snapLimitDelta // up + : delta < snapLimitDelta; // down + + return this.resize(index, delta, sizes, lowPriorityIndexes, highPriorityIndexes, overloadMinDelta, overloadMaxDelta); + } + delta = clamp(delta, minDelta, maxDelta); for (let i = 0, deltaUp = delta; i < upItems.length; i++) { const item = upItems[i]; - const size = clamp(upSizes[i] + deltaUp, item.view.minimumSize, item.view.maximumSize); + const size = clamp(upSizes[i] + deltaUp, item.minimumSize, item.maximumSize); const viewDelta = size - upSizes[i]; deltaUp -= viewDelta; @@ -570,7 +705,7 @@ export class SplitView extends Disposable { for (let i = 0, deltaDown = delta; i < downItems.length; i++) { const item = downItems[i]; - const size = clamp(downSizes[i] - deltaDown, item.view.minimumSize, item.view.maximumSize); + const size = clamp(downSizes[i] - deltaDown, item.minimumSize, item.maximumSize); const viewDelta = size - downSizes[i]; deltaDown += viewDelta; @@ -580,13 +715,19 @@ export class SplitView extends Disposable { return delta; } - private distributeEmptySpace(): void { - let contentSize = this.viewItems.reduce((r, i) => r + i.size, 0); + private distributeEmptySpace(lowPriorityIndex?: number): void { + const contentSize = this.viewItems.reduce((r, i) => r + i.size, 0); let emptyDelta = this.size - contentSize; - for (let i = this.viewItems.length - 1; emptyDelta !== 0 && i >= 0; i--) { - const item = this.viewItems[i]; - const size = clamp(item.size + emptyDelta, item.view.minimumSize, item.view.maximumSize); + const indexes = range(this.viewItems.length - 1, -1); + + if (typeof lowPriorityIndex === 'number') { + pushToEnd(indexes, lowPriorityIndex); + } + + for (let i = 0; emptyDelta !== 0 && i < indexes.length; i++) { + const item = this.viewItems[indexes[i]]; + const size = clamp(item.size + emptyDelta, item.minimumSize, item.maximumSize); const viewDelta = size - item.size; emptyDelta -= viewDelta; @@ -606,30 +747,43 @@ export class SplitView extends Disposable { // Update sashes enablement let previous = false; - const collapsesDown = this.viewItems.map(i => previous = (i.size - i.view.minimumSize > 0) || previous); + const collapsesDown = this.viewItems.map(i => previous = (i.size - i.minimumSize > 0) || previous); previous = false; - const expandsDown = this.viewItems.map(i => previous = (i.view.maximumSize - i.size > 0) || previous); + const expandsDown = this.viewItems.map(i => previous = (i.maximumSize - i.size > 0) || previous); const reverseViews = [...this.viewItems].reverse(); previous = false; - const collapsesUp = reverseViews.map(i => previous = (i.size - i.view.minimumSize > 0) || previous).reverse(); + const collapsesUp = reverseViews.map(i => previous = (i.size - i.minimumSize > 0) || previous).reverse(); previous = false; - const expandsUp = reverseViews.map(i => previous = (i.view.maximumSize - i.size > 0) || previous).reverse(); + const expandsUp = reverseViews.map(i => previous = (i.maximumSize - i.size > 0) || previous).reverse(); this.sashItems.forEach((s, i) => { - const min = !(collapsesDown[i] && expandsUp[i + 1]); - const max = !(expandsDown[i] && collapsesUp[i + 1]); - - if (min && max) { + if (!this.viewItems[i].visible) { s.sash.state = SashState.Disabled; - } else if (min && !max) { - s.sash.state = SashState.Minimum; - } else if (!min && max) { - s.sash.state = SashState.Maximum; } else { - s.sash.state = SashState.Enabled; + const min = !(collapsesDown[i] && expandsUp[i + 1]); + const max = !(expandsDown[i] && collapsesUp[i + 1]); + + if (min && max) { + const before = !range(0, i + 1).some(i => !this.viewItems[i].snap || this.viewItems[i].visible); + const after = !range(i + 1, this.viewItems.length).some(i => !this.viewItems[i].snap || this.viewItems[i].visible); + + if (before) { + s.sash.state = SashState.Minimum; + } else if (after) { + s.sash.state = SashState.Maximum; + } else { + s.sash.state = SashState.Disabled; + } + } else if (min && !max) { + s.sash.state = SashState.Minimum; + } else if (!min && max) { + s.sash.state = SashState.Maximum; + } else { + s.sash.state = SashState.Enabled; + } } }); } @@ -651,7 +805,7 @@ export class SplitView extends Disposable { dispose(): void { super.dispose(); - this.viewItems.forEach(i => i.disposable.dispose()); + this.viewItems.forEach(i => i.dispose()); this.viewItems = []; this.sashItems.forEach(i => i.disposable.dispose()); diff --git a/src/vs/base/browser/ui/toolbar/toolbar.css b/src/vs/base/browser/ui/toolbar/toolbar.css index f1fdad313ab..47669712253 100644 --- a/src/vs/base/browser/ui/toolbar/toolbar.css +++ b/src/vs/base/browser/ui/toolbar/toolbar.css @@ -17,5 +17,5 @@ } .hc-black .monaco-toolbar .action-label.toolbar-toggle-more { - background-image: url('ellipsis-dark.svg'); + background-image: url('ellipsis-hc.svg'); } \ No newline at end of file diff --git a/src/vs/base/node/id.ts b/src/vs/base/node/id.ts index 6f72afeed79..c2faa20632f 100644 --- a/src/vs/base/node/id.ts +++ b/src/vs/base/node/id.ts @@ -7,6 +7,7 @@ import * as errors from 'vs/base/common/errors'; import * as uuid from 'vs/base/common/uuid'; import { networkInterfaces } from 'os'; import { TernarySearchTree } from 'vs/base/common/map'; +import { getMac } from 'vs/base/node/macAddress'; // http://www.techrepublic.com/blog/data-center/mac-address-scorecard-for-common-virtual-machine-platforms/ // VMware ESX 3, Server, Workstation, Player 00-50-56, 00-0C-29, 00-05-69 @@ -76,35 +77,25 @@ export const virtualMachineHint: { value(): number } = new class { }; let machineId: Promise; -export function getMachineId(): Promise { - return machineId || (machineId = getMacMachineId() - .then(id => id || uuid.generateUuid())); // fallback, generate a UUID +export async function getMachineId(): Promise { + if (!machineId) { + machineId = (async () => { + const id = await getMacMachineId(); + + return id || uuid.generateUuid(); // fallback, generate a UUID + })(); + } + + return machineId; } -function getMacMachineId(): Promise { - return new Promise(resolve => { - Promise.all([import('crypto'), import('getmac')]).then(([crypto, getmac]) => { - try { - getmac.getMac((error, macAddress) => { - if (!error) { - resolve(crypto.createHash('sha256').update(macAddress, 'utf8').digest('hex')); - } else { - resolve(undefined); - } - }); - - // Timeout due to hang with reduced privileges #58392 - // TODO@sbatten: Remove this when getmac is patched - setTimeout(() => { - resolve(undefined); - }, 10000); - } catch (err) { - errors.onUnexpectedError(err); - resolve(undefined); - } - }, err => { - errors.onUnexpectedError(err); - resolve(undefined); - }); - }); +async function getMacMachineId(): Promise { + try { + const crypto = await import('crypto'); + const macAddress = await getMac(); + return crypto.createHash('sha256').update(macAddress, 'utf8').digest('hex'); + } catch (err) { + errors.onUnexpectedError(err); + return undefined; + } } diff --git a/src/vs/base/node/macAddress.ts b/src/vs/base/node/macAddress.ts new file mode 100644 index 00000000000..dd36be22344 --- /dev/null +++ b/src/vs/base/node/macAddress.ts @@ -0,0 +1,69 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { exec } from 'child_process'; +import { isWindows } from 'vs/base/common/platform'; + +const cmdline = { + windows: 'getmac.exe', + unix: '/sbin/ifconfig -a || /sbin/ip link' +}; + +const invalidMacAddresses = [ + '00:00:00:00:00:00', + 'ff:ff:ff:ff:ff:ff', + 'ac:de:48:00:11:22' +]; + +function validateMacAddress(candidate: string): boolean { + let tempCandidate = candidate.replace(/\-/g, ':').toLowerCase(); + for (let invalidMacAddress of invalidMacAddresses) { + if (invalidMacAddress === tempCandidate) { + return false; + } + } + + return true; +} + +export function getMac(): Promise { + return new Promise(async (resolve, reject) => { + const timeout = setTimeout(() => reject('Unable to retrieve mac address (timeout after 10s)'), 10000); + + try { + resolve(await doGetMac()); + } catch (error) { + reject(error); + } finally { + clearTimeout(timeout); + } + }); +} + +function doGetMac(): Promise { + return new Promise((resolve, reject) => { + try { + exec(isWindows ? cmdline.windows : cmdline.unix, { timeout: 10000 }, (err, stdout, stdin) => { + if (err) { + return reject(`Unable to retrieve mac address (${err.toString()})`); + } else { + const regex = /(?:[a-f\d]{2}[:\-]){5}[a-f\d]{2}/gi; + + let match; + while ((match = regex.exec(stdout)) !== null) { + const macAddressCandidate = match[0]; + if (validateMacAddress(macAddressCandidate)) { + return resolve(macAddressCandidate); + } + } + + return reject('Unable to retrieve mac address (unexpected format)'); + } + }); + } catch (err) { + reject(err); + } + }); +} \ No newline at end of file diff --git a/src/vs/base/test/node/id.test.ts b/src/vs/base/test/node/id.test.ts index 689bb126d6b..637afa5b550 100644 --- a/src/vs/base/test/node/id.test.ts +++ b/src/vs/base/test/node/id.test.ts @@ -3,8 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import * as getmac from 'getmac'; import { getMachineId } from 'vs/base/node/id'; +import { getMac } from 'vs/base/node/macAddress'; suite('ID', () => { @@ -16,9 +16,7 @@ suite('ID', () => { }); test('getMac', () => { - return new Promise((resolve, reject) => { - getmac.getMac((err, macAddress) => err ? reject(err) : resolve(macAddress)); - }).then(macAddress => { + return getMac().then(macAddress => { assert.ok(/^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/.test(macAddress), `Expected a MAC address, got: ${macAddress}`); }); }); diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts index e713834efe6..854373e8920 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts @@ -16,7 +16,7 @@ import { EnvironmentService } from 'vs/platform/environment/node/environmentServ import { ExtensionManagementChannel } from 'vs/platform/extensionManagement/node/extensionManagementIpc'; import { IExtensionManagementService, IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { ExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService'; -import { ExtensionGalleryService } from 'vs/platform/extensionManagement/node/extensionGalleryService'; +import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ConfigurationService } from 'vs/platform/configuration/node/configurationService'; import { IRequestService } from 'vs/platform/request/common/request'; @@ -55,6 +55,8 @@ 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'; +import { IProductService } from 'vs/platform/product/common/product'; +import { ProductService } from 'vs/platform/product/node/productService'; export interface ISharedProcessConfiguration { readonly machineId: string; @@ -114,6 +116,7 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat services.set(IConfigurationService, configurationService); services.set(IRequestService, new SyncDescriptor(RequestService)); services.set(IDownloadService, new SyncDescriptor(DownloadService)); + services.set(IProductService, new SyncDescriptor(ProductService)); const mainProcessService = new MainProcessService(server, mainRouter); services.set(IMainProcessService, mainProcessService); diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index f70eece8b30..cd81cc3dbb2 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -90,6 +90,7 @@ import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemPro export class CodeApplication extends Disposable { private static readonly MACHINE_ID_KEY = 'telemetry.machineId'; + private static readonly TRUE_MACHINE_ID_KEY = 'telemetry.trueMachineId'; private windowsMainService: IWindowsMainService | undefined; @@ -363,8 +364,8 @@ export class CodeApplication extends Disposable { // Resolve unique machine ID this.logService.trace('Resolving machine identifier...'); - const machineId = await this.resolveMachineId(); - this.logService.trace(`Resolved machine identifier: ${machineId}`); + const { machineId, trueMachineId } = await this.resolveMachineId(); + this.logService.trace(`Resolved machine identifier: ${machineId} (trueMachineId: ${trueMachineId})`); // Spawn shared process after the first window has opened and 3s have passed const sharedProcess = this.instantiationService.createInstance(SharedProcess, machineId, this.userEnv); @@ -378,7 +379,7 @@ export class CodeApplication extends Disposable { }); // Services - const appInstantiationService = await this.createServices(machineId, sharedProcess, sharedProcessClient); + const appInstantiationService = await this.createServices(machineId, trueMachineId, sharedProcess, sharedProcessClient); // Create driver if (this.environmentService.driverHandle) { @@ -404,7 +405,7 @@ export class CodeApplication extends Disposable { } } - private async resolveMachineId(): Promise { + private async resolveMachineId(): Promise<{ machineId: string, trueMachineId?: string }> { // We cache the machineId for faster lookups on startup // and resolve it only once initially if not cached @@ -415,10 +416,21 @@ export class CodeApplication extends Disposable { this.stateService.setItem(CodeApplication.MACHINE_ID_KEY, machineId); } - return machineId; + // Check if machineId is hashed iBridge Device + let trueMachineId: string | undefined; + if (isMacintosh && machineId === '6c9d2bc8f91b89624add29c0abeae7fb42bf539fa1cdb2e3e57cd668fa9bcead') { + trueMachineId = this.stateService.getItem(CodeApplication.TRUE_MACHINE_ID_KEY); + if (!trueMachineId) { + trueMachineId = await getMachineId(); + + this.stateService.setItem(CodeApplication.TRUE_MACHINE_ID_KEY, trueMachineId); + } + } + + return { machineId, trueMachineId }; } - private async createServices(machineId: string, sharedProcess: SharedProcess, sharedProcessClient: Promise>): Promise { + private async createServices(machineId: string, trueMachineId: string | undefined, sharedProcess: SharedProcess, sharedProcessClient: Promise>): Promise { const services = new ServiceCollection(); // Files @@ -473,7 +485,7 @@ export class CodeApplication extends Disposable { const appender = combinedAppender(new TelemetryAppenderClient(channel), new LogAppender(this.logService)); const commonProperties = resolveCommonProperties(product.commit, pkg.version, machineId, this.environmentService.installSourcePath); const piiPaths = [this.environmentService.appRoot, this.environmentService.extensionsPath]; - const config: ITelemetryServiceConfig = { appender, commonProperties, piiPaths }; + const config: ITelemetryServiceConfig = { appender, commonProperties, piiPaths, trueMachineId }; services.set(ITelemetryService, new SyncDescriptor(TelemetryService, [config])); } else { diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index e6cb0ebb5e5..48055ea9071 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -21,10 +21,12 @@ import { IWorkspaceIdentifier, IWorkspacesMainService } from 'vs/platform/worksp import { IBackupMainService } from 'vs/platform/backup/common/backup'; import { ISerializableCommandAction } from 'vs/platform/actions/common/actions'; import * as perf from 'vs/base/common/performance'; -import { resolveMarketplaceHeaders } from 'vs/platform/extensionManagement/node/extensionGalleryService'; +import { resolveMarketplaceHeaders } from 'vs/platform/extensionManagement/common/extensionGalleryService'; import { IThemeMainService } from 'vs/platform/theme/electron-main/themeMainService'; import { endsWith } from 'vs/base/common/strings'; import { RunOnceScheduler } from 'vs/base/common/async'; +import { IFileService } from 'vs/platform/files/common/files'; +import pkg from 'vs/platform/product/node/package'; const RUN_TEXTMATE_IN_WORKER = false; @@ -76,6 +78,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { config: IWindowCreationOptions, @ILogService private readonly logService: ILogService, @IEnvironmentService private readonly environmentService: IEnvironmentService, + @IFileService private readonly fileService: IFileService, @IConfigurationService private readonly configurationService: IConfigurationService, @IThemeMainService private readonly themeMainService: IThemeMainService, @IWorkspacesMainService private readonly workspacesMainService: IWorkspacesMainService, @@ -307,7 +310,7 @@ export class CodeWindow extends Disposable implements ICodeWindow { private handleMarketplaceRequests(): void { // Resolve marketplace headers - this.marketplaceHeadersPromise = resolveMarketplaceHeaders(this.environmentService); + this.marketplaceHeadersPromise = resolveMarketplaceHeaders(pkg.version, this.environmentService, this.fileService); // Inject headers when requests are incoming const urls = ['https://marketplace.visualstudio.com/*', 'https://*.vsassets.io/*']; diff --git a/src/vs/code/electron-main/windows.ts b/src/vs/code/electron-main/windows.ts index ad3025e5c3c..be336e02113 100644 --- a/src/vs/code/electron-main/windows.ts +++ b/src/vs/code/electron-main/windows.ts @@ -207,46 +207,17 @@ export class WindowsManager extends Disposable implements IWindowsMainService { this.workspacesManager = new WorkspacesManager(workspacesMainService, backupMainService, this); this.lifecycleService.when(LifecycleMainPhase.Ready).then(() => this.registerListeners()); - this.lifecycleService.when(LifecycleMainPhase.AfterWindowOpen).then(() => this.setupNativeHelpers()); + this.lifecycleService.when(LifecycleMainPhase.AfterWindowOpen).then(() => this.installWindowsMutex()); } - private setupNativeHelpers(): void { + private installWindowsMutex(): void { if (isWindows) { - - // Setup Windows mutex try { const WindowsMutex = (require.__$__nodeRequire('windows-mutex') as typeof import('windows-mutex')).Mutex; const mutex = new WindowsMutex(product.win32MutexName); once(this.lifecycleService.onWillShutdown)(() => mutex.release()); } catch (e) { this.logService.error(e); - - if (!this.environmentService.isBuilt) { - this.showMessageBox({ - title: product.nameLong, - type: 'warning', - message: 'Failed to load windows-mutex!', - detail: e.toString(), - noLink: true - }); - } - } - - // Dev only: Ensure Windows foreground love module is present - if (!this.environmentService.isBuilt) { - try { - require.__$__nodeRequire('windows-foreground-love'); - } catch (e) { - this.logService.error(e); - - this.showMessageBox({ - title: product.nameLong, - type: 'warning', - message: 'Failed to load windows-foreground-love!', - detail: e.toString(), - noLink: true - }); - } } } } diff --git a/src/vs/code/node/cliProcessMain.ts b/src/vs/code/node/cliProcessMain.ts index 092c1f6be7c..3a7b44232e3 100644 --- a/src/vs/code/node/cliProcessMain.ts +++ b/src/vs/code/node/cliProcessMain.ts @@ -17,7 +17,7 @@ import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/ import { EnvironmentService } from 'vs/platform/environment/node/environmentService'; import { IExtensionManagementService, IExtensionGalleryService, IGalleryExtension, ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement'; import { ExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService'; -import { ExtensionGalleryService } from 'vs/platform/extensionManagement/node/extensionGalleryService'; +import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService'; 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'; @@ -46,6 +46,8 @@ 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'; +import { IProductService } from 'vs/platform/product/common/product'; +import { ProductService } from 'vs/platform/product/node/productService'; const notFound = (id: string) => localize('notFound', "Extension '{0}' not found.", id); const notInstalled = (id: string) => localize('notInstalled', "Extension '{0}' is not installed.", id); @@ -301,6 +303,7 @@ export async function main(argv: ParsedArgs): Promise { services.set(ILogService, logService); services.set(IConfigurationService, configurationService); services.set(IStateService, new SyncDescriptor(StateService)); + services.set(IProductService, new SyncDescriptor(ProductService)); // Files const fileService = new FileService(logService); diff --git a/src/vs/code/test/electron-main/nativeHelpers.test.ts b/src/vs/code/test/electron-main/nativeHelpers.test.ts new file mode 100644 index 00000000000..ff0f589d511 --- /dev/null +++ b/src/vs/code/test/electron-main/nativeHelpers.test.ts @@ -0,0 +1,28 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import { isWindows } from 'vs/base/common/platform'; + +suite('Windows Native Helpers', () => { + test('windows-mutex', async () => { + if (!isWindows) { + return; + } + + const mutex = await import('windows-mutex'); + assert.ok(mutex, 'Unable to load windows-mutex dependency.'); + assert.ok(typeof mutex.isActive === 'function', 'Unable to load windows-mutex dependency.'); + }); + + test('windows-foreground-love', async () => { + if (!isWindows) { + return; + } + + const foregroundLove = await import('windows-foreground-love'); + assert.ok(foregroundLove, 'Unable to load windows-foreground-love dependency.'); + }); +}); \ No newline at end of file diff --git a/src/vs/editor/contrib/codeAction/codeActionCommands.ts b/src/vs/editor/contrib/codeAction/codeActionCommands.ts index 4484c4405dc..1b76fa157ee 100644 --- a/src/vs/editor/contrib/codeAction/codeActionCommands.ts +++ b/src/vs/editor/contrib/codeAction/codeActionCommands.ts @@ -80,7 +80,7 @@ export class QuickFixController extends Disposable implements IEditorContributio this._ui.update(newState); } - public showCodeActions(actions: Promise, at: IAnchor | IPosition) { + public showCodeActions(actions: CodeActionSet, at: IAnchor | IPosition) { return this._ui.showCodeActionList(actions, at); } diff --git a/src/vs/editor/contrib/codeAction/codeActionUi.ts b/src/vs/editor/contrib/codeAction/codeActionUi.ts index 8b5bf92538d..a496f3e708f 100644 --- a/src/vs/editor/contrib/codeAction/codeActionUi.ts +++ b/src/vs/editor/contrib/codeAction/codeActionUi.ts @@ -95,15 +95,7 @@ export class CodeActionUi extends Disposable { } } - public async showCodeActionList(codeActions: Promise, at?: IAnchor | IPosition): Promise { - let actions: CodeActionSet; - try { - actions = await codeActions; - } catch (e) { - onUnexpectedError(e); - return; - } - + public async showCodeActionList(actions: CodeActionSet, at?: IAnchor | IPosition): Promise { this._codeActionWidget.show(actions, at); } diff --git a/src/vs/editor/contrib/hover/modesContentHover.ts b/src/vs/editor/contrib/hover/modesContentHover.ts index 80c7a0661c9..7bc5a7fb022 100644 --- a/src/vs/editor/contrib/hover/modesContentHover.ts +++ b/src/vs/editor/contrib/hover/modesContentHover.ts @@ -13,7 +13,7 @@ import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { Position } from 'vs/editor/common/core/position'; import { IRange, Range } from 'vs/editor/common/core/range'; import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; -import { DocumentColorProvider, Hover as MarkdownHover, HoverProviderRegistry, IColor, CodeAction } from 'vs/editor/common/modes'; +import { DocumentColorProvider, Hover as MarkdownHover, HoverProviderRegistry, IColor } from 'vs/editor/common/modes'; import { getColorPresentations } from 'vs/editor/contrib/colorPicker/color'; import { ColorDetector } from 'vs/editor/contrib/colorPicker/colorDetector'; import { ColorPickerModel } from 'vs/editor/contrib/colorPicker/colorPickerModel'; @@ -517,21 +517,6 @@ export class ModesContentHoverWidget extends ContentHoverWidget { const hoverElement = $('div.hover-row.status-bar'); const disposables = new DisposableStore(); const actionsElement = dom.append(hoverElement, $('div.actions')); - disposables.add(this.renderAction(actionsElement, { - label: nls.localize('quick fixes', "Quick Fix..."), - commandId: QuickFixAction.Id, - run: async (target) => { - const codeActionsPromise = this.getCodeActions(markerHover.marker); - disposables.add(toDisposable(() => codeActionsPromise.cancel())); - - const controller = QuickFixController.get(this._editor); - const elementPosition = dom.getDomNodePagePosition(target); - controller.showCodeActions(codeActionsPromise, { - x: elementPosition.left + 6, - y: elementPosition.top + elementPosition.height + 6 - }); - } - })); if (markerHover.marker.severity === MarkerSeverity.Error || markerHover.marker.severity === MarkerSeverity.Warning || markerHover.marker.severity === MarkerSeverity.Info) { disposables.add(this.renderAction(actionsElement, { label: nls.localize('peek problem', "Peek Problem"), @@ -543,27 +528,61 @@ export class ModesContentHoverWidget extends ContentHoverWidget { } })); } + + const quickfixPlaceholderElement = dom.append(actionsElement, $('div')); + quickfixPlaceholderElement.style.opacity = '0'; + quickfixPlaceholderElement.style.transition = 'opacity 0.2s'; + setTimeout(() => quickfixPlaceholderElement.style.opacity = '1', 200); + quickfixPlaceholderElement.textContent = nls.localize('checkingForQuickFixes', "Checking for quick fixes..."); + disposables.add(toDisposable(() => quickfixPlaceholderElement.remove())); + + + const codeActionsPromise = this.getCodeActions(markerHover.marker); + disposables.add(toDisposable(() => codeActionsPromise.cancel())); + codeActionsPromise.then(actions => { + quickfixPlaceholderElement.style.transition = ''; + quickfixPlaceholderElement.style.opacity = '1'; + + if (!actions.actions.length) { + actions.dispose(); + quickfixPlaceholderElement.textContent = nls.localize('noQuickFixes', "No quick fixes available"); + return; + } + quickfixPlaceholderElement.remove(); + + let showing = false; + disposables.add(toDisposable(() => { + if (!showing) { + actions.dispose(); + } + })); + + disposables.add(this.renderAction(actionsElement, { + label: nls.localize('quick fixes', "Quick Fix..."), + commandId: QuickFixAction.Id, + run: (target) => { + showing = true; + const controller = QuickFixController.get(this._editor); + const elementPosition = dom.getDomNodePagePosition(target); + controller.showCodeActions(actions, { + x: elementPosition.left + 6, + y: elementPosition.top + elementPosition.height + 6 + }); + } + })); + }); + this.renderDisposable.value = disposables; return hoverElement; } private getCodeActions(marker: IMarker): CancelablePromise { - const noAction: CodeAction = { - title: nls.localize('editor.action.quickFix.noneMessage', "No code actions available"), - kind: CodeActionKind.QuickFix.value, - }; - return createCancelablePromise(async (cancellationToken): Promise => { - const result = await getCodeActions( + return createCancelablePromise(cancellationToken => { + return getCodeActions( this._editor.getModel()!, new Range(marker.startLineNumber, marker.startColumn, marker.endLineNumber, marker.endColumn), { type: 'manual', filter: { kind: CodeActionKind.QuickFix } }, cancellationToken); - - return { - actions: result.actions.length ? result.actions : [noAction], - hasAutoFix: result.hasAutoFix, - dispose: () => result.dispose(), - }; }); } diff --git a/src/vs/platform/extensionManagement/node/extensionGalleryService.ts b/src/vs/platform/extensionManagement/common/extensionGalleryService.ts similarity index 93% rename from src/vs/platform/extensionManagement/node/extensionGalleryService.ts rename to src/vs/platform/extensionManagement/common/extensionGalleryService.ts index 71c67d5bda3..08c4c3a022f 100644 --- a/src/vs/platform/extensionManagement/node/extensionGalleryService.ts +++ b/src/vs/platform/extensionManagement/common/extensionGalleryService.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { tmpdir } from 'os'; -import * as path from 'vs/base/common/path'; import { getErrorMessage, isPromiseCanceledError, canceled } from 'vs/base/common/errors'; 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'; @@ -12,11 +10,8 @@ import { assign, getOrDefault } from 'vs/base/common/objects'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IPager } from 'vs/base/common/paging'; 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'; +import { isEngineValid } from 'vs/platform/extensions/common/extensionValidator'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { writeFileSync, readFile } from 'vs/base/node/pfs'; import { generateUuid, isUUID } from 'vs/base/common/uuid'; import { values } from 'vs/base/common/map'; import { CancellationToken } from 'vs/base/common/cancellation'; @@ -24,6 +19,9 @@ 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'; +import { joinPath } from 'vs/base/common/resources'; +import { VSBuffer } from 'vs/base/common/buffer'; +import { IProductService } from 'vs/platform/product/common/product'; interface IRawGalleryExtensionFile { assetType: string; @@ -339,11 +337,12 @@ export class ExtensionGalleryService implements IExtensionGalleryService { @IEnvironmentService private readonly environmentService: IEnvironmentService, @ITelemetryService private readonly telemetryService: ITelemetryService, @IFileService private readonly fileService: IFileService, + @IProductService private readonly productService: IProductService, ) { - const config = product.extensionsGallery; + const config = productService.extensionsGallery; this.extensionsGalleryUrl = config && config.serviceUrl; this.extensionsControlUrl = config && config.controlUrl; - this.commonHeadersPromise = resolveMarketplaceHeaders(this.environmentService); + this.commonHeadersPromise = resolveMarketplaceHeaders(productService.version, this.environmentService, this.fileService); } private api(path = ''): string { @@ -356,7 +355,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService { getCompatibleExtension(arg1: IExtensionIdentifier | IGalleryExtension, version?: string): Promise { const extension: IGalleryExtension | null = isIExtensionIdentifier(arg1) ? null : arg1; - if (extension && extension.properties.engine && isEngineValid(extension.properties.engine)) { + if (extension && extension.properties.engine && isEngineValid(extension.properties.engine, this.productService.version)) { return Promise.resolve(extension); } const { id, uuid } = extension ? extension.identifier : arg1; @@ -382,7 +381,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService { const versionAsset = rawExtension.versions.filter(v => v.version === version)[0]; if (versionAsset) { const extension = toExtension(rawExtension, versionAsset, 0, query); - if (extension.properties.engine && isEngineValid(extension.properties.engine)) { + if (extension.properties.engine && isEngineValid(extension.properties.engine, this.productService.version)) { return extension; } } @@ -535,9 +534,9 @@ export class ExtensionGalleryService implements IExtensionGalleryService { }); } - download(extension: IGalleryExtension, operation: InstallOperation): Promise { + download(extension: IGalleryExtension, location: URI, operation: InstallOperation): Promise { this.logService.trace('ExtensionGalleryService#download', extension.identifier.id); - const zipPath = path.join(tmpdir(), generateUuid()); + const zip = joinPath(location, generateUuid()); const data = getGalleryExtensionTelemetryData(extension); const startTime = new Date().getTime(); /* __GDPR__ @@ -557,9 +556,9 @@ export class ExtensionGalleryService implements IExtensionGalleryService { } : extension.assets.download; return this.getAsset(downloadAsset) - .then(context => this.fileService.writeFile(URI.file(zipPath), context.stream)) + .then(context => this.fileService.writeFile(zip, context.stream)) .then(() => log(new Date().getTime() - startTime)) - .then(() => zipPath); + .then(() => zip); } getReadme(extension: IGalleryExtension, token: CancellationToken): Promise { @@ -615,7 +614,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService { return this.queryGallery(query, CancellationToken.None).then(({ galleryExtensions }) => { if (galleryExtensions.length) { if (compatible) { - return Promise.all(galleryExtensions[0].versions.map(v => this.getEngine(v).then(engine => isEngineValid(engine) ? v : null))) + return Promise.all(galleryExtensions[0].versions.map(v => this.getEngine(v).then(engine => isEngineValid(engine, this.productService.version) ? v : null))) .then(versions => versions .filter(v => !!v) .map(v => ({ version: v!.version, date: v!.lastUpdated }))); @@ -701,7 +700,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService { if (!engine) { return null; } - if (isEngineValid(engine)) { + if (isEngineValid(engine, this.productService.version)) { return Promise.resolve(version); } } @@ -733,7 +732,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService { const version = versions[0]; return this.getEngine(version) .then(engine => { - if (!isEngineValid(engine)) { + if (!isEngineValid(engine, this.productService.version)) { return this.getLastValidExtensionVersionRecursively(extension, versions.slice(1)); } @@ -774,24 +773,30 @@ export class ExtensionGalleryService implements IExtensionGalleryService { } } -export function resolveMarketplaceHeaders(environmentService: IEnvironmentService): Promise<{ [key: string]: string; }> { - const marketplaceMachineIdFile = path.join(environmentService.userDataPath, 'machineid'); +export async function resolveMarketplaceHeaders(version: string, environmentService: IEnvironmentService, fileService: IFileService): Promise<{ [key: string]: string; }> { + const marketplaceMachineIdFile = joinPath(URI.file(environmentService.userDataPath), 'machineid'); - return readFile(marketplaceMachineIdFile, 'utf8') - .then(contents => isUUID(contents) ? contents : null, () => null /* error reading ID file */) - .then(uuid => { - if (!uuid) { - uuid = generateUuid(); - try { - writeFileSync(marketplaceMachineIdFile, uuid); - } catch (error) { - //noop - } - } - return { - 'X-Market-Client-Id': `VSCode ${pkg.version}`, - 'User-Agent': `VSCode ${pkg.version}`, - 'X-Market-User-Id': uuid - }; - }); + let uuid: string | null = null; + + try { + const contents = await fileService.readFile(marketplaceMachineIdFile); + const value = contents.value.toString(); + uuid = isUUID(value) ? value : null; + } catch (e) { + uuid = null; + } + + if (!uuid) { + uuid = generateUuid(); + try { + await fileService.writeFile(marketplaceMachineIdFile, VSBuffer.fromString(uuid)); + } catch (error) { + //noop + } + } + return { + 'X-Market-Client-Id': `VSCode ${version}`, + 'User-Agent': `VSCode ${version}`, + 'X-Market-User-Id': uuid + }; } \ No newline at end of file diff --git a/src/vs/platform/extensionManagement/common/extensionManagement.ts b/src/vs/platform/extensionManagement/common/extensionManagement.ts index ad60965cfd1..0edfddb4904 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagement.ts @@ -151,7 +151,7 @@ export interface IExtensionGalleryService { isEnabled(): boolean; query(token: CancellationToken): Promise>; query(options: IQueryOptions, token: CancellationToken): Promise>; - download(extension: IGalleryExtension, operation: InstallOperation): Promise; + download(extension: IGalleryExtension, location: URI, operation: InstallOperation): Promise; reportStatistic(publisher: string, name: string, version: string, type: StatisticType): Promise; getReadme(extension: IGalleryExtension, token: CancellationToken): Promise; getManifest(extension: IGalleryExtension, token: CancellationToken): Promise; diff --git a/src/vs/platform/extensionManagement/node/extensionManagementService.ts b/src/vs/platform/extensionManagement/node/extensionManagementService.ts index e09049c5b94..fdad3b308e7 100644 --- a/src/vs/platform/extensionManagement/node/extensionManagementService.ts +++ b/src/vs/platform/extensionManagement/node/extensionManagementService.ts @@ -35,7 +35,7 @@ import { ExtensionsManifestCache } from 'vs/platform/extensionManagement/node/ex import { ExtensionsLifecycle } from 'vs/platform/extensionManagement/node/extensionLifecycle'; import { toErrorMessage } from 'vs/base/common/errorMessage'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { isEngineValid } from 'vs/platform/extensions/node/extensionValidator'; +import { isEngineValid } from 'vs/platform/extensions/common/extensionValidator'; import { tmpdir } from 'os'; import { generateUuid } from 'vs/base/common/uuid'; import { IDownloadService } from 'vs/platform/download/common/download'; @@ -197,7 +197,7 @@ export class ExtensionManagementService extends Disposable implements IExtension .then(manifest => { const identifier = { id: getGalleryExtensionId(manifest.publisher, manifest.name) }; let operation: InstallOperation = InstallOperation.Install; - if (manifest.engines && manifest.engines.vscode && !isEngineValid(manifest.engines.vscode)) { + if (manifest.engines && manifest.engines.vscode && !isEngineValid(manifest.engines.vscode, pkg.version)) { return Promise.reject(new Error(nls.localize('incompatible', "Unable to install extension '{0}' as it is not compatible with VS Code '{1}'.", identifier.id, pkg.version))); } const identifierWithVersion = new ExtensionIdentifierWithVersion(identifier, manifest.version); @@ -391,9 +391,10 @@ export class ExtensionManagementService extends Disposable implements IExtension }; this.logService.trace('Started downloading extension:', extension.identifier.id); - return this.galleryService.download(extension, operation) + return this.galleryService.download(extension, URI.file(tmpdir()), operation) .then( - zipPath => { + zip => { + const zipPath = zip.fsPath; this.logService.info('Downloaded extension:', extension.identifier.id, zipPath); return getManifest(zipPath) .then( diff --git a/src/vs/platform/extensionManagement/test/node/extensionGalleryService.test.ts b/src/vs/platform/extensionManagement/test/node/extensionGalleryService.test.ts index f29376fea98..f579807f76c 100644 --- a/src/vs/platform/extensionManagement/test/node/extensionGalleryService.test.ts +++ b/src/vs/platform/extensionManagement/test/node/extensionGalleryService.test.ts @@ -10,15 +10,32 @@ import { parseArgs } from 'vs/platform/environment/node/argv'; import { getRandomTestPath } from 'vs/base/test/node/testUtils'; import { join } from 'vs/base/common/path'; import { mkdirp, RimRafMode, rimraf } from 'vs/base/node/pfs'; -import { resolveMarketplaceHeaders } from 'vs/platform/extensionManagement/node/extensionGalleryService'; +import { resolveMarketplaceHeaders } from 'vs/platform/extensionManagement/common/extensionGalleryService'; import { isUUID } from 'vs/base/common/uuid'; +import { DisposableStore } from 'vs/base/common/lifecycle'; +import { IFileService } from 'vs/platform/files/common/files'; +import { FileService } from 'vs/platform/files/common/fileService'; +import { NullLogService } from 'vs/platform/log/common/log'; +import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemProvider'; +import { Schemas } from 'vs/base/common/network'; +import pkg from 'vs/platform/product/node/package'; suite('Extension Gallery Service', () => { const parentDir = getRandomTestPath(os.tmpdir(), 'vsctests', 'extensiongalleryservice'); const marketplaceHome = join(parentDir, 'Marketplace'); + let fileService: IFileService; + let disposables: DisposableStore; setup(done => { + disposables = new DisposableStore(); + fileService = new FileService(new NullLogService()); + disposables.add(fileService); + + const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService()); + disposables.add(diskFileSystemProvider); + fileService.registerProvider(Schemas.file, diskFileSystemProvider); + // Delete any existing backups completely and then re-create it. rimraf(marketplaceHome, RimRafMode.MOVE).then(() => { mkdirp(marketplaceHome).then(() => { @@ -28,6 +45,7 @@ suite('Extension Gallery Service', () => { }); teardown(done => { + disposables.clear(); rimraf(marketplaceHome, RimRafMode.MOVE).then(done, done); }); @@ -35,10 +53,10 @@ suite('Extension Gallery Service', () => { const args = ['--user-data-dir', marketplaceHome]; const environmentService = new EnvironmentService(parseArgs(args), process.execPath); - return resolveMarketplaceHeaders(environmentService).then(headers => { + return resolveMarketplaceHeaders(pkg.version, environmentService, fileService).then(headers => { assert.ok(isUUID(headers['X-Market-User-Id'])); - return resolveMarketplaceHeaders(environmentService).then(headers2 => { + return resolveMarketplaceHeaders(pkg.version, environmentService, fileService).then(headers2 => { assert.equal(headers['X-Market-User-Id'], headers2['X-Market-User-Id']); }); }); diff --git a/src/vs/platform/extensions/node/extensionValidator.ts b/src/vs/platform/extensions/common/extensionValidator.ts similarity index 97% rename from src/vs/platform/extensions/node/extensionValidator.ts rename to src/vs/platform/extensions/common/extensionValidator.ts index 3234b2b85db..77f125ff220 100644 --- a/src/vs/platform/extensions/node/extensionValidator.ts +++ b/src/vs/platform/extensions/common/extensionValidator.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import * as nls from 'vs/nls'; -import pkg from 'vs/platform/product/node/package'; export interface IParsedVersion { hasCaret: boolean; @@ -222,9 +221,9 @@ export function isValidExtensionVersion(version: string, extensionDesc: IReduced return isVersionValid(version, extensionDesc.engines.vscode, notices); } -export function isEngineValid(engine: string): boolean { +export function isEngineValid(engine: string, version: string): boolean { // TODO@joao: discuss with alex '*' doesn't seem to be a valid engine version - return engine === '*' || isVersionValid(pkg.version, engine); + return engine === '*' || isVersionValid(version, engine); } export function isVersionValid(currentVersion: string, requestedVersion: string, notices: string[] = []): boolean { diff --git a/src/vs/platform/extensions/test/node/extensionValidator.test.ts b/src/vs/platform/extensions/test/node/extensionValidator.test.ts index f88885d9508..860d2201e73 100644 --- a/src/vs/platform/extensions/test/node/extensionValidator.test.ts +++ b/src/vs/platform/extensions/test/node/extensionValidator.test.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { INormalizedVersion, IParsedVersion, IReducedExtensionDescription, isValidExtensionVersion, isValidVersion, isValidVersionStr, normalizeVersion, parseVersion } from 'vs/platform/extensions/node/extensionValidator'; +import { INormalizedVersion, IParsedVersion, IReducedExtensionDescription, isValidExtensionVersion, isValidVersion, isValidVersionStr, normalizeVersion, parseVersion } from 'vs/platform/extensions/common/extensionValidator'; suite('Extension Version Validator', () => { diff --git a/src/vs/platform/files/test/node/diskFileService.test.ts b/src/vs/platform/files/test/node/diskFileService.test.ts index 33b3a30717c..6d10050ec0e 100644 --- a/src/vs/platform/files/test/node/diskFileService.test.ts +++ b/src/vs/platform/files/test/node/diskFileService.test.ts @@ -1696,7 +1696,9 @@ suite('Disk File Service', () => { assert.ok(!error); }); - test('watch - file', done => { + const runWatchTests = isLinux; + + (runWatchTests ? test : test.skip)('watch - file', done => { const toWatch = URI.file(join(testDir, 'index-watch1.html')); writeFileSync(toWatch.fsPath, 'Init'); @@ -1705,11 +1707,7 @@ suite('Disk File Service', () => { setTimeout(() => writeFileSync(toWatch.fsPath, 'Changes'), 50); }); - test('watch - file symbolic link', async done => { - if (isWindows) { - return done(); // watch tests are flaky on other platforms - } - + (runWatchTests && !isWindows /* symbolic links not reliable on windows */ ? test : test.skip)('watch - file symbolic link', async done => { const toWatch = URI.file(join(testDir, 'lorem.txt-linked')); await symlink(join(testDir, 'lorem.txt'), toWatch.fsPath); @@ -1718,11 +1716,7 @@ suite('Disk File Service', () => { setTimeout(() => writeFileSync(toWatch.fsPath, 'Changes'), 50); }); - test('watch - file - multiple writes', done => { - if (isWindows) { - return done(); // watch tests are flaky on other platforms - } - + (runWatchTests ? test : test.skip)('watch - file - multiple writes', done => { const toWatch = URI.file(join(testDir, 'index-watch1.html')); writeFileSync(toWatch.fsPath, 'Init'); @@ -1733,7 +1727,7 @@ suite('Disk File Service', () => { setTimeout(() => writeFileSync(toWatch.fsPath, 'Changes 3'), 20); }); - test('watch - file - delete file', done => { + (runWatchTests ? test : test.skip)('watch - file - delete file', done => { const toWatch = URI.file(join(testDir, 'index-watch1.html')); writeFileSync(toWatch.fsPath, 'Init'); @@ -1742,11 +1736,7 @@ suite('Disk File Service', () => { setTimeout(() => unlinkSync(toWatch.fsPath), 50); }); - test('watch - file - rename file', done => { - if (isWindows) { - return done(); // watch tests are flaky on other platforms - } - + (runWatchTests ? test : test.skip)('watch - file - rename file', done => { const toWatch = URI.file(join(testDir, 'index-watch1.html')); const toWatchRenamed = URI.file(join(testDir, 'index-watch1-renamed.html')); writeFileSync(toWatch.fsPath, 'Init'); @@ -1756,7 +1746,7 @@ suite('Disk File Service', () => { setTimeout(() => renameSync(toWatch.fsPath, toWatchRenamed.fsPath), 50); }); - test('watch - file - rename file (different case)', done => { + (runWatchTests ? test : test.skip)('watch - file - rename file (different case)', done => { const toWatch = URI.file(join(testDir, 'index-watch1.html')); const toWatchRenamed = URI.file(join(testDir, 'INDEX-watch1.html')); writeFileSync(toWatch.fsPath, 'Init'); @@ -1770,7 +1760,7 @@ suite('Disk File Service', () => { setTimeout(() => renameSync(toWatch.fsPath, toWatchRenamed.fsPath), 50); }); - test('watch - file (atomic save)', function (done) { + (runWatchTests ? test : test.skip)('watch - file (atomic save)', function (done) { const toWatch = URI.file(join(testDir, 'index-watch2.html')); writeFileSync(toWatch.fsPath, 'Init'); @@ -1786,11 +1776,7 @@ suite('Disk File Service', () => { }, 50); }); - test('watch - folder (non recursive) - change file', done => { - if (!isLinux) { - return done(); // watch tests are flaky on other platforms - } - + (runWatchTests ? test : test.skip)('watch - folder (non recursive) - change file', done => { const watchDir = URI.file(join(testDir, 'watch3')); mkdirSync(watchDir.fsPath); @@ -1802,11 +1788,7 @@ suite('Disk File Service', () => { setTimeout(() => writeFileSync(file.fsPath, 'Changes'), 50); }); - test('watch - folder (non recursive) - add file', done => { - if (!isLinux) { - return done(); // watch tests are flaky on other platforms - } - + (runWatchTests ? test : test.skip)('watch - folder (non recursive) - add file', done => { const watchDir = URI.file(join(testDir, 'watch4')); mkdirSync(watchDir.fsPath); @@ -1817,11 +1799,7 @@ suite('Disk File Service', () => { setTimeout(() => writeFileSync(file.fsPath, 'Changes'), 50); }); - test('watch - folder (non recursive) - delete file', done => { - if (!isLinux) { - return done(); // watch tests are flaky on other platforms - } - + (runWatchTests ? test : test.skip)('watch - folder (non recursive) - delete file', done => { const watchDir = URI.file(join(testDir, 'watch5')); mkdirSync(watchDir.fsPath); @@ -1833,11 +1811,7 @@ suite('Disk File Service', () => { setTimeout(() => unlinkSync(file.fsPath), 50); }); - test('watch - folder (non recursive) - add folder', done => { - if (!isLinux) { - return done(); // watch tests are flaky on other platforms - } - + (runWatchTests ? test : test.skip)('watch - folder (non recursive) - add folder', done => { const watchDir = URI.file(join(testDir, 'watch6')); mkdirSync(watchDir.fsPath); @@ -1848,11 +1822,7 @@ suite('Disk File Service', () => { setTimeout(() => mkdirSync(folder.fsPath), 50); }); - test('watch - folder (non recursive) - delete folder', done => { - if (!isLinux) { - return done(); // watch tests are flaky on other platforms - } - + (runWatchTests ? test : test.skip)('watch - folder (non recursive) - delete folder', done => { const watchDir = URI.file(join(testDir, 'watch7')); mkdirSync(watchDir.fsPath); @@ -1864,11 +1834,7 @@ suite('Disk File Service', () => { setTimeout(() => rimrafSync(folder.fsPath), 50); }); - test('watch - folder (non recursive) - symbolic link - change file', async done => { - if (!isLinux) { - return done(); // watch tests are flaky on other platforms - } - + (runWatchTests && !isWindows /* symbolic links not reliable on windows */ ? test : test.skip)('watch - folder (non recursive) - symbolic link - change file', async done => { const watchDir = URI.file(join(testDir, 'deep-link')); await symlink(join(testDir, 'deep'), watchDir.fsPath); @@ -1880,11 +1846,7 @@ suite('Disk File Service', () => { setTimeout(() => writeFileSync(file.fsPath, 'Changes'), 50); }); - test('watch - folder (non recursive) - rename file', done => { - if (!isLinux) { - return done(); // watch tests are flaky on other platforms - } - + (runWatchTests ? test : test.skip)('watch - folder (non recursive) - rename file', done => { const watchDir = URI.file(join(testDir, 'watch8')); mkdirSync(watchDir.fsPath); @@ -1898,11 +1860,7 @@ suite('Disk File Service', () => { setTimeout(() => renameSync(file.fsPath, fileRenamed.fsPath), 50); }); - test('watch - folder (non recursive) - rename file (different case)', done => { - if (!isLinux) { - return done(); // watch tests are flaky on other platforms - } - + (runWatchTests && isLinux /* this test requires a case sensitive file system */ ? test : test.skip)('watch - folder (non recursive) - rename file (different case)', done => { const watchDir = URI.file(join(testDir, 'watch8')); mkdirSync(watchDir.fsPath); diff --git a/src/vs/platform/product/browser/productService.ts b/src/vs/platform/product/browser/productService.ts index e65407170d9..d40b86aa0d2 100644 --- a/src/vs/platform/product/browser/productService.ts +++ b/src/vs/platform/product/browser/productService.ts @@ -38,4 +38,10 @@ export class ProductService implements IProductService { get settingsSearchBuildId(): number | undefined { return this.productConfiguration ? this.productConfiguration.settingsSearchBuildId : undefined; } get settingsSearchUrl(): string | undefined { return this.productConfiguration ? this.productConfiguration.settingsSearchUrl : undefined; } + + get experimentsUrl(): string | undefined { return this.productConfiguration ? this.productConfiguration.experimentsUrl : undefined; } + + get extensionKeywords(): { [extension: string]: readonly string[]; } | undefined { return this.productConfiguration ? this.productConfiguration.extensionKeywords : undefined; } + + get extensionAllowedBadgeProviders(): readonly string[] | undefined { return this.productConfiguration ? this.productConfiguration.extensionAllowedBadgeProviders : undefined; } } \ No newline at end of file diff --git a/src/vs/platform/product/common/product.ts b/src/vs/platform/product/common/product.ts index c56b004a9c7..63ea4836512 100644 --- a/src/vs/platform/product/common/product.ts +++ b/src/vs/platform/product/common/product.ts @@ -33,6 +33,10 @@ export interface IProductService { readonly settingsSearchBuildId?: number; readonly settingsSearchUrl?: string; + + readonly experimentsUrl?: string; + readonly extensionKeywords?: { [extension: string]: readonly string[]; }; + readonly extensionAllowedBadgeProviders?: readonly string[]; } export interface IProductConfiguration { diff --git a/src/vs/platform/product/node/productService.ts b/src/vs/platform/product/node/productService.ts index bc3b42172f7..4b98ff65d0f 100644 --- a/src/vs/platform/product/node/productService.ts +++ b/src/vs/platform/product/node/productService.ts @@ -33,4 +33,10 @@ export class ProductService implements IProductService { get settingsSearchBuildId(): number | undefined { return product.settingsSearchBuildId; } get settingsSearchUrl(): string | undefined { return product.settingsSearchUrl; } + + get experimentsUrl(): string | undefined { return product.experimentsUrl; } + + get extensionKeywords(): { [extension: string]: readonly string[]; } | undefined { return product.extensionKeywords; } + + get extensionAllowedBadgeProviders(): readonly string[] | undefined { return product.extensionAllowedBadgeProviders; } } \ No newline at end of file diff --git a/src/vs/platform/request/common/request.ts b/src/vs/platform/request/common/request.ts index acb9e553824..ed6c2611166 100644 --- a/src/vs/platform/request/common/request.ts +++ b/src/vs/platform/request/common/request.ts @@ -12,22 +12,24 @@ import { VSBufferReadableStream, streamToBuffer } from 'vs/base/common/buffer'; export const IRequestService = createDecorator('requestService'); +export interface IHeaders { + [header: string]: string; +} + export interface IRequestOptions { type?: string; url?: string; user?: string; password?: string; - headers?: any; + headers?: IHeaders; timeout?: number; data?: string; followRedirects?: number; } export interface IRequestContext { - // req: http.ClientRequest; - // res: http.ClientResponse; res: { - headers: { [n: string]: string }; + headers: IHeaders; statusCode?: number; }; stream: VSBufferReadableStream; diff --git a/src/vs/platform/request/common/requestIpc.ts b/src/vs/platform/request/common/requestIpc.ts new file mode 100644 index 00000000000..8f553261707 --- /dev/null +++ b/src/vs/platform/request/common/requestIpc.ts @@ -0,0 +1,51 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IChannel, IServerChannel } from 'vs/base/parts/ipc/common/ipc'; +import { Event } from 'vs/base/common/event'; +import { IRequestService, IRequestOptions, IRequestContext, IHeaders } from 'vs/platform/request/common/request'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { VSBuffer, bufferToStream, streamToBuffer } from 'vs/base/common/buffer'; + +type RequestResponse = [ + { + headers: IHeaders; + statusCode?: number; + }, + VSBuffer +]; + +export class RequestChannel implements IServerChannel { + + constructor(private readonly service: IRequestService) { } + + listen(context: any, event: string): Event { + throw new Error('Invalid listen'); + } + + call(context: any, command: string, args?: any): Promise { + switch (command) { + case 'request': return this.service.request(args[0], CancellationToken.None) + .then(async ({ res, stream }) => { + const buffer = await streamToBuffer(stream); + return [{ statusCode: res.statusCode, headers: res.headers }, buffer]; + }); + } + throw new Error('Invalid call'); + } +} + +export class RequestChannelClient { + + _serviceBrand: any; + + constructor(private readonly channel: IChannel) { } + + async request(options: IRequestOptions, token: CancellationToken): Promise { + const [res, buffer] = await this.channel.call('request', [options]); + return { res, stream: bufferToStream(buffer) }; + } + +} diff --git a/src/vs/platform/storage/node/storageIpc.ts b/src/vs/platform/storage/node/storageIpc.ts index c60779b7bad..d317e31a55b 100644 --- a/src/vs/platform/storage/node/storageIpc.ts +++ b/src/vs/platform/storage/node/storageIpc.ts @@ -12,7 +12,7 @@ import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle'; import { onUnexpectedError } from 'vs/base/common/errors'; import { ILogService } from 'vs/platform/log/common/log'; import { generateUuid } from 'vs/base/common/uuid'; -import { instanceStorageKey, firstSessionDateStorageKey, lastSessionDateStorageKey, currentSessionDateStorageKey } from 'vs/platform/telemetry/node/workbenchCommonProperties'; +import { instanceStorageKey, firstSessionDateStorageKey, lastSessionDateStorageKey, currentSessionDateStorageKey } from 'vs/platform/telemetry/common/telemetry'; type Key = string; type Value = string; diff --git a/src/vs/platform/telemetry/common/telemetry.ts b/src/vs/platform/telemetry/common/telemetry.ts index e82693979be..847f4856a55 100644 --- a/src/vs/platform/telemetry/common/telemetry.ts +++ b/src/vs/platform/telemetry/common/telemetry.ts @@ -38,3 +38,9 @@ export interface ITelemetryService { isOptedIn: boolean; } + +// Keys +export const instanceStorageKey = 'telemetry.instanceId'; +export const currentSessionDateStorageKey = 'telemetry.currentSessionDate'; +export const firstSessionDateStorageKey = 'telemetry.firstSessionDate'; +export const lastSessionDateStorageKey = 'telemetry.lastSessionDate'; \ No newline at end of file diff --git a/src/vs/platform/telemetry/common/telemetryService.ts b/src/vs/platform/telemetry/common/telemetryService.ts index 30fb12f5f79..2e7a4bb00d1 100644 --- a/src/vs/platform/telemetry/common/telemetryService.ts +++ b/src/vs/platform/telemetry/common/telemetryService.ts @@ -19,6 +19,7 @@ export interface ITelemetryServiceConfig { appender: ITelemetryAppender; commonProperties?: Promise<{ [name: string]: any }>; piiPaths?: string[]; + trueMachineId?: string; } export class TelemetryService implements ITelemetryService { @@ -74,6 +75,15 @@ export class TelemetryService implements ITelemetryService { } */ this.publicLog('machineIdFallback', { usingFallbackGuid: !isHashedId }); + + if (config.trueMachineId) { + /* __GDPR__ + "machineIdDisambiguation" : { + "correctedMachineId" : { "endPoint": "MacAddressHash", "classification": "EndUserPseudonymizedInformation", "purpose": "FeatureInsight" } + } + */ + this.publicLog('machineIdDisambiguation', { correctedMachineId: config.trueMachineId }); + } }); } } diff --git a/src/vs/platform/telemetry/node/workbenchCommonProperties.ts b/src/vs/platform/telemetry/node/workbenchCommonProperties.ts index d335c3d170b..d1b83a14146 100644 --- a/src/vs/platform/telemetry/node/workbenchCommonProperties.ts +++ b/src/vs/platform/telemetry/node/workbenchCommonProperties.ts @@ -5,11 +5,7 @@ import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { resolveCommonProperties } from 'vs/platform/telemetry/node/commonProperties'; - -export const instanceStorageKey = 'telemetry.instanceId'; -export const currentSessionDateStorageKey = 'telemetry.currentSessionDate'; -export const firstSessionDateStorageKey = 'telemetry.firstSessionDate'; -export const lastSessionDateStorageKey = 'telemetry.lastSessionDate'; +import { instanceStorageKey, firstSessionDateStorageKey, lastSessionDateStorageKey } from 'vs/platform/telemetry/common/telemetry'; export async function resolveWorkbenchCommonProperties(storageService: IStorageService, commit: string | undefined, version: string | undefined, machineId: string, installSourcePath: string, remoteAuthority?: string): Promise<{ [name: string]: string | undefined }> { const result = await resolveCommonProperties(commit, version, machineId, installSourcePath); diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 76122f4e69a..1c9fb3974c8 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -1084,8 +1084,11 @@ declare module 'vscode' { /** * Implement to handle when the terminal is ready to start firing events. + * + * @param initialDimensions The dimensions of the terminal, this will be undefined if the + * terminal panel has not been opened before this is called. */ - start?(): void; + start?(initialDimensions: TerminalDimensions | undefined): void; } //#endregion diff --git a/src/vs/workbench/api/browser/mainThreadCodeInsets.ts b/src/vs/workbench/api/browser/mainThreadCodeInsets.ts index e52a8969269..05cfa4cdc4c 100644 --- a/src/vs/workbench/api/browser/mainThreadCodeInsets.ts +++ b/src/vs/workbench/api/browser/mainThreadCodeInsets.ts @@ -88,7 +88,7 @@ export class MainThreadEditorInsets implements MainThreadEditorInsetsShape { const disposables = new DisposableStore(); - const webview = this._webviewService.createWebview({ + const webview = this._webviewService.createWebview('' + handle, { enableFindWidget: false, allowSvgs: false, extension: { id: extensionId, location: URI.revive(extensionLocation) } diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index 7883f70b7b6..bc8349ab47c 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; -import { ITerminalService, ITerminalInstance, IShellLaunchConfig, ITerminalProcessExtHostProxy, ITerminalProcessExtHostRequest, ITerminalDimensions, EXT_HOST_CREATION_DELAY, IAvailableShellsRequest, IDefaultShellAndArgsRequest } from 'vs/workbench/contrib/terminal/common/terminal'; -import { ExtHostContext, ExtHostTerminalServiceShape, MainThreadTerminalServiceShape, MainContext, IExtHostContext, ShellLaunchConfigDto, TerminalLaunchConfig } from 'vs/workbench/api/common/extHost.protocol'; +import { ITerminalService, ITerminalInstance, IShellLaunchConfig, ITerminalProcessExtHostProxy, ITerminalProcessExtHostRequest, ITerminalDimensions, EXT_HOST_CREATION_DELAY, IAvailableShellsRequest, IDefaultShellAndArgsRequest, ITerminalVirtualProcessRequest } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ExtHostContext, ExtHostTerminalServiceShape, MainThreadTerminalServiceShape, MainContext, IExtHostContext, ShellLaunchConfigDto, TerminalLaunchConfig, ITerminalDimensionsDto } from 'vs/workbench/api/common/extHost.protocol'; import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { URI } from 'vs/base/common/uri'; import { StopWatch } from 'vs/base/common/stopwatch'; @@ -48,7 +48,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape this._toDispose.add(_terminalService.onInstanceDimensionsChanged(instance => this._onInstanceDimensionsChanged(instance))); this._toDispose.add(_terminalService.onInstanceMaximumDimensionsChanged(instance => this._onInstanceMaximumDimensionsChanged(instance))); this._toDispose.add(_terminalService.onInstanceRequestExtHostProcess(request => this._onTerminalRequestExtHostProcess(request))); - this._toDispose.add(_terminalService.onInstanceRequestVirtualProcess(proxy => this._onTerminalRequestVirtualProcess(proxy))); + this._toDispose.add(_terminalService.onInstanceRequestVirtualProcess(e => this._onTerminalRequestVirtualProcess(e))); this._toDispose.add(_terminalService.onActiveInstanceChanged(instance => this._onActiveTerminalChanged(instance ? instance.id : null))); this._toDispose.add(_terminalService.onInstanceTitleChanged(instance => this._onTitleChanged(instance.id, instance.title))); this._toDispose.add(_terminalService.configHelper.onWorkspacePermissionsChanged(isAllowed => this._onWorkspacePermissionsChanged(isAllowed))); @@ -244,12 +244,13 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape return; } - const ready = this._terminalProcessesReady[request.proxy.terminalId]; + const proxy = request.proxy; + const ready = this._terminalProcessesReady[proxy.terminalId]; if (ready) { - ready(request.proxy); - delete this._terminalProcessesReady[request.proxy.terminalId]; + ready(proxy); + delete this._terminalProcessesReady[proxy.terminalId]; } else { - this._terminalProcesses[request.proxy.terminalId] = Promise.resolve(request.proxy); + this._terminalProcesses[proxy.terminalId] = Promise.resolve(proxy); } const shellLaunchConfigDto: ShellLaunchConfigDto = { name: request.shellLaunchConfig.name, @@ -258,16 +259,17 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape cwd: request.shellLaunchConfig.cwd, env: request.shellLaunchConfig.env }; - this._proxy.$createProcess(request.proxy.terminalId, shellLaunchConfigDto, request.activeWorkspaceRootUri, request.cols, request.rows, request.isWorkspaceShellAllowed); - request.proxy.onInput(data => this._proxy.$acceptProcessInput(request.proxy.terminalId, data)); - request.proxy.onResize(dimensions => this._proxy.$acceptProcessResize(request.proxy.terminalId, dimensions.cols, dimensions.rows)); - request.proxy.onShutdown(immediate => this._proxy.$acceptProcessShutdown(request.proxy.terminalId, immediate)); - request.proxy.onRequestCwd(() => this._proxy.$acceptProcessRequestCwd(request.proxy.terminalId)); - request.proxy.onRequestInitialCwd(() => this._proxy.$acceptProcessRequestInitialCwd(request.proxy.terminalId)); - request.proxy.onRequestLatency(() => this._onRequestLatency(request.proxy.terminalId)); + this._proxy.$createProcess(proxy.terminalId, shellLaunchConfigDto, request.activeWorkspaceRootUri, request.cols, request.rows, request.isWorkspaceShellAllowed); + proxy.onInput(data => this._proxy.$acceptProcessInput(proxy.terminalId, data)); + proxy.onResize(dimensions => this._proxy.$acceptProcessResize(proxy.terminalId, dimensions.cols, dimensions.rows)); + proxy.onShutdown(immediate => this._proxy.$acceptProcessShutdown(proxy.terminalId, immediate)); + proxy.onRequestCwd(() => this._proxy.$acceptProcessRequestCwd(proxy.terminalId)); + proxy.onRequestInitialCwd(() => this._proxy.$acceptProcessRequestInitialCwd(proxy.terminalId)); + proxy.onRequestLatency(() => this._onRequestLatency(proxy.terminalId)); } - private _onTerminalRequestVirtualProcess(proxy: ITerminalProcessExtHostProxy): void { + private _onTerminalRequestVirtualProcess(request: ITerminalVirtualProcessRequest): void { + const proxy = request.proxy; const ready = this._terminalProcessesReady[proxy.terminalId]; if (!ready) { this._terminalProcesses[proxy.terminalId] = Promise.resolve(proxy); @@ -278,6 +280,11 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape // Note that onReisze is not being listened to here as it needs to fire when max dimensions // change, excluding the dimension override + const initialDimensions: ITerminalDimensionsDto | undefined = request.cols && request.rows ? { + columns: request.cols, + rows: request.rows + } : undefined; + this._proxy.$startVirtualProcess(proxy.terminalId, initialDimensions); proxy.onInput(data => this._proxy.$acceptProcessInput(proxy.terminalId, data)); proxy.onShutdown(immediate => this._proxy.$acceptProcessShutdown(proxy.terminalId, immediate)); proxy.onRequestCwd(() => this._proxy.$acceptProcessRequestCwd(proxy.terminalId)); diff --git a/src/vs/workbench/api/browser/mainThreadWebview.ts b/src/vs/workbench/api/browser/mainThreadWebview.ts index e87a48fc9d9..d26b5440d47 100644 --- a/src/vs/workbench/api/browser/mainThreadWebview.ts +++ b/src/vs/workbench/api/browser/mainThreadWebview.ts @@ -93,7 +93,7 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews mainThreadShowOptions.group = viewColumnToEditorGroup(this._editorGroupService, showOptions.viewColumn); } - const webview = this._webviewEditorService.createWebview(this.getInternalWebviewId(viewType), title, mainThreadShowOptions, reviveWebviewOptions(options), { + const webview = this._webviewEditorService.createWebview(handle, this.getInternalWebviewViewType(viewType), title, mainThreadShowOptions, reviveWebviewOptions(options), { location: URI.revive(extensionLocation), id: extensionId }, this.createWebviewEventDelegate(handle)) as WebviewEditorInput; @@ -212,7 +212,7 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews this._revivers.delete(viewType); } - private getInternalWebviewId(viewType: string): string { + private getInternalWebviewViewType(viewType: string): string { return `mainThreadWebview-${viewType}`; } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 095d0cd4def..d64f50a9460 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -1135,6 +1135,11 @@ export interface IShellAndArgsDto { args: string[] | string | undefined; } +export interface ITerminalDimensionsDto { + columns: number; + rows: number; +} + export interface ExtHostTerminalServiceShape { $acceptTerminalClosed(id: number): void; $acceptTerminalOpened(id: number, name: string): void; @@ -1146,6 +1151,7 @@ export interface ExtHostTerminalServiceShape { $acceptTerminalDimensions(id: number, cols: number, rows: number): void; $acceptTerminalMaximumDimensions(id: number, cols: number, rows: number): void; $createProcess(id: number, shellLaunchConfig: ShellLaunchConfigDto, activeWorkspaceRootUri: UriComponents, cols: number, rows: number, isWorkspaceShellAllowed: boolean): void; + $startVirtualProcess(id: number, initialDimensions: ITerminalDimensionsDto | undefined): void; $acceptProcessInput(id: number, data: string): void; $acceptProcessResize(id: number, cols: number, rows: number): void; $acceptProcessShutdown(id: number, immediate: boolean): void; diff --git a/src/vs/workbench/api/common/extHostWebview.ts b/src/vs/workbench/api/common/extHostWebview.ts index cc83d789340..aaa6a49734c 100644 --- a/src/vs/workbench/api/common/extHostWebview.ts +++ b/src/vs/workbench/api/common/extHostWebview.ts @@ -40,7 +40,7 @@ export class ExtHostWebview implements vscode.Webview { } public get cspSource(): string { - return this._initData.webviewCspSource; + return this._initData.webviewCspSource.replace('{{uuid}}', this._handle); } public get html(): string { diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 92634a01bcd..87657c7e6f1 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -10,7 +10,7 @@ import { URI, UriComponents } from 'vs/base/common/uri'; import * as platform from 'vs/base/common/platform'; import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; import { Event, Emitter } from 'vs/base/common/event'; -import { ExtHostTerminalServiceShape, MainContext, MainThreadTerminalServiceShape, IMainContext, ShellLaunchConfigDto, IShellDefinitionDto, IShellAndArgsDto } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostTerminalServiceShape, MainContext, MainThreadTerminalServiceShape, IMainContext, ShellLaunchConfigDto, IShellDefinitionDto, IShellAndArgsDto, ITerminalDimensionsDto } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostConfiguration, ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration'; import { ILogService } from 'vs/platform/log/common/log'; import { EXT_HOST_CREATION_DELAY, IShellLaunchConfig, ITerminalEnvironment, ITerminalChildProcess, ITerminalDimensions } from 'vs/workbench/contrib/terminal/common/terminal'; @@ -329,10 +329,7 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { public createVirtualProcessTerminal(options: vscode.TerminalVirtualProcessOptions): vscode.Terminal { const terminal = new ExtHostTerminal(this._proxy, options.name); const p = new ExtHostVirtualProcess(options.virtualProcess); - terminal.createVirtualProcess().then(() => { - this._setupExtHostProcessListeners(terminal._id, p); - p.startSendingEvents(); - }); + terminal.createVirtualProcess().then(() => this._setupExtHostProcessListeners(terminal._id, p)); this._terminals.push(terminal); return terminal; } @@ -344,7 +341,6 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { } const p = new ExtHostVirtualProcess(virtualProcess); this._setupExtHostProcessListeners(id, p); - p.startSendingEvents(); } public createTerminalRenderer(name: string): vscode.TerminalRenderer { @@ -585,6 +581,10 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { this._setupExtHostProcessListeners(id, new TerminalProcess(shellLaunchConfig, initialCwd, cols, rows, env, enableConpty, this._logService)); } + public $startVirtualProcess(id: number, initialDimensions: ITerminalDimensionsDto | undefined): void { + (this._terminalProcesses[id] as ExtHostVirtualProcess).startSendingEvents(initialDimensions); + } + private _setupExtHostProcessListeners(id: number, p: ITerminalChildProcess): void { p.onProcessReady((e: { pid: number, cwd: string }) => this._proxy.$sendProcessReady(id, e.pid, e.cwd)); p.onProcessTitleChanged(title => this._proxy.$sendProcessTitle(id, title)); @@ -779,7 +779,7 @@ class ExtHostVirtualProcess implements ITerminalChildProcess { return Promise.resolve(0); } - startSendingEvents(): void { + startSendingEvents(initialDimensions: ITerminalDimensionsDto | undefined): void { // Flush all buffered events this._queuedEvents.forEach(e => (e.emitter.fire)(e.data)); this._queuedEvents = []; @@ -798,7 +798,7 @@ class ExtHostVirtualProcess implements ITerminalChildProcess { } if (this._virtualProcess.start) { - this._virtualProcess.start(); + this._virtualProcess.start(initialDimensions); } } } diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index 531ec2810d0..f7f28e50a1d 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -40,6 +40,9 @@ import { joinPath } from 'vs/base/common/resources'; import { BrowserStorageService } from 'vs/platform/storage/browser/storageService'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { getThemeTypeSelector, DARK, HIGH_CONTRAST, LIGHT } from 'vs/platform/theme/common/themeService'; +import { IRequestService } from 'vs/platform/request/common/request'; +import { RequestService } from 'vs/workbench/services/request/browser/requestService'; +import { InMemoryUserDataProvider } from 'vs/workbench/services/userData/common/inMemoryUserDataProvider'; class CodeRendererMain extends Disposable { @@ -155,12 +158,14 @@ class CodeRendererMain extends Disposable { } } - // User Data Provider - if (userDataProvider) { - fileService.registerProvider(Schemas.userData, userDataProvider); + if (!userDataProvider) { + userDataProvider = this._register(new InMemoryUserDataProvider()); } - const services = await Promise.all([ + // User Data Provider + fileService.registerProvider(Schemas.userData, userDataProvider); + + const [configurationService, storageService] = await Promise.all([ this.createWorkspaceService(payload, environmentService, fileService, remoteAgentService, logService).then(service => { // Workspace @@ -181,7 +186,10 @@ class CodeRendererMain extends Disposable { }) ]); - return { serviceCollection, logService, storageService: services[1] }; + // Request Service + serviceCollection.set(IRequestService, new RequestService(this.configuration.requestHandler, remoteAgentService, configurationService, logService)); + + return { serviceCollection, logService, storageService }; } private async createStorageService(payload: IWorkspaceInitializationPayload, environmentService: IWorkbenchEnvironmentService, fileService: IFileService, logService: ILogService): Promise { diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index 4f92412aea2..3384986b4ad 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -11,9 +11,8 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation' // tslint:disable-next-line: import-patterns no-standalone-editor import { IDownloadService } from 'vs/platform/download/common/download'; import { CancellationToken } from 'vs/base/common/cancellation'; -import { IExtensionGalleryService, IQueryOptions, IGalleryExtension, InstallOperation, StatisticType, ITranslation, IGalleryExtensionVersion, IExtensionIdentifier, IReportedExtension, IExtensionManagementService, ILocalExtension, IGalleryMetadata, IExtensionTipsService, ExtensionRecommendationReason, IExtensionRecommendation, IExtensionEnablementService, EnablementState } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { IPager } from 'vs/base/common/paging'; -import { IExtensionManifest, ExtensionType, ExtensionIdentifier, IExtension } from 'vs/platform/extensions/common/extensions'; +import { IGalleryExtension, IExtensionIdentifier, IReportedExtension, IExtensionManagementService, ILocalExtension, IGalleryMetadata, IExtensionTipsService, ExtensionRecommendationReason, IExtensionRecommendation, IExtensionEnablementService, EnablementState } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { ExtensionType, ExtensionIdentifier, IExtension } from 'vs/platform/extensions/common/extensions'; import { IURLHandler, IURLService } from 'vs/platform/url/common/url'; import { ITelemetryService, ITelemetryData, ITelemetryInfo } from 'vs/platform/telemetry/common/telemetry'; import { ConsoleLogService, ILogService } from 'vs/platform/log/common/log'; @@ -29,7 +28,6 @@ import { ITunnelService } from 'vs/platform/remote/common/tunnel'; import { IReloadSessionEvent, IExtensionHostDebugService, ICloseSessionEvent, IAttachSessionEvent, ILogToSessionEvent, ITerminateSessionEvent } from 'vs/workbench/services/extensions/common/extensionHostDebug'; import { IRemoteConsoleLog } from 'vs/base/common/console'; // tslint:disable-next-line: import-patterns -// tslint:disable-next-line: import-patterns import { IExtensionsWorkbenchService, IExtension as IExtension2 } from 'vs/workbench/contrib/extensions/common/extensions'; import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { addDisposableListener, EventType } from 'vs/base/browser/dom'; @@ -41,6 +39,8 @@ import { ParsedArgs } from 'vs/platform/environment/common/environment'; import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings'; import { IProcessEnvironment } from 'vs/base/common/platform'; import { toStoreData, restoreRecentlyOpened } from 'vs/platform/history/common/historyStorage'; +// tslint:disable-next-line: import-patterns +import { IExperimentService, IExperiment, ExperimentActionType, ExperimentState } from 'vs/workbench/contrib/experiments/common/experimentService'; //#region Download @@ -58,74 +58,6 @@ registerSingleton(IDownloadService, SimpleDownloadService, true); //#endregion -//#region Extension Gallery - -export class SimpleExtensionGalleryService implements IExtensionGalleryService { - - _serviceBrand: any; - - isEnabled(): boolean { - return false; - } - - query(token: CancellationToken): Promise>; - query(options: IQueryOptions, token: CancellationToken): Promise>; - query(arg1: any, arg2?: any): Promise> { - // @ts-ignore - return Promise.resolve(undefined); - } - - download(extension: IGalleryExtension, operation: InstallOperation): Promise { - // @ts-ignore - return Promise.resolve(undefined); - } - - reportStatistic(publisher: string, name: string, version: string, type: StatisticType): Promise { - return Promise.resolve(undefined); - } - - getReadme(extension: IGalleryExtension, token: CancellationToken): Promise { - // @ts-ignore - return Promise.resolve(undefined); - } - - getManifest(extension: IGalleryExtension, token: CancellationToken): Promise { - // @ts-ignore - return Promise.resolve(undefined); - } - - getChangelog(extension: IGalleryExtension, token: CancellationToken): Promise { - // @ts-ignore - return Promise.resolve(undefined); - } - - getCoreTranslation(extension: IGalleryExtension, languageId: string): Promise { - // @ts-ignore - return Promise.resolve(undefined); - } - - getAllVersions(extension: IGalleryExtension, compatible: boolean): Promise { - // @ts-ignore - return Promise.resolve(undefined); - } - - getExtensionsReport(): Promise { - // @ts-ignore - return Promise.resolve(undefined); - } - - // @ts-ignore - getCompatibleExtension(extension: IGalleryExtension): Promise; - getCompatibleExtension(id: IExtensionIdentifier, version?: string): Promise; - getCompatibleExtension(id: any, version?: any) { - return Promise.resolve(undefined); - } -} - -registerSingleton(IExtensionGalleryService, SimpleExtensionGalleryService, true); - -//#endregion - //#endregion IExtensionsWorkbenchService export class SimpleExtensionsWorkbenchService implements IExtensionsWorkbenchService { _serviceBrand: any; @@ -1066,3 +998,34 @@ class SimpleTunnelService implements ITunnelService { registerSingleton(ITunnelService, SimpleTunnelService); //#endregion + +//#region experiments + +class ExperimentService implements IExperimentService { + _serviceBrand: any; + + async getExperimentById(id: string): Promise { + return { + enabled: false, + id: '', + state: ExperimentState.NoRun + }; + } + + async getExperimentsByType(type: ExperimentActionType): Promise { + return []; + } + + async getCuratedExtensionsList(curatedExtensionsKey: string): Promise { + return []; + } + + markAsCompleted(experimentId: string): void { } + + onExperimentEnabled: Event = Event.None; + +} + +registerSingleton(IExperimentService, ExperimentService); + +//#endregion diff --git a/src/vs/workbench/contrib/experiments/common/experimentService.ts b/src/vs/workbench/contrib/experiments/common/experimentService.ts new file mode 100644 index 00000000000..437afe18bd6 --- /dev/null +++ b/src/vs/workbench/contrib/experiments/common/experimentService.ts @@ -0,0 +1,59 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +import { Event } from 'vs/base/common/event'; + +export const enum ExperimentState { + Evaluating, + NoRun, + Run, + Complete +} + +export interface IExperimentAction { + type: ExperimentActionType; + properties: any; +} + +export enum ExperimentActionType { + Custom = 'Custom', + Prompt = 'Prompt', + AddToRecommendations = 'AddToRecommendations', + ExtensionSearchResults = 'ExtensionSearchResults' +} + +export type LocalizedPromptText = { [locale: string]: string; }; + +export interface IExperimentActionPromptProperties { + promptText: string | LocalizedPromptText; + commands: IExperimentActionPromptCommand[]; +} + +export interface IExperimentActionPromptCommand { + text: string | { [key: string]: string }; + externalLink?: string; + curatedExtensionsKey?: string; + curatedExtensionsList?: string[]; +} + +export interface IExperiment { + id: string; + enabled: boolean; + state: ExperimentState; + action?: IExperimentAction; +} + +export interface IExperimentService { + _serviceBrand: any; + getExperimentById(id: string): Promise; + getExperimentsByType(type: ExperimentActionType): Promise; + getCuratedExtensionsList(curatedExtensionsKey: string): Promise; + markAsCompleted(experimentId: string): void; + + onExperimentEnabled: Event; +} + +export const IExperimentService = createDecorator('experimentService'); \ No newline at end of file diff --git a/src/vs/workbench/contrib/experiments/electron-browser/experimentService.ts b/src/vs/workbench/contrib/experiments/electron-browser/experimentService.ts index 22f39699416..ada56e8df4d 100644 --- a/src/vs/workbench/contrib/experiments/electron-browser/experimentService.ts +++ b/src/vs/workbench/contrib/experiments/electron-browser/experimentService.ts @@ -3,12 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import product from 'vs/platform/product/node/product'; - -import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { ITelemetryService, lastSessionDateStorageKey } 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'; @@ -21,8 +18,9 @@ import { ITextFileService, StateChange } from 'vs/workbench/services/textfile/co import { WorkspaceStats } from 'vs/workbench/contrib/stats/electron-browser/workspaceStats'; import { CancellationToken } from 'vs/base/common/cancellation'; import { distinct } from 'vs/base/common/arrays'; -import { lastSessionDateStorageKey } from 'vs/platform/telemetry/node/workbenchCommonProperties'; import { ExtensionType } from 'vs/platform/extensions/common/extensions'; +import { ExperimentState, IExperimentAction, IExperimentService, IExperiment, ExperimentActionType, IExperimentActionPromptProperties } from 'vs/workbench/contrib/experiments/common/experimentService'; +import { IProductService } from 'vs/platform/product/common/product'; interface IExperimentStorageState { enabled: boolean; @@ -31,13 +29,6 @@ interface IExperimentStorageState { lastEditedDate?: string; } -export const enum ExperimentState { - Evaluating, - NoRun, - Run, - Complete -} - interface IRawExperiment { id: string; enabled?: boolean; @@ -64,51 +55,6 @@ interface IRawExperiment { action?: IExperimentAction; } -interface IExperimentAction { - type: ExperimentActionType; - properties: any; -} - -export enum ExperimentActionType { - Custom = 'Custom', - Prompt = 'Prompt', - AddToRecommendations = 'AddToRecommendations', - ExtensionSearchResults = 'ExtensionSearchResults' -} - -export type LocalizedPromptText = { [locale: string]: string; }; - -export interface IExperimentActionPromptProperties { - promptText: string | LocalizedPromptText; - commands: IExperimentActionPromptCommand[]; -} - -export interface IExperimentActionPromptCommand { - text: string | { [key: string]: string }; - externalLink?: string; - curatedExtensionsKey?: string; - curatedExtensionsList?: string[]; -} - -export interface IExperiment { - id: string; - enabled: boolean; - state: ExperimentState; - action?: IExperimentAction; -} - -export interface IExperimentService { - _serviceBrand: any; - getExperimentById(id: string): Promise; - getExperimentsByType(type: ExperimentActionType): Promise; - getCuratedExtensionsList(curatedExtensionsKey: string): Promise; - markAsCompleted(experimentId: string): void; - - onExperimentEnabled: Event; -} - -export const IExperimentService = createDecorator('experimentService'); - export class ExperimentService extends Disposable implements IExperimentService { _serviceBrand: any; private _experiments: IExperiment[] = []; @@ -127,7 +73,8 @@ export class ExperimentService extends Disposable implements IExperimentService @ITelemetryService private readonly telemetryService: ITelemetryService, @ILifecycleService private readonly lifecycleService: ILifecycleService, @IRequestService private readonly requestService: IRequestService, - @IConfigurationService private readonly configurationService: IConfigurationService + @IConfigurationService private readonly configurationService: IConfigurationService, + @IProductService private readonly productService: IProductService ) { super(); @@ -171,10 +118,10 @@ export class ExperimentService extends Disposable implements IExperimentService } protected getExperiments(): Promise { - if (!product.experimentsUrl || this.configurationService.getValue('workbench.enableExperiments') === false) { + if (!this.productService.experimentsUrl || this.configurationService.getValue('workbench.enableExperiments') === false) { return Promise.resolve([]); } - return this.requestService.request({ type: 'GET', url: product.experimentsUrl }, CancellationToken.None).then(context => { + return this.requestService.request({ type: 'GET', url: this.productService.experimentsUrl }, CancellationToken.None).then(context => { if (context.res.statusCode !== 200) { return Promise.resolve(null); } diff --git a/src/vs/workbench/contrib/experiments/electron-browser/experimentalPrompt.ts b/src/vs/workbench/contrib/experiments/electron-browser/experimentalPrompt.ts index 3581351f6e0..97f55700a40 100644 --- a/src/vs/workbench/contrib/experiments/electron-browser/experimentalPrompt.ts +++ b/src/vs/workbench/contrib/experiments/electron-browser/experimentalPrompt.ts @@ -5,7 +5,7 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { INotificationService, Severity, IPromptChoice } from 'vs/platform/notification/common/notification'; -import { IExperimentService, IExperiment, ExperimentActionType, IExperimentActionPromptProperties, IExperimentActionPromptCommand, ExperimentState } from 'vs/workbench/contrib/experiments/electron-browser/experimentService'; +import { IExperimentService, IExperiment, ExperimentActionType, IExperimentActionPromptProperties, IExperimentActionPromptCommand, ExperimentState } from 'vs/workbench/contrib/experiments/common/experimentService'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IExtensionsViewlet } from 'vs/workbench/contrib/extensions/common/extensions'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; diff --git a/src/vs/workbench/contrib/experiments/electron-browser/experiments.contribution.ts b/src/vs/workbench/contrib/experiments/electron-browser/experiments.contribution.ts index f3dcaf5074e..ca28e9b6f67 100644 --- a/src/vs/workbench/contrib/experiments/electron-browser/experiments.contribution.ts +++ b/src/vs/workbench/contrib/experiments/electron-browser/experiments.contribution.ts @@ -4,7 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { IExperimentService, ExperimentService } from 'vs/workbench/contrib/experiments/electron-browser/experimentService'; +import { IExperimentService } from 'vs/workbench/contrib/experiments/common/experimentService'; +import { ExperimentService } from 'vs/workbench/contrib/experiments/electron-browser/experimentService'; import { Registry } from 'vs/platform/registry/common/platform'; import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; diff --git a/src/vs/workbench/contrib/experiments/test/electron-browser/experimentService.test.ts b/src/vs/workbench/contrib/experiments/test/electron-browser/experimentService.test.ts index d98057ee111..fdea7523dbb 100644 --- a/src/vs/workbench/contrib/experiments/test/electron-browser/experimentService.test.ts +++ b/src/vs/workbench/contrib/experiments/test/electron-browser/experimentService.test.ts @@ -4,7 +4,8 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { ExperimentService, ExperimentActionType, ExperimentState, IExperiment } from 'vs/workbench/contrib/experiments/electron-browser/experimentService'; +import { ExperimentActionType, ExperimentState, IExperiment } from 'vs/workbench/contrib/experiments/common/experimentService'; +import { ExperimentService } from 'vs/workbench/contrib/experiments/electron-browser/experimentService'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { TestLifecycleService } from 'vs/workbench/test/workbenchTestServices'; @@ -17,7 +18,7 @@ import { Emitter } from 'vs/base/common/event'; import { TestExtensionEnablementService } from 'vs/workbench/services/extensionManagement/test/electron-browser/extensionEnablementService.test'; import { URLService } from 'vs/platform/url/common/urlService'; import { IURLService } from 'vs/platform/url/common/url'; -import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { ITelemetryService, lastSessionDateStorageKey } from 'vs/platform/telemetry/common/telemetry'; import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; @@ -25,7 +26,6 @@ import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { assign } from 'vs/base/common/objects'; import { URI } from 'vs/base/common/uri'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; -import { lastSessionDateStorageKey } from 'vs/platform/telemetry/node/workbenchCommonProperties'; import { getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { ExtensionType } from 'vs/platform/extensions/common/extensions'; diff --git a/src/vs/workbench/contrib/experiments/test/electron-browser/experimentalPrompts.test.ts b/src/vs/workbench/contrib/experiments/test/electron-browser/experimentalPrompts.test.ts index ec566e9c57a..781fc5ab7c0 100644 --- a/src/vs/workbench/contrib/experiments/test/electron-browser/experimentalPrompts.test.ts +++ b/src/vs/workbench/contrib/experiments/test/electron-browser/experimentalPrompts.test.ts @@ -13,7 +13,7 @@ import { IStorageService, StorageScope } from 'vs/platform/storage/common/storag import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; import { ExperimentalPrompts } from 'vs/workbench/contrib/experiments/electron-browser/experimentalPrompt'; -import { ExperimentActionType, ExperimentState, IExperiment, IExperimentActionPromptProperties, IExperimentService, LocalizedPromptText } from 'vs/workbench/contrib/experiments/electron-browser/experimentService'; +import { ExperimentActionType, ExperimentState, IExperiment, IExperimentActionPromptProperties, IExperimentService, LocalizedPromptText } from 'vs/workbench/contrib/experiments/common/experimentService'; import { TestExperimentService } from 'vs/workbench/contrib/experiments/test/electron-browser/experimentService.test'; import { TestLifecycleService } from 'vs/workbench/test/workbenchTestServices'; diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionEditor.ts b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts similarity index 98% rename from src/vs/workbench/contrib/extensions/electron-browser/extensionEditor.ts rename to src/vs/workbench/contrib/extensions/browser/extensionEditor.ts index 08929e250d5..2ab1851bda6 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionEditor.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionEditor.ts @@ -25,11 +25,10 @@ import { IExtensionManifest, IKeyBinding, IView, IViewContainer, ExtensionType } import { ResolvedKeybinding, KeyMod, KeyCode } from 'vs/base/common/keyCodes'; import { ExtensionsInput } from 'vs/workbench/contrib/extensions/common/extensionsInput'; import { IExtensionsWorkbenchService, IExtensionsViewlet, VIEWLET_ID, IExtension, ExtensionContainers } from 'vs/workbench/contrib/extensions/common/extensions'; -import { RatingsWidget, InstallCountWidget, RemoteBadgeWidget } from 'vs/workbench/contrib/extensions/electron-browser/extensionsWidgets'; +import { RatingsWidget, InstallCountWidget, RemoteBadgeWidget } from 'vs/workbench/contrib/extensions/browser/extensionsWidgets'; import { EditorOptions } from 'vs/workbench/common/editor'; import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; -import { CombinedInstallAction, UpdateAction, ExtensionEditorDropDownAction, ReloadAction, MaliciousStatusLabelAction, IgnoreExtensionRecommendationAction, UndoIgnoreExtensionRecommendationAction, EnableDropDownAction, DisableDropDownAction, StatusLabelAction, SetFileIconThemeAction, SetColorThemeAction, RemoteInstallAction, DisabledLabelAction, SystemDisabledWarningAction, LocalInstallAction } from 'vs/workbench/contrib/extensions/electron-browser/extensionsActions'; -import { WebviewElement } from 'vs/workbench/contrib/webview/electron-browser/webviewElement'; +import { CombinedInstallAction, UpdateAction, ExtensionEditorDropDownAction, ReloadAction, MaliciousStatusLabelAction, IgnoreExtensionRecommendationAction, UndoIgnoreExtensionRecommendationAction, EnableDropDownAction, DisableDropDownAction, StatusLabelAction, SetFileIconThemeAction, SetColorThemeAction, RemoteInstallAction, DisabledLabelAction, SystemDisabledWarningAction, LocalInstallAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement'; import { IOpenerService } from 'vs/platform/opener/common/opener'; @@ -44,7 +43,7 @@ import { assign } from 'vs/base/common/objects'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { CancellationToken } from 'vs/base/common/cancellation'; import { ExtensionsTree, ExtensionData } from 'vs/workbench/contrib/extensions/browser/extensionsViewer'; -import { ShowCurrentReleaseNotesAction } from 'vs/workbench/contrib/update/electron-browser/update'; +import { ShowCurrentReleaseNotesActionId } from 'vs/workbench/contrib/update/common/update'; import { KeybindingParser } from 'vs/base/common/keybindingParser'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; @@ -52,6 +51,7 @@ import { getDefaultValue } from 'vs/platform/configuration/common/configurationR import { isUndefined } from 'vs/base/common/types'; import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { URI } from 'vs/base/common/uri'; +import { IWebviewService, Webview } from 'vs/workbench/contrib/webview/common/webview'; function renderBody(body: string): string { const styleSheetPath = require.toUrl('./media/markdown.css').replace('file://', 'vscode-resource://'); @@ -194,8 +194,8 @@ export class ExtensionEditor extends BaseEditor { @IExtensionTipsService private readonly extensionTipsService: IExtensionTipsService, @IStorageService storageService: IStorageService, @IExtensionService private readonly extensionService: IExtensionService, - @IWorkbenchThemeService private readonly workbenchThemeService: IWorkbenchThemeService - + @IWorkbenchThemeService private readonly workbenchThemeService: IWorkbenchThemeService, + @IWebviewService private readonly webviewService: IWebviewService ) { super(ExtensionEditor.ID, telemetryService, themeService, storageService); this.extensionReadme = null; @@ -490,8 +490,8 @@ export class ExtensionEditor extends BaseEditor { } showFind(): void { - if (this.activeElement instanceof WebviewElement) { - this.activeElement.showFind(); + if (this.activeElement && (this.activeElement).showFind) { + (this.activeElement).showFind(); } } @@ -537,7 +537,7 @@ export class ExtensionEditor extends BaseEditor { .then(renderBody) .then(removeEmbeddedSVGs) .then(body => { - const webviewElement = this.instantiationService.createInstance(WebviewElement, + const webviewElement = this.webviewService.createWebview('extensionEditor', { enableFindWidget: true, }, @@ -558,7 +558,7 @@ export class ExtensionEditor extends BaseEditor { return; } // Whitelist supported schemes for links - if (['http', 'https', 'mailto'].indexOf(link.scheme) >= 0 || (link.scheme === 'command' && link.path === ShowCurrentReleaseNotesAction.ID)) { + if (['http', 'https', 'mailto'].indexOf(link.scheme) >= 0 || (link.scheme === 'command' && link.path === ShowCurrentReleaseNotesActionId)) { this.openerService.open(link); } }, null, this.contentDisposables)); diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/extensionsActions.ts rename to src/vs/workbench/contrib/extensions/browser/extensionsActions.ts diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionsDependencyChecker.ts b/src/vs/workbench/contrib/extensions/browser/extensionsDependencyChecker.ts similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/extensionsDependencyChecker.ts rename to src/vs/workbench/contrib/extensions/browser/extensionsDependencyChecker.ts diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionsList.ts b/src/vs/workbench/contrib/extensions/browser/extensionsList.ts similarity index 98% rename from src/vs/workbench/contrib/extensions/electron-browser/extensionsList.ts rename to src/vs/workbench/contrib/extensions/browser/extensionsList.ts index 78fca332fc1..0946dc134d9 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionsList.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsList.ts @@ -13,9 +13,9 @@ import { IPagedRenderer } from 'vs/base/browser/ui/list/listPaging'; import { Event } from 'vs/base/common/event'; import { domEvent } from 'vs/base/browser/event'; import { IExtension, ExtensionContainers, ExtensionState, IExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/common/extensions'; -import { InstallAction, UpdateAction, ManageExtensionAction, ReloadAction, MaliciousStatusLabelAction, ExtensionActionViewItem, StatusLabelAction, RemoteInstallAction, SystemDisabledWarningAction, DisabledLabelAction, LocalInstallAction } from 'vs/workbench/contrib/extensions/electron-browser/extensionsActions'; +import { InstallAction, UpdateAction, ManageExtensionAction, ReloadAction, MaliciousStatusLabelAction, ExtensionActionViewItem, StatusLabelAction, RemoteInstallAction, SystemDisabledWarningAction, DisabledLabelAction, LocalInstallAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; -import { Label, RatingsWidget, InstallCountWidget, RecommendationWidget, RemoteBadgeWidget, TooltipWidget } from 'vs/workbench/contrib/extensions/electron-browser/extensionsWidgets'; +import { Label, RatingsWidget, InstallCountWidget, RecommendationWidget, RemoteBadgeWidget, TooltipWidget } from 'vs/workbench/contrib/extensions/browser/extensionsWidgets'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IExtensionManagementServerService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { INotificationService } from 'vs/platform/notification/common/notification'; diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts similarity index 95% rename from src/vs/workbench/contrib/extensions/electron-browser/extensionsViewlet.ts rename to src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts index 3523014aa0b..bbfe3e75868 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.ts @@ -8,7 +8,7 @@ import { localize } from 'vs/nls'; import { timeout, Delayer } from 'vs/base/common/async'; import { isPromiseCanceledError } from 'vs/base/common/errors'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; import { Event as EventOf, Emitter } from 'vs/base/common/event'; import { IAction } from 'vs/base/common/actions'; import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; @@ -23,10 +23,10 @@ import { ShowEnabledExtensionsAction, ShowInstalledExtensionsAction, ShowRecommendedExtensionsAction, ShowPopularExtensionsAction, ShowDisabledExtensionsAction, ShowOutdatedExtensionsAction, ClearExtensionsInputAction, ChangeSortAction, UpdateAllAction, CheckForUpdatesAction, DisableAllAction, EnableAllAction, EnableAutoUpdateAction, DisableAutoUpdateAction, ShowBuiltInExtensionsAction, InstallVSIXAction -} from 'vs/workbench/contrib/extensions/electron-browser/extensionsActions'; +} from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import { IExtensionManagementService, IExtensionManagementServerService, IExtensionManagementServer, IExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { ExtensionsInput } from 'vs/workbench/contrib/extensions/common/extensionsInput'; -import { ExtensionsListView, EnabledExtensionsView, DisabledExtensionsView, RecommendedExtensionsView, WorkspaceRecommendedExtensionsView, BuiltInExtensionsView, BuiltInThemesExtensionsView, BuiltInBasicsExtensionsView, ServerExtensionsView, DefaultRecommendedExtensionsView } from './extensionsViews'; +import { ExtensionsListView, EnabledExtensionsView, DisabledExtensionsView, RecommendedExtensionsView, WorkspaceRecommendedExtensionsView, BuiltInExtensionsView, BuiltInThemesExtensionsView, BuiltInBasicsExtensionsView, ServerExtensionsView, DefaultRecommendedExtensionsView } from 'vs/workbench/contrib/extensions/browser/extensionsViews'; import { OpenGlobalSettingsAction } from 'vs/workbench/contrib/preferences/browser/preferencesActions'; import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; @@ -339,7 +339,6 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio private extensionsBox: HTMLElement; private primaryActions: IAction[]; private secondaryActions: IAction[] | null; - private disposables: IDisposable[] = []; private readonly searchViewletState: MementoObject; constructor( @@ -374,14 +373,14 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio this.recommendedExtensionsContextKey = RecommendedExtensionsContext.bindTo(contextKeyService); this.defaultRecommendedExtensionsContextKey = DefaultRecommendedExtensionsContext.bindTo(contextKeyService); this.defaultRecommendedExtensionsContextKey.set(!this.configurationService.getValue(ShowRecommendationsOnlyOnDemandKey)); - this.disposables.push(this.viewletService.onDidViewletOpen(this.onViewletOpen, this, this.disposables)); + this._register(this.viewletService.onDidViewletOpen(this.onViewletOpen, this)); this.searchViewletState = this.getMemento(StorageScope.WORKSPACE); this.extensionManagementService.getInstalled(ExtensionType.User).then(result => { this.hasInstalledExtensionsContextKey.set(result.length > 0); }); - this.configurationService.onDidChangeConfiguration(e => { + this._register(this.configurationService.onDidChangeConfiguration(e => { if (e.affectsConfiguration(AutoUpdateConfigurationKey)) { this.secondaryActions = null; this.updateTitleArea(); @@ -389,7 +388,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio if (e.affectedKeys.indexOf(ShowRecommendationsOnlyOnDemandKey) > -1) { this.defaultRecommendedExtensionsContextKey.set(!this.configurationService.getValue(ShowRecommendationsOnlyOnDemandKey)); } - }, this, this.disposables); + }, this)); } create(parent: HTMLElement): void { @@ -401,7 +400,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio const placeholder = localize('searchExtensions', "Search Extensions in Marketplace"); const searchValue = this.searchViewletState['query.value'] ? this.searchViewletState['query.value'] : ''; - this.searchBox = this.instantiationService.createInstance(SuggestEnabledInput, `${VIEWLET_ID}.searchbox`, header, { + this.searchBox = this._register(this.instantiationService.createInstance(SuggestEnabledInput, `${VIEWLET_ID}.searchbox`, header, { triggerCharacters: ['@'], sortKey: (item: string) => { if (item.indexOf(':') === -1) { return 'a'; } @@ -410,24 +409,22 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio else { return 'd'; } }, provideResults: (query: string) => Query.suggestions(query) - }, placeholder, 'extensions:searchinput', { placeholderText: placeholder, value: searchValue }); + }, placeholder, 'extensions:searchinput', { placeholderText: placeholder, value: searchValue })); if (this.searchBox.getValue()) { this.triggerSearch(); } - this.disposables.push(attachSuggestEnabledInputBoxStyler(this.searchBox, this.themeService)); - - this.disposables.push(this.searchBox); + this._register(attachSuggestEnabledInputBoxStyler(this.searchBox, this.themeService)); const _searchChange = new Emitter(); this.onSearchChange = _searchChange.event; - this.searchBox.onInputDidChange(() => { + this._register(this.searchBox.onInputDidChange(() => { this.triggerSearch(); _searchChange.fire(this.searchBox.getValue()); - }, this, this.disposables); + }, this)); - this.searchBox.onShouldFocusResults(() => this.focusListView(), this, this.disposables); + this._register(this.searchBox.onShouldFocusResults(() => this.focusListView(), this)); this._register(this.onDidChangeVisibility(visible => { if (visible) { @@ -614,52 +611,39 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio this.notificationService.error(err); } - - dispose(): void { - this.disposables = dispose(this.disposables); - super.dispose(); - } } -export class StatusUpdater implements IWorkbenchContribution { +export class StatusUpdater extends Disposable implements IWorkbenchContribution { - private disposables: IDisposable[]; - private badgeHandle: IDisposable; + private readonly badgeHandle = this._register(new MutableDisposable()); constructor( @IActivityService private readonly activityService: IActivityService, @IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService, @IExtensionEnablementService private readonly extensionEnablementService: IExtensionEnablementService ) { - extensionsWorkbenchService.onChange(this.onServiceChange, this, this.disposables); + super(); + this._register(extensionsWorkbenchService.onChange(this.onServiceChange, this)); } private onServiceChange(): void { - - dispose(this.badgeHandle); + this.badgeHandle.clear(); if (this.extensionsWorkbenchService.local.some(e => e.state === ExtensionState.Installing)) { - this.badgeHandle = this.activityService.showActivity(VIEWLET_ID, new ProgressBadge(() => localize('extensions', "Extensions")), 'extensions-badge progress-badge'); + this.badgeHandle.value = this.activityService.showActivity(VIEWLET_ID, new ProgressBadge(() => localize('extensions', "Extensions")), 'extensions-badge progress-badge'); return; } const outdated = this.extensionsWorkbenchService.outdated.reduce((r, e) => r + (this.extensionEnablementService.isEnabled(e.local!) ? 1 : 0), 0); if (outdated > 0) { const badge = new NumberBadge(outdated, n => localize('outdatedExtensions', '{0} Outdated Extensions', n)); - this.badgeHandle = this.activityService.showActivity(VIEWLET_ID, badge, 'extensions-badge count-badge'); + this.badgeHandle.value = this.activityService.showActivity(VIEWLET_ID, badge, 'extensions-badge count-badge'); } } - - dispose(): void { - this.disposables = dispose(this.disposables); - dispose(this.badgeHandle); - } } export class MaliciousExtensionChecker implements IWorkbenchContribution { - private disposables: IDisposable[]; - constructor( @IExtensionManagementService private readonly extensionsManagementService: IExtensionManagementService, @IWindowService private readonly windowService: IWindowService, @@ -704,8 +688,4 @@ export class MaliciousExtensionChecker implements IWorkbenchContribution { }).then(() => undefined); }, err => this.logService.error(err)); } - - dispose(): void { - this.disposables = dispose(this.disposables); - } } diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionsViews.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts similarity index 99% rename from src/vs/workbench/contrib/extensions/electron-browser/extensionsViews.ts rename to src/vs/workbench/contrib/extensions/browser/extensionsViews.ts index 1d0c1dcd7ae..4b160a91004 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionsViews.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts @@ -15,7 +15,7 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { append, $, toggleClass } from 'vs/base/browser/dom'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { Delegate, Renderer, IExtensionsViewState } from 'vs/workbench/contrib/extensions/electron-browser/extensionsList'; +import { Delegate, Renderer, IExtensionsViewState } from 'vs/workbench/contrib/extensions/browser/extensionsList'; import { IExtension, IExtensionsWorkbenchService, ExtensionState } from '../common/extensions'; import { Query } from '../common/extensionQuery'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; @@ -27,14 +27,14 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge'; import { ActionBar, Separator } from 'vs/base/browser/ui/actionbar/actionbar'; -import { InstallWorkspaceRecommendedExtensionsAction, ConfigureWorkspaceFolderRecommendedExtensionsAction, ManageExtensionAction } from 'vs/workbench/contrib/extensions/electron-browser/extensionsActions'; +import { InstallWorkspaceRecommendedExtensionsAction, ConfigureWorkspaceFolderRecommendedExtensionsAction, ManageExtensionAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import { WorkbenchPagedList } from 'vs/platform/list/browser/listService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { ViewletPanel, IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { distinct, coalesce } from 'vs/base/common/arrays'; -import { IExperimentService, IExperiment, ExperimentActionType } from 'vs/workbench/contrib/experiments/electron-browser/experimentService'; +import { IExperimentService, IExperiment, ExperimentActionType } from 'vs/workbench/contrib/experiments/common/experimentService'; import { alert } from 'vs/base/browser/ui/aria/aria'; import { IListContextMenuEvent } from 'vs/base/browser/ui/list/list'; import { createErrorWithActions } from 'vs/base/common/errorsWithActions'; diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionsWidgets.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWidgets.ts similarity index 93% rename from src/vs/workbench/contrib/extensions/electron-browser/extensionsWidgets.ts rename to src/vs/workbench/contrib/extensions/browser/extensionsWidgets.ts index c34a342320f..13ec15781cd 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionsWidgets.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWidgets.ts @@ -4,14 +4,14 @@ *--------------------------------------------------------------------------------------------*/ import 'vs/css!./media/extensionsWidgets'; -import { Disposable, IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, toDisposable, DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle'; import { IExtension, IExtensionsWorkbenchService, IExtensionContainer, ExtensionState } from '../common/extensions'; import { append, $, addClass } from 'vs/base/browser/dom'; import * as platform from 'vs/base/common/platform'; import { localize } from 'vs/nls'; import { IExtensionManagementServerService, IExtensionTipsService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { ILabelService } from 'vs/platform/label/common/label'; -import { extensionButtonProminentBackground, extensionButtonProminentForeground, DisabledLabelAction, ReloadAction } from 'vs/workbench/contrib/extensions/electron-browser/extensionsActions'; +import { extensionButtonProminentBackground, extensionButtonProminentForeground, DisabledLabelAction, ReloadAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import { IThemeService, ITheme } from 'vs/platform/theme/common/themeService'; import { EXTENSION_BADGE_REMOTE_BACKGROUND, EXTENSION_BADGE_REMOTE_FOREGROUND } from 'vs/workbench/common/theme'; import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts'; @@ -196,7 +196,7 @@ export class TooltipWidget extends ExtensionWidget { export class RecommendationWidget extends ExtensionWidget { private element?: HTMLElement; - private disposables: IDisposable[] = []; + private readonly disposables = this._register(new DisposableStore()); private _tooltip: string; get tooltip(): string { return this._tooltip; } @@ -227,7 +227,7 @@ export class RecommendationWidget extends ExtensionWidget { this.parent.removeChild(this.element); } this.element = undefined; - this.disposables = dispose(this.disposables); + this.disposables.clear(); } render(): void { @@ -256,8 +256,7 @@ export class RecommendationWidget extends ExtensionWidget { export class RemoteBadgeWidget extends ExtensionWidget { - private remoteBadge: RemoteBadge | null; - private disposables: IDisposable[] = []; + private readonly remoteBadge = this._register(new MutableDisposable()); private element: HTMLElement; @@ -274,12 +273,10 @@ export class RemoteBadgeWidget extends ExtensionWidget { } private clear(): void { - if (this.remoteBadge) { - this.element.removeChild(this.remoteBadge.element); - this.remoteBadge.dispose(); + if (this.remoteBadge.value) { + this.element.removeChild(this.remoteBadge.value.element); } - this.remoteBadge = null; - this.disposables = dispose(this.disposables); + this.remoteBadge.clear(); } render(): void { @@ -288,17 +285,10 @@ export class RemoteBadgeWidget extends ExtensionWidget { return; } if (this.extension.server === this.extensionManagementServerService.remoteExtensionManagementServer) { - this.remoteBadge = this.instantiationService.createInstance(RemoteBadge, this.tooltip); - append(this.element, this.remoteBadge.element); + this.remoteBadge.value = this.instantiationService.createInstance(RemoteBadge, this.tooltip); + append(this.element, this.remoteBadge.value.element); } } - - dispose(): void { - if (this.remoteBadge) { - this.remoteBadge.dispose(); - } - super.dispose(); - } } class RemoteBadge extends Disposable { diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/clear-dark.svg b/src/vs/workbench/contrib/extensions/browser/media/clear-dark.svg similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/clear-dark.svg rename to src/vs/workbench/contrib/extensions/browser/media/clear-dark.svg diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/clear-hc.svg b/src/vs/workbench/contrib/extensions/browser/media/clear-hc.svg similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/clear-hc.svg rename to src/vs/workbench/contrib/extensions/browser/media/clear-hc.svg diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/clear-inverse.svg b/src/vs/workbench/contrib/extensions/browser/media/clear-inverse.svg similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/clear-inverse.svg rename to src/vs/workbench/contrib/extensions/browser/media/clear-inverse.svg diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/clear-light.svg b/src/vs/workbench/contrib/extensions/browser/media/clear-light.svg similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/clear-light.svg rename to src/vs/workbench/contrib/extensions/browser/media/clear-light.svg diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/configure-dark.svg b/src/vs/workbench/contrib/extensions/browser/media/configure-dark.svg similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/configure-dark.svg rename to src/vs/workbench/contrib/extensions/browser/media/configure-dark.svg diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/configure-hc.svg b/src/vs/workbench/contrib/extensions/browser/media/configure-hc.svg similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/configure-hc.svg rename to src/vs/workbench/contrib/extensions/browser/media/configure-hc.svg diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/configure-light.svg b/src/vs/workbench/contrib/extensions/browser/media/configure-light.svg similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/configure-light.svg rename to src/vs/workbench/contrib/extensions/browser/media/configure-light.svg diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/defaultIcon.png b/src/vs/workbench/contrib/extensions/browser/media/defaultIcon.png similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/defaultIcon.png rename to src/vs/workbench/contrib/extensions/browser/media/defaultIcon.png diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/extensionActions.css b/src/vs/workbench/contrib/extensions/browser/media/extensionActions.css similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/extensionActions.css rename to src/vs/workbench/contrib/extensions/browser/media/extensionActions.css diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/extensionEditor.css b/src/vs/workbench/contrib/extensions/browser/media/extensionEditor.css similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/extensionEditor.css rename to src/vs/workbench/contrib/extensions/browser/media/extensionEditor.css diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/extensions-activity-bar.svg b/src/vs/workbench/contrib/extensions/browser/media/extensions-activity-bar.svg similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/extensions-activity-bar.svg rename to src/vs/workbench/contrib/extensions/browser/media/extensions-activity-bar.svg diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/extensions.css b/src/vs/workbench/contrib/extensions/browser/media/extensions.css similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/extensions.css rename to src/vs/workbench/contrib/extensions/browser/media/extensions.css diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/extensionsViewlet.css b/src/vs/workbench/contrib/extensions/browser/media/extensionsViewlet.css similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/extensionsViewlet.css rename to src/vs/workbench/contrib/extensions/browser/media/extensionsViewlet.css diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/extensionsWidgets.css b/src/vs/workbench/contrib/extensions/browser/media/extensionsWidgets.css similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/extensionsWidgets.css rename to src/vs/workbench/contrib/extensions/browser/media/extensionsWidgets.css diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/language-icon.svg b/src/vs/workbench/contrib/extensions/browser/media/language-icon.svg similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/language-icon.svg rename to src/vs/workbench/contrib/extensions/browser/media/language-icon.svg diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/loading.svg b/src/vs/workbench/contrib/extensions/browser/media/loading.svg similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/loading.svg rename to src/vs/workbench/contrib/extensions/browser/media/loading.svg diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/markdown.css b/src/vs/workbench/contrib/extensions/browser/media/markdown.css similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/markdown.css rename to src/vs/workbench/contrib/extensions/browser/media/markdown.css diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/profile-start-dark.svg b/src/vs/workbench/contrib/extensions/browser/media/profile-start-dark.svg similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/profile-start-dark.svg rename to src/vs/workbench/contrib/extensions/browser/media/profile-start-dark.svg diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/profile-start-light.svg b/src/vs/workbench/contrib/extensions/browser/media/profile-start-light.svg similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/profile-start-light.svg rename to src/vs/workbench/contrib/extensions/browser/media/profile-start-light.svg diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/profile-stop-dark.svg b/src/vs/workbench/contrib/extensions/browser/media/profile-stop-dark.svg similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/profile-stop-dark.svg rename to src/vs/workbench/contrib/extensions/browser/media/profile-stop-dark.svg diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/profile-stop-light.svg b/src/vs/workbench/contrib/extensions/browser/media/profile-stop-light.svg similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/profile-stop-light.svg rename to src/vs/workbench/contrib/extensions/browser/media/profile-stop-light.svg diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/save-dark.svg b/src/vs/workbench/contrib/extensions/browser/media/save-dark.svg similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/save-dark.svg rename to src/vs/workbench/contrib/extensions/browser/media/save-dark.svg diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/save-light.svg b/src/vs/workbench/contrib/extensions/browser/media/save-light.svg similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/save-light.svg rename to src/vs/workbench/contrib/extensions/browser/media/save-light.svg diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/star-empty.svg b/src/vs/workbench/contrib/extensions/browser/media/star-empty.svg similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/star-empty.svg rename to src/vs/workbench/contrib/extensions/browser/media/star-empty.svg diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/star-full.svg b/src/vs/workbench/contrib/extensions/browser/media/star-full.svg similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/star-full.svg rename to src/vs/workbench/contrib/extensions/browser/media/star-full.svg diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/star-half.svg b/src/vs/workbench/contrib/extensions/browser/media/star-half.svg similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/star-half.svg rename to src/vs/workbench/contrib/extensions/browser/media/star-half.svg diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/star-small.svg b/src/vs/workbench/contrib/extensions/browser/media/star-small.svg similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/star-small.svg rename to src/vs/workbench/contrib/extensions/browser/media/star-small.svg diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/start-dark.svg b/src/vs/workbench/contrib/extensions/browser/media/start-dark.svg similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/start-dark.svg rename to src/vs/workbench/contrib/extensions/browser/media/start-dark.svg diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/start-light.svg b/src/vs/workbench/contrib/extensions/browser/media/start-light.svg similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/start-light.svg rename to src/vs/workbench/contrib/extensions/browser/media/start-light.svg diff --git a/src/vs/workbench/contrib/extensions/electron-browser/media/theme-icon.png b/src/vs/workbench/contrib/extensions/browser/media/theme-icon.png similarity index 100% rename from src/vs/workbench/contrib/extensions/electron-browser/media/theme-icon.png rename to src/vs/workbench/contrib/extensions/browser/media/theme-icon.png diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionProfileService.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionProfileService.ts index 65cbc3a44b1..283c3406d8f 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionProfileService.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionProfileService.ts @@ -7,7 +7,7 @@ import * as nls from 'vs/nls'; import { Event, Emitter } from 'vs/base/common/event'; import { IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; import { IExtensionHostProfile, ProfileSession, IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; -import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, toDisposable, MutableDisposable } from 'vs/base/common/lifecycle'; import { onUnexpectedError } from 'vs/base/common/errors'; import { StatusbarAlignment, IStatusbarService, IStatusbarEntryAccessor, IStatusbarEntry } from 'vs/platform/statusbar/common/statusbar'; import { IExtensionHostProfileService, ProfileSessionState } from 'vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor'; @@ -37,7 +37,7 @@ export class ExtensionHostProfileService extends Disposable implements IExtensio private _state: ProfileSessionState; private profilingStatusBarIndicator: IStatusbarEntryAccessor | undefined; - private profilingStatusBarIndicatorLabelUpdater: IDisposable | undefined; + private readonly profilingStatusBarIndicatorLabelUpdater = this._register(new MutableDisposable()); public get state() { return this._state; } public get lastProfile() { return this._profile; } @@ -77,10 +77,7 @@ export class ExtensionHostProfileService extends Disposable implements IExtensio } private updateProfilingStatusBarIndicator(visible: boolean): void { - if (this.profilingStatusBarIndicatorLabelUpdater) { - this.profilingStatusBarIndicatorLabelUpdater.dispose(); - this.profilingStatusBarIndicatorLabelUpdater = undefined; - } + this.profilingStatusBarIndicatorLabelUpdater.clear(); if (visible) { const indicator: IStatusbarEntry = { @@ -95,7 +92,7 @@ export class ExtensionHostProfileService extends Disposable implements IExtensio this.profilingStatusBarIndicator.update({ ...indicator, text: nls.localize('profilingExtensionHostTime', "$(sync~spin) Profiling Extension Host ({0} sec)", Math.round((new Date().getTime() - timeStarted) / 1000)), }); } }, 1000); - this.profilingStatusBarIndicatorLabelUpdater = toDisposable(() => clearInterval(handle)); + this.profilingStatusBarIndicatorLabelUpdater.value = toDisposable(() => clearInterval(handle)); if (!this.profilingStatusBarIndicator) { this.profilingStatusBarIndicator = this._statusbarService.addEntry(indicator, 'status.profiler', nls.localize('status.profiler', "Extension Profiler"), StatusbarAlignment.RIGHT); diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts index 853db02ca8d..eb853688336 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts @@ -6,7 +6,7 @@ import { localize } from 'vs/nls'; import { join } from 'vs/base/common/path'; import { forEach } from 'vs/base/common/collections'; -import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle'; +import { Disposable } from 'vs/base/common/lifecycle'; import { match } from 'vs/base/common/glob'; import * as json from 'vs/base/common/json'; import { @@ -18,7 +18,7 @@ import { ITextModel } from 'vs/editor/common/model'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import product from 'vs/platform/product/node/product'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { ShowRecommendedExtensionsAction, InstallWorkspaceRecommendedExtensionsAction, InstallRecommendedExtensionAction } from 'vs/workbench/contrib/extensions/electron-browser/extensionsActions'; +import { ShowRecommendedExtensionsAction, InstallWorkspaceRecommendedExtensionsAction, InstallRecommendedExtensionAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import Severity from 'vs/base/common/severity'; import { IWorkspaceContextService, IWorkspaceFolder, IWorkspace, IWorkspaceFoldersChangeEvent, WorkbenchState } from 'vs/platform/workspace/common/workspace'; import { IFileService } from 'vs/platform/files/common/files'; @@ -40,7 +40,7 @@ import { Emitter, Event } from 'vs/base/common/event'; import { assign } from 'vs/base/common/objects'; import { URI } from 'vs/base/common/uri'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; -import { IExperimentService, ExperimentActionType, ExperimentState } from 'vs/workbench/contrib/experiments/electron-browser/experimentService'; +import { IExperimentService, ExperimentActionType, ExperimentState } from 'vs/workbench/contrib/experiments/common/experimentService'; import { CancellationToken } from 'vs/base/common/cancellation'; import { ExtensionType } from 'vs/platform/extensions/common/extensions'; import { extname } from 'vs/base/common/resources'; @@ -82,7 +82,6 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe private _globallyIgnoredRecommendations: string[] = []; private _workspaceIgnoredRecommendations: string[] = []; private _extensionsRecommendationsUrl: string; - private _disposables: IDisposable[] = []; public loadWorkspaceConfigPromise: Promise; private proactiveRecommendationsFetched: boolean = false; @@ -134,7 +133,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe this.loadWorkspaceConfigPromise = this.getWorkspaceRecommendations().then(() => { this.promptWorkspaceRecommendations(); - this._modelService.onModelAdded(this.promptFiletypeBasedRecommendations, this, this._disposables); + this._register(this._modelService.onModelAdded(this.promptFiletypeBasedRecommendations, this)); this._modelService.getModels().forEach(model => this.promptFiletypeBasedRecommendations(model)); }); @@ -1034,8 +1033,4 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe private isExtensionAllowedToBeRecommended(id: string): boolean { return this._allIgnoredRecommendations.indexOf(id.toLowerCase()) === -1; } - - dispose() { - this._disposables = dispose(this._disposables); - } } diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensions.contribution.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensions.contribution.ts index 77643b4b45f..8723e3a6930 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensions.contribution.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensions.contribution.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import 'vs/css!./media/extensions'; +import 'vs/css!../browser/media/extensions'; import { localize } from 'vs/nls'; import { KeyMod, KeyChord, KeyCode } from 'vs/base/common/keyCodes'; import { Registry } from 'vs/platform/registry/common/platform'; @@ -22,11 +22,11 @@ import { OpenExtensionsViewletAction, InstallExtensionsAction, ShowOutdatedExtensionsAction, ShowRecommendedExtensionsAction, ShowRecommendedKeymapExtensionsAction, ShowPopularExtensionsAction, ShowEnabledExtensionsAction, ShowInstalledExtensionsAction, ShowDisabledExtensionsAction, ShowBuiltInExtensionsAction, UpdateAllAction, EnableAllAction, EnableAllWorkpsaceAction, DisableAllAction, DisableAllWorkpsaceAction, CheckForUpdatesAction, ShowLanguageExtensionsAction, ShowAzureExtensionsAction, EnableAutoUpdateAction, DisableAutoUpdateAction, ConfigureRecommendedExtensionsCommandsContributor, OpenExtensionsFolderAction, InstallVSIXAction, ReinstallAction, InstallSpecificVersionOfExtensionAction -} from 'vs/workbench/contrib/extensions/electron-browser/extensionsActions'; +} from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import { ExtensionsInput } from 'vs/workbench/contrib/extensions/common/extensionsInput'; import { ViewletRegistry, Extensions as ViewletExtensions, ViewletDescriptor } from 'vs/workbench/browser/viewlet'; -import { ExtensionEditor } from 'vs/workbench/contrib/extensions/electron-browser/extensionEditor'; -import { StatusUpdater, ExtensionsViewlet, MaliciousExtensionChecker, ExtensionsViewletViewsContribution } from 'vs/workbench/contrib/extensions/electron-browser/extensionsViewlet'; +import { ExtensionEditor } from 'vs/workbench/contrib/extensions/browser/extensionEditor'; +import { StatusUpdater, ExtensionsViewlet, MaliciousExtensionChecker, ExtensionsViewletViewsContribution } from 'vs/workbench/contrib/extensions/browser/extensionsViewlet'; import { IQuickOpenRegistry, Extensions, QuickOpenHandlerDescriptor } from 'vs/workbench/browser/quickopen'; import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; import * as jsonContributionRegistry from 'vs/platform/jsonschemas/common/jsonContributionRegistry'; @@ -47,7 +47,7 @@ import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey'; import { ExtensionActivationProgress } from 'vs/workbench/contrib/extensions/browser/extensionsActivationProgress'; import { ExtensionsAutoProfiler } from 'vs/workbench/contrib/extensions/electron-browser/extensionsAutoProfiler'; import { onUnexpectedError } from 'vs/base/common/errors'; -import { ExtensionDependencyChecker } from 'vs/workbench/contrib/extensions/electron-browser/extensionsDependencyChecker'; +import { ExtensionDependencyChecker } from 'vs/workbench/contrib/extensions/browser/extensionsDependencyChecker'; import { CancellationToken } from 'vs/base/common/cancellation'; import { ExtensionType } from 'vs/platform/extensions/common/extensions'; @@ -337,8 +337,8 @@ MenuRegistry.appendMenuItem(MenuId.EditorTitle, { id: DebugExtensionHostAction.ID, title: DebugExtensionHostAction.LABEL, iconLocation: { - dark: URI.parse(require.toUrl(`vs/workbench/contrib/extensions/electron-browser/media/start-dark.svg`)), - light: URI.parse(require.toUrl(`vs/workbench/contrib/extensions/electron-browser/media/start-light.svg`)), + dark: URI.parse(require.toUrl(`vs/workbench/contrib/extensions/browser/media/start-dark.svg`)), + light: URI.parse(require.toUrl(`vs/workbench/contrib/extensions/browser/media/start-light.svg`)), } }, group: 'navigation', @@ -350,8 +350,8 @@ MenuRegistry.appendMenuItem(MenuId.EditorTitle, { id: StartExtensionHostProfileAction.ID, title: StartExtensionHostProfileAction.LABEL, iconLocation: { - dark: URI.parse(require.toUrl(`vs/workbench/contrib/extensions/electron-browser/media/profile-start-dark.svg`)), - light: URI.parse(require.toUrl(`vs/workbench/contrib/extensions/electron-browser/media/profile-start-light.svg`)), + dark: URI.parse(require.toUrl(`vs/workbench/contrib/extensions/browser/media/profile-start-dark.svg`)), + light: URI.parse(require.toUrl(`vs/workbench/contrib/extensions/browser/media/profile-start-light.svg`)), } }, group: 'navigation', @@ -363,8 +363,8 @@ MenuRegistry.appendMenuItem(MenuId.EditorTitle, { id: StopExtensionHostProfileAction.ID, title: StopExtensionHostProfileAction.LABEL, iconLocation: { - dark: URI.parse(require.toUrl(`vs/workbench/contrib/extensions/electron-browser/media/profile-stop-dark.svg`)), - light: URI.parse(require.toUrl(`vs/workbench/contrib/extensions/electron-browser/media/profile-stop-light.svg`)), + dark: URI.parse(require.toUrl(`vs/workbench/contrib/extensions/browser/media/profile-stop-dark.svg`)), + light: URI.parse(require.toUrl(`vs/workbench/contrib/extensions/browser/media/profile-stop-light.svg`)), } }, group: 'navigation', @@ -376,8 +376,8 @@ MenuRegistry.appendMenuItem(MenuId.EditorTitle, { id: SaveExtensionHostProfileAction.ID, title: SaveExtensionHostProfileAction.LABEL, iconLocation: { - dark: URI.parse(require.toUrl(`vs/workbench/contrib/extensions/electron-browser/media/save-dark.svg`)), - light: URI.parse(require.toUrl(`vs/workbench/contrib/extensions/electron-browser/media/save-light.svg`)), + dark: URI.parse(require.toUrl(`vs/workbench/contrib/extensions/browser/media/save-dark.svg`)), + light: URI.parse(require.toUrl(`vs/workbench/contrib/extensions/browser/media/save-light.svg`)), }, precondition: CONTEXT_EXTENSION_HOST_PROFILE_RECORDED }, diff --git a/src/vs/workbench/contrib/extensions/node/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/node/extensionsWorkbenchService.ts index cbcdbaac997..fe9b03f0756 100644 --- a/src/vs/workbench/contrib/extensions/node/extensionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/extensions/node/extensionsWorkbenchService.ts @@ -25,7 +25,6 @@ import { IExtension, ExtensionState, IExtensionsWorkbenchService, AutoUpdateConf import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { IURLService, IURLHandler } from 'vs/platform/url/common/url'; import { ExtensionsInput } from 'vs/workbench/contrib/extensions/common/extensionsInput'; -import product from 'vs/platform/product/node/product'; import { ILogService } from 'vs/platform/log/common/log'; import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress'; import { INotificationService } from 'vs/platform/notification/common/notification'; @@ -35,6 +34,7 @@ import { IStorageService, StorageScope } from 'vs/platform/storage/common/storag import { IFileService } from 'vs/platform/files/common/files'; import { IExtensionManifest, ExtensionType, IExtension as IPlatformExtension, isLanguagePackExtension } from 'vs/platform/extensions/common/extensions'; import { IModeService } from 'vs/editor/common/services/modeService'; +import { IProductService } from 'vs/platform/product/common/product'; interface IExtensionStateProvider { (extension: Extension): T; @@ -45,14 +45,15 @@ class Extension implements IExtension { public enablementState: EnablementState = EnablementState.Enabled; constructor( - private galleryService: IExtensionGalleryService, private stateProvider: IExtensionStateProvider, public readonly server: IExtensionManagementServer | undefined, public local: ILocalExtension | undefined, public gallery: IGalleryExtension | undefined, - private telemetryService: ITelemetryService, - private logService: ILogService, - private fileService: IFileService + @IExtensionGalleryService private readonly galleryService: IExtensionGalleryService, + @ITelemetryService private readonly telemetryService: ITelemetryService, + @ILogService private readonly logService: ILogService, + @IFileService private readonly fileService: IFileService, + @IProductService private readonly productService: IProductService ) { } get type(): ExtensionType | undefined { @@ -111,11 +112,11 @@ class Extension implements IExtension { } get url(): string | undefined { - if (!product.extensionsGallery || !this.gallery) { + if (!this.productService.extensionsGallery || !this.gallery) { return undefined; } - return `${product.extensionsGallery.itemUrl}?itemName=${this.publisher}.${this.name}`; + return `${this.productService.extensionsGallery.itemUrl}?itemName=${this.publisher}.${this.name}`; } get iconUrl(): string { @@ -145,14 +146,14 @@ class Extension implements IExtension { if (this.type === ExtensionType.System && this.local) { if (this.local.manifest && this.local.manifest.contributes) { if (Array.isArray(this.local.manifest.contributes.themes) && this.local.manifest.contributes.themes.length) { - return require.toUrl('../electron-browser/media/theme-icon.png'); + return require.toUrl('../browser/media/theme-icon.png'); } if (Array.isArray(this.local.manifest.contributes.grammars) && this.local.manifest.contributes.grammars.length) { - return require.toUrl('../electron-browser/media/language-icon.svg'); + return require.toUrl('../browser/media/language-icon.svg'); } } } - return require.toUrl('../electron-browser/media/defaultIcon.png'); + return require.toUrl('../browser/media/defaultIcon.png'); } get repository(): string | undefined { @@ -316,10 +317,8 @@ class Extensions extends Disposable { private readonly server: IExtensionManagementServer, private readonly stateProvider: IExtensionStateProvider, @IExtensionGalleryService private readonly galleryService: IExtensionGalleryService, - @ITelemetryService private readonly telemetryService: ITelemetryService, - @ILogService private readonly logService: ILogService, - @IFileService private readonly fileService: IFileService, - @IExtensionEnablementService private readonly extensionEnablementService: IExtensionEnablementService + @IExtensionEnablementService private readonly extensionEnablementService: IExtensionEnablementService, + @IInstantiationService private readonly instantiationService: IInstantiationService ) { super(); this._register(server.extensionManagementService.onInstallExtension(e => this.onInstallExtension(e))); @@ -341,7 +340,7 @@ class Extensions extends Disposable { const installed = await this.server.extensionManagementService.getInstalled(); const byId = index(this.installed, e => e.local ? e.local.identifier.id : e.identifier.id); this.installed = installed.map(local => { - const extension = byId[local.identifier.id] || new Extension(this.galleryService, this.stateProvider, this.server, local, undefined, this.telemetryService, this.logService, this.fileService); + const extension = byId[local.identifier.id] || this.instantiationService.createInstance(Extension, this.stateProvider, this.server, local, undefined); extension.local = local; extension.enablementState = this.extensionEnablementService.getEnablementState(local); return extension; @@ -394,7 +393,7 @@ class Extensions extends Disposable { const { gallery } = event; if (gallery) { const extension = this.installed.filter(e => areSameExtensions(e.identifier, gallery.identifier))[0] - || new Extension(this.galleryService, this.stateProvider, this.server, undefined, gallery, this.telemetryService, this.logService, this.fileService); + || this.instantiationService.createInstance(Extension, this.stateProvider, this.server, undefined, gallery); this.installing.push(extension); this._onChange.fire(extension); } @@ -405,7 +404,7 @@ class Extensions extends Disposable { const installingExtension = gallery ? this.installing.filter(e => areSameExtensions(e.identifier, gallery.identifier))[0] : null; this.installing = installingExtension ? this.installing.filter(e => e !== installingExtension) : this.installing; - let extension: Extension | undefined = installingExtension ? installingExtension : zipPath ? new Extension(this.galleryService, this.stateProvider, this.server, local, undefined, this.telemetryService, this.logService, this.fileService) : undefined; + let extension: Extension | undefined = installingExtension ? installingExtension : zipPath ? this.instantiationService.createInstance(Extension, this.stateProvider, this.server, local, undefined) : undefined; if (extension) { if (local) { const installed = this.installed.filter(e => areSameExtensions(e.identifier, extension!.identifier))[0]; @@ -495,12 +494,11 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension @IURLService urlService: IURLService, @IExtensionEnablementService private readonly extensionEnablementService: IExtensionEnablementService, @IWindowService private readonly windowService: IWindowService, - @ILogService private readonly logService: ILogService, @IProgressService private readonly progressService: IProgressService, @IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService, @IStorageService private readonly storageService: IStorageService, - @IFileService private readonly fileService: IFileService, - @IModeService private readonly modeService: IModeService + @IModeService private readonly modeService: IModeService, + @IProductService private readonly productService: IProductService ) { super(); this.localExtensions = this._register(instantiationService.createInstance(Extensions, extensionManagementServerService.localExtensionManagementServer, ext => this.getExtensionState(ext))); @@ -605,7 +603,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension text = text.replace(extensionRegex, (m, ext) => { // Get curated keywords - const lookup = product.extensionKeywords || {}; + const lookup = this.productService.extensionKeywords || {}; const keywords = lookup[ext] || []; // Get mode name @@ -648,7 +646,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension if (installed) { return installed; } - const extension = new Extension(this.galleryService, ext => this.getExtensionState(ext), undefined, undefined, gallery, this.telemetryService, this.logService, this.fileService); + const extension = this.instantiationService.createInstance(Extension, ext => this.getExtensionState(ext), undefined, undefined, gallery); if (maliciousExtensionSet.has(extension.identifier.id)) { extension.isMalicious = true; } @@ -998,7 +996,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension get allowedBadgeProviders(): string[] { if (!this._extensionAllowedBadgeProviders) { - this._extensionAllowedBadgeProviders = (product.extensionAllowedBadgeProviders || []).map(s => s.toLowerCase()); + this._extensionAllowedBadgeProviders = (this.productService.extensionAllowedBadgeProviders || []).map(s => s.toLowerCase()); } return this._extensionAllowedBadgeProviders; } diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts index 9d1919ae5e5..49503a85eca 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsActions.test.ts @@ -7,7 +7,7 @@ import * as assert from 'assert'; import { assign } from 'vs/base/common/objects'; import { generateUuid } from 'vs/base/common/uuid'; import { IExtensionsWorkbenchService, ExtensionContainers } from 'vs/workbench/contrib/extensions/common/extensions'; -import * as ExtensionsActions from 'vs/workbench/contrib/extensions/electron-browser/extensionsActions'; +import * as ExtensionsActions from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import { ExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/node/extensionsWorkbenchService'; import { IExtensionManagementService, IExtensionGalleryService, IExtensionEnablementService, IExtensionTipsService, ILocalExtension, IGalleryExtension, @@ -17,7 +17,7 @@ import { getGalleryExtensionId } from 'vs/platform/extensionManagement/common/ex import { ExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService'; import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/electron-browser/extensionTipsService'; import { TestExtensionEnablementService } from 'vs/workbench/services/extensionManagement/test/electron-browser/extensionEnablementService.test'; -import { ExtensionGalleryService } from 'vs/platform/extensionManagement/node/extensionGalleryService'; +import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService'; import { IURLService } from 'vs/platform/url/common/url'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { Emitter } from 'vs/base/common/event'; diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsTipsService.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsTipsService.test.ts index abe5d44d706..eb1c1c0aa08 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsTipsService.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsTipsService.test.ts @@ -15,7 +15,7 @@ import { IExtensionEnablementService, DidInstallExtensionEvent, DidUninstallExtensionEvent, InstallExtensionEvent, IExtensionIdentifier } from 'vs/platform/extensionManagement/common/extensionManagement'; import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/electron-browser/extensionTipsService'; -import { ExtensionGalleryService } from 'vs/platform/extensionManagement/node/extensionGalleryService'; +import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { Emitter } from 'vs/base/common/event'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; @@ -41,7 +41,7 @@ import { IModelService } from 'vs/editor/common/services/modelService'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { INotificationService, Severity, IPromptChoice, IPromptOptions } from 'vs/platform/notification/common/notification'; import { URLService } from 'vs/platform/url/common/urlService'; -import { IExperimentService } from 'vs/workbench/contrib/experiments/electron-browser/experimentService'; +import { IExperimentService } from 'vs/workbench/contrib/experiments/common/experimentService'; import { TestExperimentService } from 'vs/workbench/contrib/experiments/test/electron-browser/experimentService.test'; import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { ExtensionType } from 'vs/platform/extensions/common/extensions'; diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts index c9ad5d996c8..55e61060143 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsViews.test.ts @@ -6,7 +6,7 @@ import * as assert from 'assert'; import { assign } from 'vs/base/common/objects'; import { generateUuid } from 'vs/base/common/uuid'; -import { ExtensionsListView } from 'vs/workbench/contrib/extensions/electron-browser/extensionsViews'; +import { ExtensionsListView } from 'vs/workbench/contrib/extensions/browser/extensionsViews'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { IExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/common/extensions'; import { ExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/node/extensionsWorkbenchService'; @@ -18,7 +18,7 @@ import { getGalleryExtensionId } from 'vs/platform/extensionManagement/common/ex import { ExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService'; import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/electron-browser/extensionTipsService'; import { TestExtensionEnablementService } from 'vs/workbench/services/extensionManagement/test/electron-browser/extensionEnablementService.test'; -import { ExtensionGalleryService } from 'vs/platform/extensionManagement/node/extensionGalleryService'; +import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService'; import { IURLService } from 'vs/platform/url/common/url'; import { Emitter } from 'vs/base/common/event'; import { IPager } from 'vs/base/common/paging'; @@ -34,7 +34,8 @@ import { URLService } from 'vs/platform/url/common/urlService'; import { URI } from 'vs/base/common/uri'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { SinonStub } from 'sinon'; -import { IExperimentService, ExperimentService, ExperimentState, ExperimentActionType } from 'vs/workbench/contrib/experiments/electron-browser/experimentService'; +import { IExperimentService, ExperimentState, ExperimentActionType } from 'vs/workbench/contrib/experiments/common/experimentService'; +import { ExperimentService } from 'vs/workbench/contrib/experiments/electron-browser/experimentService'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { RemoteAgentService } from 'vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl'; import { ExtensionIdentifier, ExtensionType, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts index 783230407cc..1b142655ae5 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts @@ -18,7 +18,7 @@ import { getGalleryExtensionId } from 'vs/platform/extensionManagement/common/ex import { ExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService'; import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/electron-browser/extensionTipsService'; import { TestExtensionEnablementService } from 'vs/workbench/services/extensionManagement/test/electron-browser/extensionEnablementService.test'; -import { ExtensionGalleryService } from 'vs/platform/extensionManagement/node/extensionGalleryService'; +import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService'; import { IURLService } from 'vs/platform/url/common/url'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { Event, Emitter } from 'vs/base/common/event'; diff --git a/src/vs/workbench/contrib/markers/browser/markers.ts b/src/vs/workbench/contrib/markers/browser/markers.ts index a8eeb539c22..4b27488a458 100644 --- a/src/vs/workbench/contrib/markers/browser/markers.ts +++ b/src/vs/workbench/contrib/markers/browser/markers.ts @@ -5,7 +5,7 @@ import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { MarkersModel, compareMarkersByUri } from './markersModel'; -import { Disposable } from 'vs/base/common/lifecycle'; +import { Disposable, MutableDisposable, IDisposable } from 'vs/base/common/lifecycle'; import { IMarkerService, MarkerSeverity, IMarker } from 'vs/platform/markers/common/markers'; import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activity'; import { localize } from 'vs/nls'; @@ -59,6 +59,8 @@ export class MarkersWorkbenchService extends Disposable implements IMarkersWorkb export class ActivityUpdater extends Disposable implements IWorkbenchContribution { + private readonly activity = this._register(new MutableDisposable()); + constructor( @IActivityService private readonly activityService: IActivityService, @IMarkerService private readonly markerService: IMarkerService @@ -72,6 +74,6 @@ export class ActivityUpdater extends Disposable implements IWorkbenchContributio const { errors, warnings, infos } = this.markerService.getStatistics(); const total = errors + warnings + infos; const message = localize('totalProblems', 'Total {0} Problems', total); - this.activityService.showActivity(Constants.MARKERS_PANEL_ID, new NumberBadge(total, () => message)); + this.activity.value = this.activityService.showActivity(Constants.MARKERS_PANEL_ID, new NumberBadge(total, () => message)); } } \ No newline at end of file diff --git a/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts b/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts index b108f6696ba..c2d2c57df76 100644 --- a/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts +++ b/src/vs/workbench/contrib/preferences/browser/keybindingsEditor.ts @@ -8,7 +8,7 @@ import { localize } from 'vs/nls'; import { Delayer } from 'vs/base/common/async'; import * as DOM from 'vs/base/browser/dom'; import { OS } from 'vs/base/common/platform'; -import { dispose, Disposable, toDisposable, IDisposable, combinedDisposable } from 'vs/base/common/lifecycle'; +import { dispose, Disposable, IDisposable, combinedDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { CheckboxActionViewItem } from 'vs/base/browser/ui/checkbox/checkbox'; import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel'; import { KeybindingLabel } from 'vs/base/browser/ui/keybindingLabel/keybindingLabel'; @@ -897,6 +897,7 @@ class ActionsColumn extends Column { } dispose(): void { + super.dispose(); dispose(this.actionBar); } } @@ -1015,7 +1016,7 @@ class WhenColumn extends Column { readonly element: HTMLElement; private whenLabel: HTMLElement; private whenInput: InputBox; - private disposables: IDisposable[] = []; + private readonly renderDisposables = this._register(new DisposableStore()); private _onDidAccept: Emitter = this._register(new Emitter()); private readonly onDidAccept: Event = this._onDidAccept.event; @@ -1031,7 +1032,6 @@ class WhenColumn extends Column { ) { super(keybindingsEditor); this.element = this.create(parent); - this._register(toDisposable(() => this.disposables = dispose(this.disposables))); } private create(parent: HTMLElement): HTMLElement { @@ -1094,14 +1094,14 @@ class WhenColumn extends Column { } render(keybindingItemEntry: IKeybindingItemEntry): void { - this.disposables = dispose(this.disposables); + this.renderDisposables.clear(); DOM.clearNode(this.whenLabel); this.keybindingsEditor.onDefineWhenExpression(e => { if (keybindingItemEntry === e) { this.startEditing(); } - }, this, this.disposables); + }, this, this.renderDisposables); this.whenInput.value = keybindingItemEntry.keybindingItem.when || ''; this.whenLabel.setAttribute('aria-label', this.getAriaLabel(keybindingItemEntry)); DOM.toggleClass(this.whenLabel, 'code', !!keybindingItemEntry.keybindingItem.when); @@ -1118,11 +1118,11 @@ class WhenColumn extends Column { this.onDidAccept(() => { this.keybindingsEditor.updateKeybinding(keybindingItemEntry, keybindingItemEntry.keybindingItem.keybinding ? keybindingItemEntry.keybindingItem.keybinding.getUserSettingsLabel() || '' : '', this.whenInput.value); this.keybindingsEditor.selectKeybinding(keybindingItemEntry); - }, this, this.disposables); + }, this, this.renderDisposables); this.onDidReject(() => { this.whenInput.value = keybindingItemEntry.keybindingItem.when || ''; this.keybindingsEditor.selectKeybinding(keybindingItemEntry); - }, this, this.disposables); + }, this, this.renderDisposables); } private getAriaLabel(keybindingItemEntry: IKeybindingItemEntry): string { diff --git a/src/vs/workbench/contrib/preferences/browser/preferencesRenderers.ts b/src/vs/workbench/contrib/preferences/browser/preferencesRenderers.ts index de35c736f91..e353af16e13 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferencesRenderers.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferencesRenderers.ts @@ -9,7 +9,7 @@ import { IAction } from 'vs/base/common/actions'; import { Delayer } from 'vs/base/common/async'; import { Emitter, Event } from 'vs/base/common/event'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; -import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { ICodeEditor, IEditorMouseEvent, MouseTargetType } from 'vs/editor/browser/editorBrowser'; import { ICursorPositionChangedEvent } from 'vs/editor/common/controller/cursorEvents'; import { Position } from 'vs/editor/common/core/position'; @@ -442,7 +442,7 @@ export class SettingsGroupTitleRenderer extends Disposable implements HiddenArea private settingsGroups: ISettingsGroup[]; private hiddenGroups: ISettingsGroup[] = []; private settingsGroupTitleWidgets: SettingsGroupTitleWidget[]; - private renderDisposables: IDisposable[] = []; + private readonly renderDisposables = this._register(new DisposableStore()); constructor(private editor: ICodeEditor, @IInstantiationService private readonly instantiationService: IInstantiationService @@ -474,8 +474,8 @@ export class SettingsGroupTitleRenderer extends Disposable implements HiddenArea const settingsGroupTitleWidget = this.instantiationService.createInstance(SettingsGroupTitleWidget, this.editor, group); settingsGroupTitleWidget.render(); this.settingsGroupTitleWidgets.push(settingsGroupTitleWidget); - this.renderDisposables.push(settingsGroupTitleWidget); - this.renderDisposables.push(settingsGroupTitleWidget.onToggled(collapsed => this.onToggled(collapsed, settingsGroupTitleWidget.settingsGroup))); + this.renderDisposables.add(settingsGroupTitleWidget); + this.renderDisposables.add(settingsGroupTitleWidget.onToggled(collapsed => this.onToggled(collapsed, settingsGroupTitleWidget.settingsGroup))); } this.settingsGroupTitleWidgets.reverse(); } @@ -515,7 +515,7 @@ export class SettingsGroupTitleRenderer extends Disposable implements HiddenArea private disposeWidgets() { this.hiddenGroups = []; - this.renderDisposables = dispose(this.renderDisposables); + this.renderDisposables.clear(); } dispose() { diff --git a/src/vs/workbench/contrib/preferences/browser/preferencesWidgets.ts b/src/vs/workbench/contrib/preferences/browser/preferencesWidgets.ts index 49beca20e0d..f45d098fb72 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferencesWidgets.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferencesWidgets.ts @@ -12,7 +12,7 @@ import { Action, IAction } from 'vs/base/common/actions'; import { Emitter, Event } from 'vs/base/common/event'; import { MarkdownString } from 'vs/base/common/htmlContent'; import { KeyCode } from 'vs/base/common/keyCodes'; -import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle'; +import { Disposable } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; import { IMarginData } from 'vs/editor/browser/controller/mouseTarget'; import { ICodeEditor, IEditorMouseEvent, IViewZone, MouseTargetType } from 'vs/editor/browser/editorBrowser'; @@ -302,8 +302,6 @@ export class FolderSettingsActionViewItem extends BaseActionViewItem { private detailsElement: HTMLElement; private dropDownElement: HTMLElement; - private disposables: IDisposable[] = []; - constructor( action: IAction, @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, @@ -312,7 +310,7 @@ export class FolderSettingsActionViewItem extends BaseActionViewItem { super(null, action); const workspace = this.contextService.getWorkspace(); this._folder = workspace.folders.length === 1 ? workspace.folders[0] : null; - this.disposables.push(this.contextService.onDidChangeWorkspaceFolders(() => this.onWorkspaceFoldersChanged())); + this._register(this.contextService.onDidChangeWorkspaceFolders(() => this.onWorkspaceFoldersChanged())); } get folder(): IWorkspaceFolder | null { @@ -347,8 +345,8 @@ export class FolderSettingsActionViewItem extends BaseActionViewItem { 'tabindex': '0' }, this.labelElement, this.detailsElement, this.dropDownElement); this._register(DOM.addDisposableListener(this.anchorElement, DOM.EventType.MOUSE_DOWN, e => DOM.EventHelper.stop(e))); - this.disposables.push(DOM.addDisposableListener(this.anchorElement, DOM.EventType.CLICK, e => this.onClick(e))); - this.disposables.push(DOM.addDisposableListener(this.anchorElement, DOM.EventType.KEY_UP, e => this.onKeyUp(e))); + this._register(DOM.addDisposableListener(this.anchorElement, DOM.EventType.CLICK, e => this.onClick(e))); + this._register(DOM.addDisposableListener(this.anchorElement, DOM.EventType.KEY_UP, e => this.onKeyUp(e))); DOM.append(this.container, this.anchorElement); @@ -460,11 +458,6 @@ export class FolderSettingsActionViewItem extends BaseActionViewItem { return label; } - - dispose(): void { - dispose(this.disposables); - super.dispose(); - } } export type SettingsTarget = ConfigurationTarget.USER_LOCAL | ConfigurationTarget.USER_REMOTE | ConfigurationTarget.WORKSPACE | URI; diff --git a/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts b/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts index e495a488cfa..c14cb52118c 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts @@ -12,7 +12,7 @@ import { IAction } from 'vs/base/common/actions'; import { Color, RGBA } from 'vs/base/common/color'; import { Emitter, Event } from 'vs/base/common/event'; import { KeyCode } from 'vs/base/common/keyCodes'; -import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import 'vs/css!./media/settingsWidgets'; import { localize } from 'vs/nls'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; @@ -199,7 +199,7 @@ export interface IExcludeChangeEvent { export class ExcludeSettingWidget extends Disposable { private listElement: HTMLElement; - private listDisposables: IDisposable[] = []; + private readonly listDisposables = this._register(new DisposableStore()); private model = new ExcludeSettingListModel(); @@ -304,7 +304,7 @@ export class ExcludeSettingWidget extends Disposable { const focused = DOM.isAncestor(document.activeElement, this.listElement); DOM.clearNode(this.listElement); - this.listDisposables = dispose(this.listDisposables); + this.listDisposables.clear(); const newMode = this.model.items.some(item => !!(item.editing && !item.pattern)); DOM.toggleClass(this.container, 'setting-exclude-new-mode', newMode); @@ -357,7 +357,7 @@ export class ExcludeSettingWidget extends Disposable { DOM.toggleClass(rowElement, 'selected', item.selected); const actionBar = new ActionBar(rowElement); - this.listDisposables.push(actionBar); + this.listDisposables.add(actionBar); const patternElement = DOM.append(rowElement, $('.setting-exclude-pattern')); const siblingElement = DOM.append(rowElement, $('.setting-exclude-sibling')); @@ -429,14 +429,14 @@ export class ExcludeSettingWidget extends Disposable { placeholder: localize('excludePatternInputPlaceholder', "Exclude Pattern...") }); patternInput.element.classList.add('setting-exclude-patternInput'); - this.listDisposables.push(attachInputBoxStyler(patternInput, this.themeService, { + this.listDisposables.add(attachInputBoxStyler(patternInput, this.themeService, { inputBackground: settingsTextInputBackground, inputForeground: settingsTextInputForeground, inputBorder: settingsTextInputBorder })); - this.listDisposables.push(patternInput); + this.listDisposables.add(patternInput); patternInput.value = item.pattern; - this.listDisposables.push(DOM.addStandardDisposableListener(patternInput.inputElement, DOM.EventType.KEY_DOWN, onKeydown)); + this.listDisposables.add(DOM.addStandardDisposableListener(patternInput.inputElement, DOM.EventType.KEY_DOWN, onKeydown)); let siblingInput: InputBox; if (item.sibling) { @@ -444,29 +444,29 @@ export class ExcludeSettingWidget extends Disposable { placeholder: localize('excludeSiblingInputPlaceholder', "When Pattern Is Present...") }); siblingInput.element.classList.add('setting-exclude-siblingInput'); - this.listDisposables.push(siblingInput); - this.listDisposables.push(attachInputBoxStyler(siblingInput, this.themeService, { + this.listDisposables.add(siblingInput); + this.listDisposables.add(attachInputBoxStyler(siblingInput, this.themeService, { inputBackground: settingsTextInputBackground, inputForeground: settingsTextInputForeground, inputBorder: settingsTextInputBorder })); siblingInput.value = item.sibling; - this.listDisposables.push(DOM.addStandardDisposableListener(siblingInput.inputElement, DOM.EventType.KEY_DOWN, onKeydown)); + this.listDisposables.add(DOM.addStandardDisposableListener(siblingInput.inputElement, DOM.EventType.KEY_DOWN, onKeydown)); } const okButton = this._register(new Button(rowElement)); okButton.label = localize('okButton', "OK"); okButton.element.classList.add('setting-exclude-okButton'); - this.listDisposables.push(attachButtonStyler(okButton, this.themeService)); - this.listDisposables.push(okButton.onDidClick(() => onSubmit(true))); + this.listDisposables.add(attachButtonStyler(okButton, this.themeService)); + this.listDisposables.add(okButton.onDidClick(() => onSubmit(true))); const cancelButton = this._register(new Button(rowElement)); cancelButton.label = localize('cancelButton', "Cancel"); cancelButton.element.classList.add('setting-exclude-cancelButton'); - this.listDisposables.push(attachButtonStyler(cancelButton, this.themeService)); - this.listDisposables.push(cancelButton.onDidClick(() => onSubmit(false))); + this.listDisposables.add(attachButtonStyler(cancelButton, this.themeService)); + this.listDisposables.add(cancelButton.onDidClick(() => onSubmit(false))); - this.listDisposables.push( + this.listDisposables.add( disposableTimeout(() => { patternInput.focus(); patternInput.select(); @@ -474,11 +474,6 @@ export class ExcludeSettingWidget extends Disposable { return rowElement; } - - dispose() { - super.dispose(); - this.listDisposables = dispose(this.listDisposables); - } } export interface IExcludeDataItem { diff --git a/src/vs/workbench/contrib/remote/electron-browser/remote.contribution.ts b/src/vs/workbench/contrib/remote/electron-browser/remote.contribution.ts index 78264965a27..8d9b3dda9f4 100644 --- a/src/vs/workbench/contrib/remote/electron-browser/remote.contribution.ts +++ b/src/vs/workbench/contrib/remote/electron-browser/remote.contribution.ts @@ -397,12 +397,45 @@ class RemoteTelemetryEnablementUpdater extends Disposable implements IWorkbenchC } } +class RemoteEmptyWorkbenchPresentation extends Disposable implements IWorkbenchContribution { + constructor( + @IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService, + @IRemoteAuthorityResolverService remoteAuthorityResolverService: IRemoteAuthorityResolverService, + @IConfigurationService configurationService: IConfigurationService, + @ICommandService commandService: ICommandService, + ) { + super(); + + function shouldShowExplorer(): boolean { + const startupEditor = configurationService.getValue('workbench.startupEditor'); + return startupEditor !== 'welcomePage' && startupEditor !== 'welcomePageInEmptyWorkbench'; + } + + function shouldShowTerminal(): boolean { + return shouldShowExplorer(); + } + + const { remoteAuthority, folderUri, workspace } = environmentService.configuration; + if (remoteAuthority && !folderUri && !workspace) { + remoteAuthorityResolverService.resolveAuthority(remoteAuthority).then(() => { + if (shouldShowExplorer()) { + commandService.executeCommand('workbench.view.explorer'); + } + if (shouldShowTerminal()) { + commandService.executeCommand('workbench.action.terminal.toggleTerminal'); + } + }); + } + } +} + const workbenchContributionsRegistry = Registry.as(WorkbenchContributionsExtensions.Workbench); workbenchContributionsRegistry.registerWorkbenchContribution(RemoteChannelsContribution, LifecyclePhase.Starting); workbenchContributionsRegistry.registerWorkbenchContribution(RemoteAgentDiagnosticListener, LifecyclePhase.Eventually); workbenchContributionsRegistry.registerWorkbenchContribution(RemoteAgentConnectionStatusListener, LifecyclePhase.Eventually); workbenchContributionsRegistry.registerWorkbenchContribution(RemoteWindowActiveIndicator, LifecyclePhase.Starting); workbenchContributionsRegistry.registerWorkbenchContribution(RemoteTelemetryEnablementUpdater, LifecyclePhase.Ready); +workbenchContributionsRegistry.registerWorkbenchContribution(RemoteEmptyWorkbenchPresentation, LifecyclePhase.Starting); Registry.as(ConfigurationExtensions.Configuration) .registerConfiguration({ diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 0e6d93805cb..1dc49e0e242 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -151,10 +151,21 @@ export const DEFAULT_COMMANDS_TO_SKIP_SHELL: string[] = [ let xtermConstructor: Promise | undefined; +interface ICanvasDimensions { + width: number; + height: number; +} + +interface IGridDimensions { + cols: number; + rows: number; +} + export class TerminalInstance implements ITerminalInstance { private static readonly EOL_REGEX = /\r?\n/g; - private static _lastKnownDimensions: dom.Dimension | null = null; + private static _lastKnownCanvasDimensions: ICanvasDimensions | undefined; + private static _lastKnownGridDimensions: IGridDimensions | undefined; private static _idCounter = 1; private _processManager: ITerminalProcessManager | undefined; @@ -327,16 +338,19 @@ export class TerminalInstance implements ITerminalInstance { private _evaluateColsAndRows(width: number, height: number): number | null { // Ignore if dimensions are undefined or 0 if (!width || !height) { + this._setLastKnownColsAndRows(); return null; } const dimension = this._getDimension(width, height); if (!dimension) { + this._setLastKnownColsAndRows(); return null; } const font = this._configHelper.getFont(this._xterm); if (!font.charWidth || !font.charHeight) { + this._setLastKnownColsAndRows(); return null; } @@ -368,21 +382,28 @@ export class TerminalInstance implements ITerminalInstance { return dimension.width; } + private _setLastKnownColsAndRows(): void { + if (TerminalInstance._lastKnownGridDimensions) { + this._cols = TerminalInstance._lastKnownGridDimensions.cols; + this._rows = TerminalInstance._lastKnownGridDimensions.rows; + } + } + @debounce(50) private _fireMaximumDimensionsChanged(): void { this._onMaximumDimensionsChanged.fire(); } - private _getDimension(width: number, height: number): dom.Dimension | null { + private _getDimension(width: number, height: number): ICanvasDimensions | undefined { // The font needs to have been initialized const font = this._configHelper.getFont(this._xterm); if (!font || !font.charWidth || !font.charHeight) { - return null; + return undefined; } // The panel is minimized if (!this._isVisible) { - return TerminalInstance._lastKnownDimensions; + return TerminalInstance._lastKnownCanvasDimensions; } else { // Trigger scroll event manually so that the viewport's scroll area is synced. This // needs to happen otherwise its scrollTop value is invalid when the panel is toggled as @@ -394,7 +415,7 @@ export class TerminalInstance implements ITerminalInstance { } if (!this._wrapperElement) { - return null; + return undefined; } const wrapperElementStyle = getComputedStyle(this._wrapperElement); @@ -405,8 +426,8 @@ export class TerminalInstance implements ITerminalInstance { const innerWidth = width - marginLeft - marginRight; const innerHeight = height - bottom; - TerminalInstance._lastKnownDimensions = new dom.Dimension(innerWidth, innerHeight); - return TerminalInstance._lastKnownDimensions; + TerminalInstance._lastKnownCanvasDimensions = new dom.Dimension(innerWidth, innerHeight); + return TerminalInstance._lastKnownCanvasDimensions; } private async _getXtermConstructor(): Promise { @@ -1295,7 +1316,9 @@ export class TerminalInstance implements ITerminalInstance { if (cols !== this._xterm.cols || rows !== this._xterm.rows) { this._onDimensionsChanged.fire(); } + this._xterm.resize(cols, rows); + TerminalInstance._lastKnownGridDimensions = { cols, rows }; if (this._isVisible) { // HACK: Force the renderer to unpause by simulating an IntersectionObserver event. diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index 53144ef0683..dfd82834397 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -229,7 +229,7 @@ export interface ITerminalService { onInstanceDimensionsChanged: Event; onInstanceMaximumDimensionsChanged: Event; onInstanceRequestExtHostProcess: Event; - onInstanceRequestVirtualProcess: Event; + onInstanceRequestVirtualProcess: Event; onInstancesChanged: Event; onInstanceTitleChanged: Event; onActiveInstanceChanged: Event; @@ -297,7 +297,7 @@ export interface ITerminalService { extHostReady(remoteAuthority: string): void; requestExtHostProcess(proxy: ITerminalProcessExtHostProxy, shellLaunchConfig: IShellLaunchConfig, activeWorkspaceRootUri: URI, cols: number, rows: number, isWorkspaceShellAllowed: boolean): void; - requestVirtualProcess(proxy: ITerminalProcessExtHostProxy): void; + requestVirtualProcess(proxy: ITerminalProcessExtHostProxy, cols: number, rows: number): void; } /** @@ -767,6 +767,12 @@ export interface ITerminalProcessExtHostRequest { isWorkspaceShellAllowed: boolean; } +export interface ITerminalVirtualProcessRequest { + proxy: ITerminalProcessExtHostProxy; + cols: number; + rows: number; +} + export interface IAvailableShellsRequest { (shells: IShellDefinition[]): void; } diff --git a/src/vs/workbench/contrib/terminal/common/terminalProcessExtHostProxy.ts b/src/vs/workbench/contrib/terminal/common/terminalProcessExtHostProxy.ts index f551c553efb..0c44e01d94c 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalProcessExtHostProxy.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalProcessExtHostProxy.ts @@ -57,7 +57,7 @@ export class TerminalProcessExtHostProxy extends Disposable implements ITerminal // Request a process if needed, if this is a virtual process this step can be skipped as // there is no real "process" and we know it's ready on the ext host already. if (shellLaunchConfig.isVirtualProcess) { - this._terminalService.requestVirtualProcess(this); + this._terminalService.requestVirtualProcess(this, cols, rows); } else { remoteAgentService.getEnvironment().then(env => { if (!env) { diff --git a/src/vs/workbench/contrib/terminal/common/terminalService.ts b/src/vs/workbench/contrib/terminal/common/terminalService.ts index 6aed26e5885..fa335e234c4 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalService.ts @@ -8,7 +8,7 @@ import { Event, Emitter } from 'vs/base/common/event'; import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; -import { ITerminalService, ITerminalInstance, IShellLaunchConfig, ITerminalConfigHelper, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_VISIBLE, TERMINAL_PANEL_ID, ITerminalTab, ITerminalProcessExtHostProxy, ITerminalProcessExtHostRequest, KEYBINDING_CONTEXT_TERMINAL_IS_OPEN, ITerminalNativeService, IShellDefinition, IAvailableShellsRequest } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalService, ITerminalInstance, IShellLaunchConfig, ITerminalConfigHelper, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_FIND_WIDGET_VISIBLE, TERMINAL_PANEL_ID, ITerminalTab, ITerminalProcessExtHostProxy, ITerminalProcessExtHostRequest, KEYBINDING_CONTEXT_TERMINAL_IS_OPEN, ITerminalNativeService, IShellDefinition, IAvailableShellsRequest, ITerminalVirtualProcessRequest } from 'vs/workbench/contrib/terminal/common/terminal'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { URI } from 'vs/base/common/uri'; import { FindReplaceState } from 'vs/editor/contrib/find/findState'; @@ -55,8 +55,8 @@ export abstract class TerminalService implements ITerminalService { public get onInstanceProcessIdReady(): Event { return this._onInstanceProcessIdReady.event; } protected readonly _onInstanceRequestExtHostProcess = new Emitter(); public get onInstanceRequestExtHostProcess(): Event { return this._onInstanceRequestExtHostProcess.event; } - protected readonly _onInstanceRequestVirtualProcess = new Emitter(); - public get onInstanceRequestVirtualProcess(): Event { return this._onInstanceRequestVirtualProcess.event; } + protected readonly _onInstanceRequestVirtualProcess = new Emitter(); + public get onInstanceRequestVirtualProcess(): Event { return this._onInstanceRequestVirtualProcess.event; } protected readonly _onInstanceDimensionsChanged = new Emitter(); public get onInstanceDimensionsChanged(): Event { return this._onInstanceDimensionsChanged.event; } protected readonly _onInstanceMaximumDimensionsChanged = new Emitter(); @@ -144,9 +144,9 @@ export abstract class TerminalService implements ITerminalService { }); } - public requestVirtualProcess(proxy: ITerminalProcessExtHostProxy): void { + public requestVirtualProcess(proxy: ITerminalProcessExtHostProxy, cols: number, rows: number): void { // Don't need to wait on extensions here as this can only be triggered by an extension - this._onInstanceRequestVirtualProcess.fire(proxy); + this._onInstanceRequestVirtualProcess.fire({ proxy, cols, rows }); } public extHostReady(remoteAuthority: string): void { diff --git a/src/typings/getmac.d.ts b/src/vs/workbench/contrib/update/common/update.ts similarity index 69% rename from src/typings/getmac.d.ts rename to src/vs/workbench/contrib/update/common/update.ts index e93b8135456..8fc0d5c041b 100644 --- a/src/typings/getmac.d.ts +++ b/src/vs/workbench/contrib/update/common/update.ts @@ -3,10 +3,4 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -declare module getmac { - export function getMac(callback: (error: Error, macAddress: string) => void): void; -} - -declare module 'getmac' { - export = getmac; -} \ No newline at end of file +export const ShowCurrentReleaseNotesActionId = 'update.showCurrentReleaseNotes'; \ No newline at end of file diff --git a/src/vs/workbench/contrib/update/electron-browser/releaseNotesEditor.ts b/src/vs/workbench/contrib/update/electron-browser/releaseNotesEditor.ts index 273eaec4fce..b4803e191fa 100644 --- a/src/vs/workbench/contrib/update/electron-browser/releaseNotesEditor.ts +++ b/src/vs/workbench/contrib/update/electron-browser/releaseNotesEditor.ts @@ -26,6 +26,7 @@ import { KeybindingParser } from 'vs/base/common/keybindingParser'; import { CancellationToken } from 'vs/base/common/cancellation'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; +import { generateUuid } from 'vs/base/common/uuid'; function renderBody( body: string, @@ -91,6 +92,7 @@ export class ReleaseNotesManager { this._webviewEditorService.revealWebview(this._currentReleaseNotes, activeControl ? activeControl.group : this._editorGroupService.activeGroup, false); } else { this._currentReleaseNotes = this._webviewEditorService.createWebview( + generateUuid(), 'releaseNotes', title, { group: ACTIVE_GROUP, preserveFocus: false }, diff --git a/src/vs/workbench/contrib/update/electron-browser/update.ts b/src/vs/workbench/contrib/update/electron-browser/update.ts index 9ab8d2d859a..e56a8a3e64e 100644 --- a/src/vs/workbench/contrib/update/electron-browser/update.ts +++ b/src/vs/workbench/contrib/update/electron-browser/update.ts @@ -29,6 +29,7 @@ import { RawContextKey, IContextKey, IContextKeyService } from 'vs/platform/cont import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions'; import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { FalseContext } from 'vs/platform/contextkey/common/contextkeys'; +import { ShowCurrentReleaseNotesActionId } from 'vs/workbench/contrib/update/common/update'; const CONTEXT_UPDATE_STATE = new RawContextKey('updateState', StateType.Uninitialized); @@ -97,7 +98,7 @@ export class ShowReleaseNotesAction extends AbstractShowReleaseNotesAction { export class ShowCurrentReleaseNotesAction extends AbstractShowReleaseNotesAction { - static readonly ID = 'update.showCurrentReleaseNotes'; + static readonly ID = ShowCurrentReleaseNotesActionId; static LABEL = nls.localize('showReleaseNotes', "Show Release Notes"); constructor( diff --git a/src/vs/workbench/contrib/webview/browser/pre/index.html b/src/vs/workbench/contrib/webview/browser/pre/index.html index af7c52ebdac..ac53ce590e2 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/index.html +++ b/src/vs/workbench/contrib/webview/browser/pre/index.html @@ -4,7 +4,7 @@ + content="default-src 'none'; script-src 'self'; frame-src 'self'; style-src 'unsafe-inline'; worker-src 'self';" /> diff --git a/src/vs/workbench/contrib/webview/browser/pre/main.js b/src/vs/workbench/contrib/webview/browser/pre/main.js index 1dc234fe681..63585fc25c2 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/main.js +++ b/src/vs/workbench/contrib/webview/browser/pre/main.js @@ -367,7 +367,7 @@ // seeing the service worker applying properly. // Fake load an empty on the correct origin and then write real html // into it to get around this. - newFrame.src = `/fake.html?id=${ID}`; + newFrame.src = `./fake.html?id=${ID}`; } newFrame.style.cssText = 'display: block; margin: 0; overflow: hidden; position: absolute; width: 100%; height: 100%; visibility: hidden'; document.body.appendChild(newFrame); diff --git a/src/vs/workbench/contrib/webview/browser/pre/service-worker.js b/src/vs/workbench/contrib/webview/browser/pre/service-worker.js index 23f08be0281..8d26680d73a 100644 --- a/src/vs/workbench/contrib/webview/browser/pre/service-worker.js +++ b/src/vs/workbench/contrib/webview/browser/pre/service-worker.js @@ -4,10 +4,12 @@ *--------------------------------------------------------------------------------------------*/ const VERSION = 1; +const rootPath = self.location.pathname.replace(/\/service-worker.js$/, ''); + /** * Root path for resources */ -const resourceRoot = '/vscode-resource'; +const resourceRoot = rootPath + '/vscode-resource'; const resolveTimeout = 30000; @@ -179,7 +181,7 @@ async function processResourceRequest(event, requestUrl) { } const webviewId = getWebviewIdForClient(client); - const resourcePath = requestUrl.pathname.replace(resourceRoot, ''); + const resourcePath = requestUrl.pathname.startsWith(resourceRoot + '/') ? requestUrl.pathname.slice(resourceRoot.length) : requestUrl.pathname; function resolveResourceEntry(entry) { if (!entry) { @@ -269,6 +271,6 @@ async function getOuterIframeClient(webviewId) { const allClients = await self.clients.matchAll({ includeUncontrolled: true }); return allClients.find(client => { const clientUrl = new URL(client.url); - return clientUrl.pathname === '/' && clientUrl.search.match(new RegExp('\\bid=' + webviewId)); + return (clientUrl.pathname === `${rootPath}/` || clientUrl.pathname === `${rootPath}/index.html`) && clientUrl.search.match(new RegExp('\\bid=' + webviewId)); }); } \ No newline at end of file diff --git a/src/vs/workbench/contrib/webview/browser/webviewEditor.ts b/src/vs/workbench/contrib/webview/browser/webviewEditor.ts index 77a8253ff66..9dfa9721021 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewEditor.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewEditor.ts @@ -243,7 +243,7 @@ export class WebviewEditor extends BaseEditor { this.findWidgetVisible = KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE.bindTo(this._contextKeyService); } - this._webview = this._webviewService.createWebview( + this._webview = this._webviewService.createWebview(input.id, { allowSvgs: true, extension: input.extension, diff --git a/src/vs/workbench/contrib/webview/browser/webviewEditorInput.ts b/src/vs/workbench/contrib/webview/browser/webviewEditorInput.ts index 2b114064420..e882669a573 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewEditorInput.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewEditorInput.ts @@ -14,14 +14,13 @@ import { WebviewEvents, WebviewInputOptions } from './webviewEditorService'; import { Webview, WebviewOptions } from 'vs/workbench/contrib/webview/common/webview'; export class WebviewEditorInput extends EditorInput { - private static handlePool = 0; private static _styleElement?: HTMLStyleElement; - private static _icons = new Map(); + private static _icons = new Map(); private static updateStyleElement( - id: number, + id: string, iconPath: { light: URI, dark: URI } | undefined ) { if (!this._styleElement) { @@ -68,9 +67,9 @@ export class WebviewEditorInput extends EditorInput { readonly location: URI; readonly id: ExtensionIdentifier; }; - private readonly _id: number; constructor( + public readonly id: string, public readonly viewType: string, name: string, options: WebviewInputOptions, @@ -84,8 +83,6 @@ export class WebviewEditorInput extends EditorInput { ) { super(); - this._id = WebviewEditorInput.handlePool++; - this._name = name; this._options = options; this._events = events; @@ -120,7 +117,7 @@ export class WebviewEditorInput extends EditorInput { public getResource(): URI { return URI.from({ scheme: 'webview-panel', - path: `webview-panel/webview-${this._id}` + path: `webview-panel/webview-${this.id}` }); } @@ -147,7 +144,7 @@ export class WebviewEditorInput extends EditorInput { public set iconPath(value: { light: URI, dark: URI } | undefined) { this._iconPath = value; - WebviewEditorInput.updateStyleElement(this._id, value); + WebviewEditorInput.updateStyleElement(this.id, value); } public matches(other: IEditorInput): boolean { @@ -213,7 +210,7 @@ export class WebviewEditorInput extends EditorInput { public get container(): HTMLElement { if (!this._container) { this._container = document.createElement('div'); - this._container.id = `webview-${this._id}`; + this._container.id = `webview-${this.id}`; const part = this._layoutService.getContainer(Parts.EDITOR_PART); part.appendChild(this._container); } @@ -301,6 +298,7 @@ export class RevivedWebviewEditorInput extends WebviewEditorInput { private _revived: boolean = false; constructor( + id: string, viewType: string, name: string, options: WebviewInputOptions, @@ -313,7 +311,7 @@ export class RevivedWebviewEditorInput extends WebviewEditorInput { private readonly reviver: (input: WebviewEditorInput) => Promise, @IWorkbenchLayoutService partService: IWorkbenchLayoutService, ) { - super(viewType, name, options, state, events, extension, partService); + super(id, viewType, name, options, state, events, extension, partService); } public async resolve(): Promise { diff --git a/src/vs/workbench/contrib/webview/browser/webviewEditorInputFactory.ts b/src/vs/workbench/contrib/webview/browser/webviewEditorInputFactory.ts index 66f9f0b8e25..6c565b87ada 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewEditorInputFactory.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewEditorInputFactory.ts @@ -9,6 +9,7 @@ import { WebviewEditorInput } from './webviewEditorInput'; import { IWebviewEditorService, WebviewInputOptions } from './webviewEditorService'; import { URI, UriComponents } from 'vs/base/common/uri'; import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; +import { generateUuid } from 'vs/base/common/uuid'; interface SerializedIconPath { light: string | UriComponents; @@ -67,7 +68,7 @@ export class WebviewEditorInputFactory implements IEditorInputFactory { const extensionLocation = reviveUri(data.extensionLocation); const extensionId = data.extensionId ? new ExtensionIdentifier(data.extensionId) : undefined; const iconPath = reviveIconPath(data.iconPath); - return this._webviewService.reviveWebview(data.viewType, data.title, iconPath, data.state, data.options, extensionLocation ? { + return this._webviewService.reviveWebview(generateUuid(), data.viewType, data.title, iconPath, data.state, data.options, extensionLocation ? { location: extensionLocation, id: extensionId } : undefined, data.group); diff --git a/src/vs/workbench/contrib/webview/browser/webviewEditorService.ts b/src/vs/workbench/contrib/webview/browser/webviewEditorService.ts index 6064f07dd95..1a5fa997a1e 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewEditorService.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewEditorService.ts @@ -26,6 +26,7 @@ export interface IWebviewEditorService { _serviceBrand: any; createWebview( + id: string, viewType: string, title: string, showOptions: ICreateWebViewShowOptions, @@ -38,6 +39,7 @@ export interface IWebviewEditorService { ): WebviewEditorInput; reviveWebview( + id: string, viewType: string, title: string, iconPath: { light: URI, dark: URI } | undefined, @@ -133,6 +135,7 @@ export class WebviewEditorService implements IWebviewEditorService { ) { } public createWebview( + id: string, viewType: string, title: string, showOptions: ICreateWebViewShowOptions, @@ -143,7 +146,7 @@ export class WebviewEditorService implements IWebviewEditorService { }, events: WebviewEvents ): WebviewEditorInput { - const webviewInput = this._instantiationService.createInstance(WebviewEditorInput, viewType, title, options, {}, events, extension); + const webviewInput = this._instantiationService.createInstance(WebviewEditorInput, id, viewType, title, options, {}, events, extension); this._editorService.openEditor(webviewInput, { pinned: true, preserveFocus: showOptions.preserveFocus }, showOptions.group); return webviewInput; } @@ -164,6 +167,7 @@ export class WebviewEditorService implements IWebviewEditorService { } public reviveWebview( + id: string, viewType: string, title: string, iconPath: { light: URI, dark: URI } | undefined, @@ -175,7 +179,7 @@ export class WebviewEditorService implements IWebviewEditorService { }, group: number | undefined, ): WebviewEditorInput { - const webviewInput = this._instantiationService.createInstance(RevivedWebviewEditorInput, viewType, title, options, state, {}, extension, async (webview: WebviewEditorInput): Promise => { + const webviewInput = this._instantiationService.createInstance(RevivedWebviewEditorInput, id, viewType, title, options, state, {}, extension, async (webview: WebviewEditorInput): Promise => { const didRevive = await this.tryRevive(webview); if (didRevive) { return Promise.resolve(undefined); diff --git a/src/vs/workbench/contrib/webview/browser/webviewElement.ts b/src/vs/workbench/contrib/webview/browser/webviewElement.ts index ed7e22ab84d..4c202ecef2c 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewElement.ts @@ -32,11 +32,10 @@ export class IFrameWebview extends Disposable implements Webview { private content: WebviewContent; private _focused = false; - private readonly id: string; - private readonly _portMappingManager: WebviewPortMappingManager; constructor( + private readonly id: string, private _options: WebviewOptions, contentOptions: WebviewContentOptions, @IThemeService themeService: IThemeService, @@ -62,11 +61,9 @@ export class IFrameWebview extends Disposable implements Webview { state: undefined }; - this.id = `webview-${Date.now()}`; - this.element = document.createElement('iframe'); this.element.sandbox.add('allow-scripts', 'allow-same-origin'); - this.element.setAttribute('src', `${environmentService.webviewEndpoint}?id=${this.id}`); + this.element.setAttribute('src', `${this.endpoint}/index.html?id=${this.id}`); this.element.style.border = 'none'; this.element.style.width = '100%'; this.element.style.height = '100%'; @@ -144,6 +141,14 @@ export class IFrameWebview extends Disposable implements Webview { this._register(themeService.onThemeChange(this.style, this)); } + private get endpoint(): string { + const endpoint = this.environmentService.webviewEndpoint!.replace('{{uuid}}', this.id); + if (endpoint[endpoint.length - 1] === '/') { + return endpoint.slice(0, endpoint.length - 1); + } + return endpoint; + } + public mountTo(parent: HTMLElement) { if (this.element) { parent.appendChild(this.element); @@ -174,7 +179,7 @@ export class IFrameWebview extends Disposable implements Webview { private preprocessHtml(value: string): string { return value.replace(/(["'])vscode-resource:([^\s'"]+?)(["'])/gi, (_, startQuote, path, endQuote) => - `${startQuote}${this.environmentService.webviewEndpoint}/vscode-resource${path}${endQuote}`); + `${startQuote}${this.endpoint}/vscode-resource${path}${endQuote}`); } public update(html: string, options: WebviewContentOptions, retainContextWhenHidden: boolean) { diff --git a/src/vs/workbench/contrib/webview/browser/webviewService.ts b/src/vs/workbench/contrib/webview/browser/webviewService.ts index 58448a143cb..a4125927d7b 100644 --- a/src/vs/workbench/contrib/webview/browser/webviewService.ts +++ b/src/vs/workbench/contrib/webview/browser/webviewService.ts @@ -15,10 +15,12 @@ export class WebviewService implements IWebviewService { ) { } createWebview( + id: string, options: WebviewOptions, contentOptions: WebviewContentOptions ): Webview { return this._instantiationService.createInstance(WebviewElement, + id, options, contentOptions); } diff --git a/src/vs/workbench/contrib/webview/common/webview.ts b/src/vs/workbench/contrib/webview/common/webview.ts index bf459a3c694..bcc186c375e 100644 --- a/src/vs/workbench/contrib/webview/common/webview.ts +++ b/src/vs/workbench/contrib/webview/common/webview.ts @@ -26,6 +26,7 @@ export interface IWebviewService { _serviceBrand: any; createWebview( + id: string, options: WebviewOptions, contentOptions: WebviewContentOptions, ): Webview; diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewService.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewService.ts index e8ccaee1881..aa7ffc5d9bc 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewService.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewService.ts @@ -15,6 +15,7 @@ export class WebviewService implements IWebviewService { ) { } createWebview( + _id: string, options: WebviewOptions, contentOptions: WebviewContentOptions ): Webview { diff --git a/src/vs/workbench/contrib/welcome/gettingStarted/electron-browser/telemetryOptOut.ts b/src/vs/workbench/contrib/welcome/gettingStarted/electron-browser/telemetryOptOut.ts index 99693277ff1..78b36054376 100644 --- a/src/vs/workbench/contrib/welcome/gettingStarted/electron-browser/telemetryOptOut.ts +++ b/src/vs/workbench/contrib/welcome/gettingStarted/electron-browser/telemetryOptOut.ts @@ -13,7 +13,7 @@ import { URI } from 'vs/base/common/uri'; import { localize } from 'vs/nls'; import { onUnexpectedError } from 'vs/base/common/errors'; import { IWindowService, IWindowsService } from 'vs/platform/windows/common/windows'; -import { IExperimentService, ExperimentState } from 'vs/workbench/contrib/experiments/electron-browser/experimentService'; +import { IExperimentService, ExperimentState } from 'vs/workbench/contrib/experiments/common/experimentService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { language, locale } from 'vs/base/common/platform'; import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement'; diff --git a/src/vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc.ts b/src/vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc.ts index 6fd6dc821e8..518978b8983 100644 --- a/src/vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc.ts +++ b/src/vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { tmpdir } from 'os'; import { IChannel } from 'vs/base/parts/ipc/common/ipc'; import { IExtensionManagementService, ILocalExtension, IGalleryExtension, IExtensionGalleryService, InstallOperation } from 'vs/platform/extensionManagement/common/extensionManagement'; import { URI } from 'vs/base/common/uri'; @@ -79,8 +80,8 @@ export class RemoteExtensionManagementChannelClient extends ExtensionManagementC } private async downloadAndInstall(extension: IGalleryExtension, installed: ILocalExtension[]): Promise { - const location = await this.galleryService.download(extension, installed.filter(i => areSameExtensions(i.identifier, extension.identifier))[0] ? InstallOperation.Update : InstallOperation.Install); - return super.install(URI.file(location)); + const location = await this.galleryService.download(extension, URI.file(tmpdir()), installed.filter(i => areSameExtensions(i.identifier, extension.identifier))[0] ? InstallOperation.Update : InstallOperation.Install); + return super.install(location); } private async installUIDependenciesAndPackedExtensions(local: ILocalExtension): Promise { diff --git a/src/vs/workbench/services/extensions/node/extensionPoints.ts b/src/vs/workbench/services/extensions/node/extensionPoints.ts index 6a1083c003b..f6e5afbc6aa 100644 --- a/src/vs/workbench/services/extensions/node/extensionPoints.ts +++ b/src/vs/workbench/services/extensions/node/extensionPoints.ts @@ -13,7 +13,7 @@ import * as types from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; import * as pfs from 'vs/base/node/pfs'; import { getGalleryExtensionId, groupByExtension, ExtensionIdentifierWithVersion } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; -import { isValidExtensionVersion } from 'vs/platform/extensions/node/extensionValidator'; +import { isValidExtensionVersion } from 'vs/platform/extensions/common/extensionValidator'; import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { Translations, ILog } from 'vs/workbench/services/extensions/common/extensionPoints'; diff --git a/src/vs/workbench/services/request/browser/requestService.ts b/src/vs/workbench/services/request/browser/requestService.ts new file mode 100644 index 00000000000..dca97347c35 --- /dev/null +++ b/src/vs/workbench/services/request/browser/requestService.ts @@ -0,0 +1,48 @@ +/*--------------------------------------------------------------------------------------------- + * 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 { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { ILogService } from 'vs/platform/log/common/log'; +import { RequestChannelClient } from 'vs/platform/request/common/requestIpc'; +import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; +import { RequestService as BrowserRequestService } from 'vs/platform/request/browser/requestService'; + +export class RequestService extends BrowserRequestService { + + private readonly remoteRequestChannel: RequestChannelClient | null; + + constructor( + private readonly requestHandler: ((options: IRequestOptions) => Promise) | undefined, + @IRemoteAgentService remoteAgentService: IRemoteAgentService, + @IConfigurationService configurationService: IConfigurationService, + @ILogService logService: ILogService + ) { + super(configurationService, logService); + const connection = remoteAgentService.getConnection(); + this.remoteRequestChannel = connection ? new RequestChannelClient(connection.getChannel('request')) : null; + } + + async request(options: IRequestOptions, token: CancellationToken): Promise { + if (this.requestHandler) { + return this.requestHandler(options); + } + try { + const context = await super.request(options, token); + if (this.remoteRequestChannel && context.res.statusCode === 405) { + return this.remoteRequestChannel.request(options, token); + } + return context; + } catch (error) { + if (this.remoteRequestChannel) { + const result = await this.remoteRequestChannel.request(options, token); + return result; + } + throw error; + } + } + +} \ No newline at end of file diff --git a/src/vs/workbench/services/userData/common/inMemoryUserDataProvider.ts b/src/vs/workbench/services/userData/common/inMemoryUserDataProvider.ts index 9693eaa5e00..ffed9c53d53 100644 --- a/src/vs/workbench/services/userData/common/inMemoryUserDataProvider.ts +++ b/src/vs/workbench/services/userData/common/inMemoryUserDataProvider.ts @@ -4,48 +4,229 @@ *--------------------------------------------------------------------------------------------*/ import { Event, Emitter } from 'vs/base/common/event'; -import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; -import { IUserDataProvider, FileChangeEvent } from 'vs/workbench/services/userData/common/userData'; -import { VSBuffer } from 'vs/base/common/buffer'; -import { FileChangeType } from 'vs/platform/files/common/files'; +import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; +import * as resources from 'vs/base/common/resources'; +import { FileChangeType, IFileSystemProvider, FileType, IWatchOptions, IStat, FileSystemProviderErrorCode, FileSystemProviderError, FileWriteOptions, IFileChange, FileDeleteOptions, FileSystemProviderCapabilities, FileOverwriteOptions } from 'vs/platform/files/common/files'; +import { URI } from 'vs/base/common/uri'; -export class InMemoryUserDataProvider extends Disposable implements IUserDataProvider { - _serviceBrand: any; +class File implements IStat { - private _onDidChangeFile: Emitter = this._register(new Emitter()); - readonly onDidChangeFile: Event = this._onDidChangeFile.event; + type: FileType; + ctime: number; + mtime: number; + size: number; - private readonly store: Map = new Map(); + name: string; + data?: Uint8Array; - constructor() { - super(); - this._register(toDisposable(() => this.store.clear())); + constructor(name: string) { + this.type = FileType.File; + this.ctime = Date.now(); + this.mtime = Date.now(); + this.size = 0; + this.name = name; + } +} + +class Directory implements IStat { + + type: FileType; + ctime: number; + mtime: number; + size: number; + + name: string; + entries: Map; + + constructor(name: string) { + this.type = FileType.Directory; + this.ctime = Date.now(); + this.mtime = Date.now(); + this.size = 0; + this.name = name; + this.entries = new Map(); + } +} + +export type Entry = File | Directory; + +export class InMemoryUserDataProvider extends Disposable implements IFileSystemProvider { + + readonly capabilities: FileSystemProviderCapabilities = FileSystemProviderCapabilities.FileReadWrite; + readonly onDidChangeCapabilities: Event = Event.None; + + root = new Directory(''); + + // --- manage file metadata + + async stat(resource: URI): Promise { + return this._lookup(resource, false); } - async listFiles(path: string): Promise { - return []; - } - - async readFile(path: string): Promise { - if (this.store.has(path)) { - return VSBuffer.fromString(this.store.get(path)!).buffer; + async readdir(resource: URI): Promise<[string, FileType][]> { + const entry = this._lookupAsDirectory(resource, false); + let result: [string, FileType][] = []; + for (const [name, child] of entry.entries) { + result.push([name, child.type]); } - throw new Error(`Not Found: ${path}`); + return result; } - async writeFile(path: string, value: Uint8Array): Promise { - const exists = this.store.has(path); - const content = VSBuffer.wrap(value).toString(); - if (!exists || content !== this.store.get(path)) { - this.store.set(path, content); - this._onDidChangeFile.fire([{ path, type: exists ? FileChangeType.UPDATED : FileChangeType.ADDED }]); + // --- manage file contents + + async readFile(resource: URI): Promise { + const data = this._lookupAsFile(resource, false).data; + if (data) { + return data; } + throw new FileSystemProviderError('file not found', FileSystemProviderErrorCode.FileNotFound); } - async deleteFile(path: string): Promise { - if (this.store.has(path)) { - this.store.delete(path); - this._onDidChangeFile.fire([{ path, type: FileChangeType.DELETED }]); + async writeFile(resource: URI, content: Uint8Array, opts: FileWriteOptions): Promise { + let basename = resources.basename(resource); + let parent = this._lookupParentDirectory(resource); + let entry = parent.entries.get(basename); + if (entry instanceof Directory) { + throw new FileSystemProviderError('file is directory', FileSystemProviderErrorCode.FileIsADirectory); } + if (!entry && !opts.create) { + throw new FileSystemProviderError('file not found', FileSystemProviderErrorCode.FileNotFound); + } + if (entry && opts.create && !opts.overwrite) { + throw new FileSystemProviderError('file exists already', FileSystemProviderErrorCode.FileExists); + } + if (!entry) { + entry = new File(basename); + parent.entries.set(basename, entry); + this._fireSoon({ type: FileChangeType.ADDED, resource }); + } + entry.mtime = Date.now(); + entry.size = content.byteLength; + entry.data = content; + + this._fireSoon({ type: FileChangeType.UPDATED, resource }); + } + + // --- manage files/folders + + async rename(from: URI, to: URI, opts: FileOverwriteOptions): Promise { + if (!opts.overwrite && this._lookup(to, true)) { + throw new FileSystemProviderError('file exists already', FileSystemProviderErrorCode.FileExists); + } + + let entry = this._lookup(from, false); + let oldParent = this._lookupParentDirectory(from); + + let newParent = this._lookupParentDirectory(to); + let newName = resources.basename(to); + + oldParent.entries.delete(entry.name); + entry.name = newName; + newParent.entries.set(newName, entry); + + this._fireSoon( + { type: FileChangeType.DELETED, resource: from }, + { type: FileChangeType.ADDED, resource: to } + ); + } + + async delete(resource: URI, opts: FileDeleteOptions): Promise { + let dirname = resources.dirname(resource); + let basename = resources.basename(resource); + let parent = this._lookupAsDirectory(dirname, false); + if (!parent.entries.has(basename)) { + throw new FileSystemProviderError('file not found', FileSystemProviderErrorCode.FileNotFound); + } + parent.entries.delete(basename); + parent.mtime = Date.now(); + parent.size -= 1; + this._fireSoon({ type: FileChangeType.UPDATED, resource: dirname }, { resource, type: FileChangeType.DELETED }); + } + + async mkdir(resource: URI): Promise { + let basename = resources.basename(resource); + let dirname = resources.dirname(resource); + let parent = this._lookupAsDirectory(dirname, false); + + let entry = new Directory(basename); + parent.entries.set(entry.name, entry); + parent.mtime = Date.now(); + parent.size += 1; + this._fireSoon({ type: FileChangeType.UPDATED, resource: dirname }, { type: FileChangeType.ADDED, resource }); + } + + // --- lookup + + private _lookup(uri: URI, silent: false): Entry; + private _lookup(uri: URI, silent: boolean): Entry | undefined; + private _lookup(uri: URI, silent: boolean): Entry | undefined { + let parts = uri.path.split('/'); + let entry: Entry = this.root; + for (const part of parts) { + if (!part) { + continue; + } + let child: Entry | undefined; + if (entry instanceof Directory) { + child = entry.entries.get(part); + } + if (!child) { + if (!silent) { + throw new FileSystemProviderError('file not found', FileSystemProviderErrorCode.FileNotFound); + } else { + return undefined; + } + } + entry = child; + } + return entry; + } + + private _lookupAsDirectory(uri: URI, silent: boolean): Directory { + let entry = this._lookup(uri, silent); + if (entry instanceof Directory) { + return entry; + } + throw new FileSystemProviderError('file not a directory', FileSystemProviderErrorCode.FileNotADirectory); + } + + private _lookupAsFile(uri: URI, silent: boolean): File { + let entry = this._lookup(uri, silent); + if (entry instanceof File) { + return entry; + } + throw new FileSystemProviderError('file is a directory', FileSystemProviderErrorCode.FileIsADirectory); + } + + private _lookupParentDirectory(uri: URI): Directory { + const dirname = resources.dirname(uri); + return this._lookupAsDirectory(dirname, false); + } + + // --- manage file events + + private readonly _onDidChangeFile: Emitter = this._register(new Emitter()); + readonly onDidChangeFile: Event = this._onDidChangeFile.event; + + private _bufferedChanges: IFileChange[] = []; + private _fireSoonHandle?: NodeJS.Timer; + + + watch(resource: URI, opts: IWatchOptions): IDisposable { + // ignore, fires for all changes... + return Disposable.None; + } + + private _fireSoon(...changes: IFileChange[]): void { + this._bufferedChanges.push(...changes); + + if (this._fireSoonHandle) { + clearTimeout(this._fireSoonHandle); + } + + this._fireSoonHandle = setTimeout(() => { + this._onDidChangeFile.fire(this._bufferedChanges); + this._bufferedChanges.length = 0; + }, 5); } } \ No newline at end of file diff --git a/src/vs/workbench/services/userData/common/userData.ts b/src/vs/workbench/services/userData/common/userData.ts deleted file mode 100644 index 6ce93879fc3..00000000000 --- a/src/vs/workbench/services/userData/common/userData.ts +++ /dev/null @@ -1,80 +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 { Event } from 'vs/base/common/event'; -import { FileChangeType } from 'vs/platform/files/common/files'; - -/** - * The event user data providers must use to signal a file change. - */ -export interface FileChangeEvent { - - /** - * The type of change. - */ - readonly type: FileChangeType; - - /** - * The path of the file that has changed. - */ - readonly path: string; -} - -/** - * The userDataProvider is used to handle user specific application - * state like settings, keybindings, UI state (e.g. opened editors) and snippets. - * - * The API reflects a simple file system provider that comes with the notion of paths - * (UNIX slash separated) as well as files. Folders are not a top level concept (e.g. we - * do not require to create or delete them), however, files can be grouped beneath one path - * and also listed from that path. - * - * Example: - * ```ts - * await writeFile('snippets/global/markdown.json', ); - * await writeFile('snippets/global/html.json', ); - * await writeFile('snippets/global/javascript.json', ); - * - * const files = await listFiles('snippets/global'); - * console.log(files); // -> ['snippets/global/markdown.json', 'snippets/global/html.json', 'snippets/global/javascript.json'] - * ``` - */ -export interface IUserDataProvider { - - /** - * An event to signal that a file has been created, changed, or deleted. - */ - readonly onDidChangeFile: Event; - - /** - * Read the file contents of the given path. - * - * Throw an error if the path does not exist. - */ - readFile(path: string): Promise; - - /** - * Writes the provided content to the file path overwriting any existing content on that path. - * - * If the path does not exist, it will be created. - * - * Throw an error if the path is a parent to existing files. - */ - writeFile(path: string, content: Uint8Array): Promise; - - /** - * Delete the file at the given path. - * - * Does NOT throw an error when the path does not exist. - */ - deleteFile(path: string): Promise; - - /** - * Returns an array of files at the given path. - * - * Throw an error if the path does not exist or points to a file. - */ - listFiles(path: string): Promise; -} diff --git a/src/vs/workbench/workbench.main.ts b/src/vs/workbench/workbench.main.ts index 1d4bb760313..753464f354a 100644 --- a/src/vs/workbench/workbench.main.ts +++ b/src/vs/workbench/workbench.main.ts @@ -67,7 +67,7 @@ import { AccessibilityService } from 'vs/workbench/services/accessibility/node/a import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement'; 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 { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService'; 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'; @@ -257,7 +257,7 @@ import 'vs/workbench/contrib/webview/electron-browser/webview.contribution'; // Extensions Management import 'vs/workbench/contrib/extensions/electron-browser/extensions.contribution'; import 'vs/workbench/contrib/extensions/browser/extensionsQuickOpen'; -import 'vs/workbench/contrib/extensions/electron-browser/extensionsViewlet'; +import 'vs/workbench/contrib/extensions/browser/extensionsViewlet'; // Output Panel import 'vs/workbench/contrib/output/browser/output.contribution'; diff --git a/src/vs/workbench/workbench.web.api.ts b/src/vs/workbench/workbench.web.api.ts index ae193ae3e26..c2dc14709b6 100644 --- a/src/vs/workbench/workbench.web.api.ts +++ b/src/vs/workbench/workbench.web.api.ts @@ -7,6 +7,7 @@ import 'vs/workbench/workbench.web.main'; import { main } from 'vs/workbench/browser/web.main'; import { UriComponents } from 'vs/base/common/uri'; import { IFileSystemProvider } from 'vs/platform/files/common/files'; +import { IRequestOptions, IRequestContext } from 'vs/platform/request/common/request'; export interface IWorkbenchConstructionOptions { @@ -37,6 +38,12 @@ export interface IWorkbenchConstructionOptions { * state like settings, keybindings, UI state (e.g. opened editors) and snippets. */ userDataProvider?: IFileSystemProvider; + + /** + * Experimental: Optional request handler to handle http requests. + * In case not provided, workbench uses XMLHttpRequest. + */ + requestHandler?: (requestOptions: IRequestOptions) => Promise; } /** diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts index 60173e2f739..720b5e70ed1 100644 --- a/src/vs/workbench/workbench.web.main.ts +++ b/src/vs/workbench/workbench.web.main.ts @@ -63,11 +63,9 @@ import { ITextResourceConfigurationService } from 'vs/editor/common/services/res import { TextResourceConfigurationService } from 'vs/editor/common/services/resourceConfigurationImpl'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { BrowserAccessibilityService } from 'vs/platform/accessibility/common/accessibilityService'; -// import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement'; +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/common/request'; -import { RequestService } from 'vs/platform/request/browser/requestService'; +import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService'; import { BrowserLifecycleService } from 'vs/platform/lifecycle/browser/lifecycleService'; import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; @@ -155,8 +153,7 @@ registerSingleton(IModelService, ModelServiceImpl, true); registerSingleton(ITextResourceConfigurationService, TextResourceConfigurationService); registerSingleton(IAccessibilityService, BrowserAccessibilityService, true); registerSingleton(IContextViewService, ContextViewService, true); -// registerSingleton(IExtensionGalleryService, ExtensionGalleryService, true); -registerSingleton(IRequestService, RequestService, true); +registerSingleton(IExtensionGalleryService, ExtensionGalleryService, true); registerSingleton(ILifecycleService, BrowserLifecycleService); // registerSingleton(ILocalizationsService, LocalizationsService); // registerSingleton(ISharedProcessService, SharedProcessService, true); @@ -267,7 +264,7 @@ registerSingleton(IWebviewEditorService, WebviewEditorService, true); // Extensions Management // import 'vs/workbench/contrib/extensions/electron-browser/extensions.contribution'; // import 'vs/workbench/contrib/extensions/browser/extensionsQuickOpen'; -// import 'vs/workbench/contrib/extensions/electron-browser/extensionsViewlet'; +// import 'vs/workbench/contrib/extensions/browser/extensionsViewlet'; // Output Panel import 'vs/workbench/contrib/output/browser/output.contribution'; diff --git a/test/smoke/package.json b/test/smoke/package.json index 979eb8ee0a0..188a2e08253 100644 --- a/test/smoke/package.json +++ b/test/smoke/package.json @@ -35,5 +35,8 @@ "tmp": "0.0.33", "typescript": "2.9.2", "watch": "^1.0.2" + }, + "dependencies": { + "vscode-uri": "^2.0.3" } } diff --git a/test/smoke/src/main.ts b/test/smoke/src/main.ts index c0cf9f5d15b..945f109449f 100644 --- a/test/smoke/src/main.ts +++ b/test/smoke/src/main.ts @@ -156,7 +156,12 @@ async function setupRepository(): Promise { console.log('*** Copying test project repository:', opts['test-repo']); rimraf.sync(workspacePath); // not platform friendly - cp.execSync(`cp -R "${opts['test-repo']}" "${workspacePath}"`); + if (process.platform === 'win32') { + cp.execSync(`xcopy /E "${opts['test-repo']}" "${workspacePath}"\\*`); + } else { + cp.execSync(`cp -R "${opts['test-repo']}" "${workspacePath}"`); + } + } else { if (!fs.existsSync(workspacePath)) { console.log('*** Cloning test project repository...'); diff --git a/test/smoke/src/vscode/code.ts b/test/smoke/src/vscode/code.ts index 804b38a6c7e..4ccf2307d32 100644 --- a/test/smoke/src/vscode/code.ts +++ b/test/smoke/src/vscode/code.ts @@ -12,6 +12,7 @@ import { tmpName } from 'tmp'; import { IDriver, connect as connectDriver, IDisposable, IElement, Thenable } from './puppeteer-driver'; import { Logger } from '../logger'; import { ncp } from 'ncp'; +import { URI } from 'vscode-uri'; const repoPath = path.join(__dirname, '../../../..'); @@ -129,11 +130,8 @@ export async function spawn(options: SpawnOptions): Promise { if (options.remote) { // Replace workspace path with URI - args.shift(); - args.push( - `--${options.workspacePath.endsWith('.code-workspace') ? 'file' : 'folder'}-uri`, - `vscode-remote://test+test${options.workspacePath}`, - ); + args[0] = `--${options.workspacePath.endsWith('.code-workspace') ? 'file' : 'folder'}-uri=vscode-remote://test+test/${URI.file(options.workspacePath).path}`; + if (codePath) { // running against a build: copy the test resolver extension const testResolverExtPath = path.join(options.extensionsPath, 'vscode-test-resolver'); diff --git a/test/smoke/yarn.lock b/test/smoke/yarn.lock index ca28dd6bf19..4af77efee7c 100644 --- a/test/smoke/yarn.lock +++ b/test/smoke/yarn.lock @@ -2623,6 +2623,11 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" +vscode-uri@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.0.3.tgz#25e5f37f552fbee3cec7e5f80cef8469cefc6543" + integrity sha512-4D3DI3F4uRy09WNtDGD93H9q034OHImxiIcSq664Hq1Y1AScehlP3qqZyTkX/RWxeu0MRMHGkrxYqm2qlDF/aw== + watch@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/watch/-/watch-1.0.2.tgz#340a717bde765726fa0aa07d721e0147a551df0c" diff --git a/test/splitview/package.json b/test/splitview/package.json new file mode 100644 index 00000000000..d6ce0c37374 --- /dev/null +++ b/test/splitview/package.json @@ -0,0 +1,13 @@ +{ + "name": "splitview", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "devDependencies": { + "koa": "^2.5.1", + "koa-mount": "^3.0.0", + "koa-route": "^3.2.0", + "koa-static": "^5.0.0", + "mz": "^2.7.0" + } +} \ No newline at end of file diff --git a/test/splitview/public/index.html b/test/splitview/public/index.html new file mode 100644 index 00000000000..73ced374c02 --- /dev/null +++ b/test/splitview/public/index.html @@ -0,0 +1,82 @@ + + + + + Splitview + + + + +
+
+ + + + + + \ No newline at end of file diff --git a/test/splitview/server.js b/test/splitview/server.js new file mode 100644 index 00000000000..67f25363671 --- /dev/null +++ b/test/splitview/server.js @@ -0,0 +1,19 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +const fs = require('mz/fs'); +const path = require('path'); +const Koa = require('koa'); +const _ = require('koa-route'); +const serve = require('koa-static'); +const mount = require('koa-mount'); + +const app = new Koa(); + +app.use(serve('public')); +app.use(mount('/static', serve('../../out'))); + +app.listen(3000); +console.log('http://localhost:3000'); \ No newline at end of file diff --git a/test/splitview/yarn.lock b/test/splitview/yarn.lock new file mode 100644 index 00000000000..237201a684e --- /dev/null +++ b/test/splitview/yarn.lock @@ -0,0 +1,341 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +accepts@^1.2.2: + version "1.3.5" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" + integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I= + dependencies: + mime-types "~2.1.18" + negotiator "0.6.1" + +any-promise@^1.0.0, any-promise@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + +content-disposition@~0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" + integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ= + +content-type@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +cookies@~0.7.0: + version "0.7.1" + resolved "https://registry.yarnpkg.com/cookies/-/cookies-0.7.1.tgz#7c8a615f5481c61ab9f16c833731bcb8f663b99b" + integrity sha1-fIphX1SBxhq58WyDNzG8uPZjuZs= + dependencies: + depd "~1.1.1" + keygrip "~1.0.2" + +debug@*, debug@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@^2.6.1: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +deep-equal@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +depd@^1.1.0, depd@~1.1.1, depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +destroy@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +error-inject@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/error-inject/-/error-inject-1.0.0.tgz#e2b3d91b54aed672f309d950d154850fa11d4f37" + integrity sha1-4rPZG1Su1nLzCdlQ0VSFD6EdTzc= + +escape-html@~1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +fresh@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +http-assert@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.3.0.tgz#a31a5cf88c873ecbb5796907d4d6f132e8c01e4a" + integrity sha1-oxpc+IyHPsu1eWkH1NbxMujAHko= + dependencies: + deep-equal "~1.0.1" + http-errors "~1.6.1" + +http-errors@^1.2.8, http-errors@^1.6.3, http-errors@~1.6.1, http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +is-generator-function@^1.0.3: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.7.tgz#d2132e529bb0000a7f80794d4bdf5cd5e5813522" + integrity sha512-YZc5EwyO4f2kWCax7oegfuSr9mFz1ZvieNYBEjmukLxgXfBUbxAWGVF7GZf0zidYtoBl3WvC07YK0wT76a+Rtw== + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +keygrip@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/keygrip/-/keygrip-1.0.2.tgz#ad3297c557069dea8bcfe7a4fa491b75c5ddeb91" + integrity sha1-rTKXxVcGneqLz+ek+kkbdcXd65E= + +koa-compose@^3.0.0, koa-compose@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/koa-compose/-/koa-compose-3.2.1.tgz#a85ccb40b7d986d8e5a345b3a1ace8eabcf54de7" + integrity sha1-qFzLQLfZhtjlo0Wzoazo6rz1Tec= + dependencies: + any-promise "^1.1.0" + +koa-compose@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/koa-compose/-/koa-compose-4.1.0.tgz#507306b9371901db41121c812e923d0d67d3e877" + integrity sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw== + +koa-convert@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/koa-convert/-/koa-convert-1.2.0.tgz#da40875df49de0539098d1700b50820cebcd21d0" + integrity sha1-2kCHXfSd4FOQmNFwC1CCDOvNIdA= + dependencies: + co "^4.6.0" + koa-compose "^3.0.0" + +koa-is-json@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/koa-is-json/-/koa-is-json-1.0.0.tgz#273c07edcdcb8df6a2c1ab7d59ee76491451ec14" + integrity sha1-JzwH7c3Ljfaiwat9We52SRRR7BQ= + +koa-mount@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/koa-mount/-/koa-mount-3.0.0.tgz#08cab3b83d31442ed8b7e75c54b1abeb922ec197" + integrity sha1-CMqzuD0xRC7Yt+dcVLGr65IuwZc= + dependencies: + debug "^2.6.1" + koa-compose "^3.2.1" + +koa-route@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/koa-route/-/koa-route-3.2.0.tgz#76298b99a6bcfa9e38cab6fe5c79a8733e758bce" + integrity sha1-dimLmaa8+p44yrb+XHmocz51i84= + dependencies: + debug "*" + methods "~1.1.0" + path-to-regexp "^1.2.0" + +koa-send@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/koa-send/-/koa-send-5.0.0.tgz#5e8441e07ef55737734d7ced25b842e50646e7eb" + integrity sha512-90ZotV7t0p3uN9sRwW2D484rAaKIsD8tAVtypw/aBU+ryfV+fR2xrcAwhI8Wl6WRkojLUs/cB9SBSCuIb+IanQ== + dependencies: + debug "^3.1.0" + http-errors "^1.6.3" + mz "^2.7.0" + resolve-path "^1.4.0" + +koa-static@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/koa-static/-/koa-static-5.0.0.tgz#5e92fc96b537ad5219f425319c95b64772776943" + integrity sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ== + dependencies: + debug "^3.1.0" + koa-send "^5.0.0" + +koa@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/koa/-/koa-2.5.1.tgz#79f8b95f8d72d04fe9a58a8da5ebd6d341103f9c" + integrity sha512-cchwbMeG2dv3E2xTAmheDAuvR53tPgJZN/Hf1h7bTzJLSPcFZp8/t5+bNKJ6GaQZoydhZQ+1GNruhKdj3lIrug== + dependencies: + accepts "^1.2.2" + content-disposition "~0.5.0" + content-type "^1.0.0" + cookies "~0.7.0" + debug "*" + delegates "^1.0.0" + depd "^1.1.0" + destroy "^1.0.3" + error-inject "~1.0.0" + escape-html "~1.0.1" + fresh "^0.5.2" + http-assert "^1.1.0" + http-errors "^1.2.8" + is-generator-function "^1.0.3" + koa-compose "^4.0.0" + koa-convert "^1.2.0" + koa-is-json "^1.0.0" + mime-types "^2.0.7" + on-finished "^2.1.0" + only "0.0.2" + parseurl "^1.3.0" + statuses "^1.2.0" + type-is "^1.5.5" + vary "^1.0.0" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +methods@~1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +mime-db@~1.33.0: + version "1.33.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" + integrity sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ== + +mime-types@^2.0.7, mime-types@~2.1.18: + version "2.1.18" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" + integrity sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ== + dependencies: + mime-db "~1.33.0" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +mz@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + +negotiator@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" + integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= + +object-assign@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +on-finished@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +only@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4" + integrity sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q= + +parseurl@^1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" + integrity sha1-/CidTtiZMRlGDBViUyYs3I3mW/M= + +path-is-absolute@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-to-regexp@^1.2.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" + integrity sha1-Wf3g9DW62suhA6hOnTvGTpa5k30= + dependencies: + isarray "0.0.1" + +resolve-path@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/resolve-path/-/resolve-path-1.4.0.tgz#c4bda9f5efb2fce65247873ab36bb4d834fe16f7" + integrity sha1-xL2p9e+y/OZSR4c6s2u02DT+Fvc= + dependencies: + http-errors "~1.6.2" + path-is-absolute "1.0.1" + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +"statuses@>= 1.4.0 < 2", statuses@^1.2.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY= + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.0" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839" + integrity sha1-5p44obq+lpsBCCB5eLn2K4hgSDk= + dependencies: + any-promise "^1.0.0" + +type-is@^1.5.5: + version "1.6.16" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" + integrity sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.18" + +vary@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= diff --git a/yarn.lock b/yarn.lock index d47dd07a343..4c46dae4c82 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2421,14 +2421,6 @@ each-props@^1.3.0: is-plain-object "^2.0.1" object.defaults "^1.1.0" -eachr@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/eachr/-/eachr-3.2.0.tgz#2c35e43ea086516f7997cf80b7aa64d55a4a4484" - integrity sha1-LDXkPqCGUW95l8+At6pk1VpKRIQ= - dependencies: - editions "^1.1.1" - typechecker "^4.3.0" - ecc-jsbn@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" @@ -2446,11 +2438,6 @@ ecstatic@^3.0.0: minimist "^1.1.0" url-join "^2.0.5" -editions@^1.1.1, editions@^1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/editions/-/editions-1.3.4.tgz#3662cb592347c3168eb8e498a0ff73271d67f50b" - integrity sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg== - editorconfig@^0.15.0: version "0.15.0" resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.15.0.tgz#b6dd4a0b6b9e76ce48e066bdc15381aebb8804fd" @@ -3078,15 +3065,6 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" -extract-opts@^3.2.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/extract-opts/-/extract-opts-3.3.1.tgz#5abbedc98c0d5202e3278727f9192d7e086c6be1" - integrity sha1-WrvtyYwNUgLjJ4cn+Rktfghsa+E= - dependencies: - eachr "^3.2.0" - editions "^1.1.1" - typechecker "^4.3.0" - extract-zip@^1.6.5: version "1.6.6" resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.6.tgz#1290ede8d20d0872b429fd3f351ca128ec5ef85c" @@ -3589,14 +3567,6 @@ get-value@^2.0.3, get-value@^2.0.6: resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= -getmac@1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/getmac/-/getmac-1.4.1.tgz#cfefcb3ee7d7a73cba5292129cb100c19afbe17a" - integrity sha512-mQp+8D+grQX0gG8EJn6VfH0PxE56ZKNsTguOMxPShAiVk9lvH8Ey36eXepG705Ac1HCsvaSrQ/6bPHZ0++F/Mg== - dependencies: - editions "^1.3.4" - extract-opts "^3.2.0" - getpass@^0.1.1: version "0.1.7" resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" @@ -9121,13 +9091,6 @@ type-is@~1.6.15: media-typer "0.3.0" mime-types "~2.1.15" -typechecker@^4.3.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/typechecker/-/typechecker-4.5.0.tgz#c382920097812364bbaf4595b0ab6588244117a6" - integrity sha512-bqPE/ck3bVIaXP7gMKTKSHrypT32lpYTpiqzPYeYzdSQnmaGvaGhy7TnN/M/+5R+2rs/kKcp9ZLPRp/Q9Yj+4w== - dependencies: - editions "^1.3.4" - typed-rest-client@^0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/typed-rest-client/-/typed-rest-client-0.9.0.tgz#f768cc0dc3f4e950f06e04825c36b3e7834aa1f2"