Merge remote-tracking branch 'origin/main' into tyriar/116113

This commit is contained in:
Daniel Imms 2021-08-11 06:27:38 -07:00
commit 3246b3ec18
1047 changed files with 14754 additions and 10437 deletions

View file

@ -578,7 +578,8 @@
"vscode-oniguruma",
"iconv-lite-umd",
"jschardet",
"@vscode/vscode-languagedetection"
"@vscode/vscode-languagedetection",
"@microsoft/applicationinsights-web"
]
},
{

View file

@ -14,3 +14,8 @@ ae1452eea678f5266ef513f22dacebb90955d6c9
# joaomoreno: add ghooks dev dependency
0dfc06e0f9de5925de792cdf9f0e6597bb25908f
# mjbvz: organize imports
494cbbd02d67e87727ec885f98d19551aa33aad1
a3cb14be7f2cceadb17adf843675b1a59537dbbd
ee1655a82ebdfd38bf8792088a6602c69f7bbd94

View file

@ -5,7 +5,7 @@
"JacksonKearl": {"accuracy": 0.5}
},
"labels": {
"L10N": {"assign": []},
"L10N": {"assign": ["TylerLeonhardt", "csigs"]},
"VIM": {"assign": []},
"accessibility": { "assign": ["isidorn", "sana-ajani"]},
"api": {"assign": ["jrieken"]},
@ -64,12 +64,12 @@
"extensions": {"assign": ["sandy081"]},
"extensions-development": {"assign": []},
"file-decorations": {"assign": ["jrieken"]},
"file-encoding": {"assign": []},
"file-encoding": {"assign": ["bpasero"]},
"file-explorer": {"assign": ["isidorn"]},
"file-glob": {"assign": []},
"file-guess-encoding": {"assign": []},
"file-io": {"assign": []},
"file-watcher": {"assign": []},
"file-guess-encoding": {"assign": ["bpasero"]},
"file-io": {"assign": ["bpasero"]},
"file-watcher": {"assign": ["bpasero"]},
"font-rendering": {"assign": []},
"formatting": {"assign": []},
"git": {"assign": ["eamodio"]},
@ -150,31 +150,31 @@
"ux": {"assign": ["misolori"]},
"variable-resolving": {"assign": []},
"vscode-build": {"assign": []},
"web": {"assign": []},
"web": {"assign": ["bpasero"]},
"webview": {"assign": ["mjbvz"]},
"workbench-cli": {"assign": []},
"workbench-diagnostics": {"assign": ["Tyriar"]},
"workbench-dnd": {"assign": []},
"workbench-dnd": {"assign": ["bpasero"]},
"workbench-editor-grid": {"assign": ["sbatten"]},
"workbench-editors": {"assign": []},
"workbench-editors": {"assign": ["bpasero"]},
"workbench-electron": {"assign": ["deepak1556"]},
"workbench-feedback": {"assign": []},
"workbench-history": {"assign": []},
"workbench-feedback": {"assign": ["bpasero"]},
"workbench-history": {"assign": ["bpasero"]},
"workbench-hot-exit": {"assign": []},
"workbench-launch": {"assign": []},
"workbench-link": {"assign": []},
"workbench-multiroot": {"assign": []},
"workbench-notifications": {"assign": []},
"workbench-multiroot": {"assign": ["bpasero"]},
"workbench-notifications": {"assign": ["bpasero"]},
"workbench-os-integration": {"assign": []},
"workbench-rapid-render": {"assign": ["jrieken"]},
"workbench-run-as-admin": {"assign": []},
"workbench-state": {"assign": []},
"workbench-status": {"assign": []},
"workbench-tabs": {"assign": []},
"workbench-touchbar": {"assign": []},
"workbench-state": {"assign": ["bpasero"]},
"workbench-status": {"assign": ["bpasero"]},
"workbench-tabs": {"assign": ["bpasero"]},
"workbench-touchbar": {"assign": ["bpasero"]},
"workbench-views": {"assign": ["sbatten"]},
"workbench-welcome": {"assign": ["JacksonKearl"]},
"workbench-window": {"assign": []},
"workbench-window": {"assign": ["bpasero"]},
"workbench-zen": {"assign": ["isidorn"]},
"workspace-edit": {"assign": ["jrieken"]},
"workspace-symbols": {"assign": []},

15
.github/commands.json vendored
View file

@ -15,7 +15,7 @@
"type": "label",
"name": "*question",
"action": "close",
"comment": "Please ask your question on [StackOverflow](https://aka.ms/vscodestackoverflow). We have a great community over [there](https://aka.ms/vscodestackoverflow). They have already answered thousands of questions and are happy to answer yours as well. See also our [issue reporting](https://aka.ms/vscodeissuereporting) guidelines.\n\nHappy Coding!"
"comment": "We closed this issue because it is a question about using VS Code rather than an issue or feature request. Please search for help on [StackOverflow](https://aka.ms/vscodestackoverflow), where the community has already answered thousands of similar questions. You may find their [guide on asking a new question](https://aka.ms/vscodestackoverflowquestion) helpful if your question has not already been asked. See also our [issue reporting](https://aka.ms/vscodeissuereporting) guidelines.\n\nHappy Coding!"
},
{
"type": "label",
@ -68,7 +68,17 @@
{
"type": "label",
"name": "notebook",
"assign": ["rebornix"]
"assign": [
"rebornix"
]
},
{
"type": "label",
"name": "L10N",
"assign": [
"csigs",
"TylerLeonhardt"
]
},
{
"type": "comment",
@ -402,6 +412,7 @@
"comment": "Thanks for reporting this issue! Unfortunately, it's hard for us to understand what issue you're seeing. Please help us out by providing a screen recording showing exactly what isn't working as expected. While we can work with most standard formats, `.gif` files are preferred as they are displayed inline on GitHub. You may find https://gifcap.dev helpful as a browser-based gif recording tool.\n\nIf the issue depends on keyboard input, you can help us by enabling screencast mode for the recording (`Developer: Toggle Screencast Mode` in the command palette).\n\nHappy coding!"
},
{
"__comment__": "Allows folks on the team to label issues by commenting: `\\label My-Label` ",
"type": "comment",
"name": "label",
"allowUsers": []

View file

@ -188,6 +188,14 @@ jobs:
- name: Compile and Download
run: yarn npm-run-all --max_old_space_size=4095 -lp compile "electron x64" playwright-install download-builtin-extensions
# This is required for keytar unittests, otherwise we hit
# https://github.com/atom/node-keytar/issues/76
- name: Create temporary keychain
run: |
security create-keychain -p pwd $RUNNER_TEMP/buildagent.keychain
security default-keychain -s $RUNNER_TEMP/buildagent.keychain
security unlock-keychain -p pwd $RUNNER_TEMP/buildagent.keychain
- name: Run Unit Tests (Electron)
run: DISPLAY=:10 ./scripts/test.sh

View file

@ -1,5 +1,6 @@
name: "Rich Navigation Indexing"
on:
workflow_dispatch:
pull_request:
push:
branches:
@ -33,5 +34,6 @@ jobs:
with:
languages: typescript
repo-token: ${{ secrets.GITHUB_TOKEN }}
typescriptVersion: 0.6.0-dev.1
typescriptVersion: 0.6.0-next.16
configFiles: .lsifrc.json
continue-on-error: true

8
.vscode/launch.json vendored
View file

@ -185,7 +185,6 @@
"name": "Attach to VS Code",
"browserAttachLocation": "workspace",
"port": 9222,
"trace": true,
"outFiles": [
"${workspaceFolder}/out/**/*.js"
],
@ -198,7 +197,6 @@
"type": "pwa-chrome",
"request": "launch",
"name": "Launch VS Code Internal",
"trace": true,
"windows": {
"runtimeExecutable": "${workspaceFolder}/scripts/code.bat"
},
@ -245,15 +243,17 @@
}
},
{
"type": "node",
"type": "pwa-node",
"request": "launch",
"name": "Main Process",
"attachSimplePort": 5875,
"runtimeExecutable": "${workspaceFolder}/scripts/code.sh",
"windows": {
"runtimeExecutable": "${workspaceFolder}/scripts/code.bat",
},
"runtimeArgs": [
"--no-cached-data"
"--inspect-brk=5875",
"--no-cached-data",
],
"outFiles": [
"${workspaceFolder}/out/**/*.js"

View file

@ -7,7 +7,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$repo=repo:microsoft/vscode\n$milestone=milestone:\"July 2021\""
"value": "$repo=repo:microsoft/vscode\n$milestone=milestone:\"August 2021\""
},
{
"kind": 1,

View file

@ -7,7 +7,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-js-debug repo:microsoft/vscode-remote-release repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-remotehub\n\n$MILESTONE=milestone:\"June 2021\""
"value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-js-debug repo:microsoft/vscode-remote-release repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-remotehub\n\n$MILESTONE=milestone:\"July 2021\""
},
{
"kind": 1,

View file

@ -7,7 +7,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-js-debug repo:microsoft/vscode-remote-release repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remotehub\n\n$MILESTONE=milestone:\"June 2021\"\n\n$MINE=assignee:@me"
"value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-js-debug repo:microsoft/vscode-remote-release repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remotehub repo:microsoft/vscode-emmet-helper\n\n$MILESTONE=milestone:\"July 2021\"\n\n$MINE=assignee:@me"
},
{
"kind": 1,

View file

@ -12,7 +12,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$repos=repo:microsoft/vscode repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks \n$milestone=milestone:\"June 2021\""
"value": "$repos=repo:microsoft/vscode repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-jupyter repo:microsoft/vscode-python\r\n$milestone=milestone:\"July 2021\""
},
{
"kind": 1,

View file

@ -1,3 +1,3 @@
disturl "https://electronjs.org/headers"
target "13.1.7"
target "13.1.8"
runtime "electron"

View file

@ -7,7 +7,7 @@ This project incorporates components from the projects listed below. The origina
1. atom/language-clojure version 0.22.7 (https://github.com/atom/language-clojure)
2. atom/language-coffee-script version 0.49.3 (https://github.com/atom/language-coffee-script)
3. atom/language-css version 0.44.4 (https://github.com/atom/language-css)
3. atom/language-css version 0.44.6 (https://github.com/atom/language-css)
4. atom/language-java version 0.32.1 (https://github.com/atom/language-java)
5. atom/language-sass version 0.62.1 (https://github.com/atom/language-sass)
6. atom/language-shellscript version 0.26.0 (https://github.com/atom/language-shellscript)
@ -25,7 +25,7 @@ This project incorporates components from the projects listed below. The origina
18. fadeevab/make.tmbundle (https://github.com/fadeevab/make.tmbundle)
19. freebroccolo/atom-language-swift (https://github.com/freebroccolo/atom-language-swift)
20. HTML 5.1 W3C Working Draft version 08 October 2015 (http://www.w3.org/TR/2015/WD-html51-20151008/)
21. Ikuyadeu/vscode-R version 1.6.7 (https://github.com/Ikuyadeu/vscode-R)
21. Ikuyadeu/vscode-R version 2.0.0 (https://github.com/Ikuyadeu/vscode-R)
22. insane version 2.6.2 (https://github.com/bevacqua/insane)
23. Ionic documentation version 1.2.4 (https://github.com/ionic-team/ionic-site)
24. ionide/ionide-fsgrammar (https://github.com/ionide/ionide-fsgrammar)
@ -33,7 +33,7 @@ This project incorporates components from the projects listed below. The origina
26. jeff-hykin/cpp-textmate-grammar version 1.12.11 (https://github.com/jeff-hykin/cpp-textmate-grammar)
27. jeff-hykin/cpp-textmate-grammar version 1.15.5 (https://github.com/jeff-hykin/cpp-textmate-grammar)
28. js-beautify version 1.6.8 (https://github.com/beautify-web/js-beautify)
29. JuliaEditorSupport/atom-language-julia version 0.21.0 (https://github.com/JuliaEditorSupport/atom-language-julia)
29. JuliaEditorSupport/atom-language-julia version 0.21.1 (https://github.com/JuliaEditorSupport/atom-language-julia)
30. Jxck/assert version 1.0.0 (https://github.com/Jxck/assert)
31. language-docker (https://github.com/moby/moby)
32. language-less version 0.34.2 (https://github.com/atom/language-less)
@ -687,7 +687,7 @@ END OF HTML 5.1 W3C Working Draft NOTICES AND INFORMATION
=========================================
MIT License
Copyright (c) 2019 Yuki Ueda
Copyright (c) 2021 REditorSupport
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View file

@ -1 +1 @@
2021-05-26T10:17:08.678Z
2021-08-06T01:18:33.387Z

View file

@ -0,0 +1,21 @@
{
"codebaseName": "vscode-client",
"ppe": false,
"notificationAliases": [
"sbatten@microsoft.com"
],
"codebaseAdmins": [
"REDMOND\\stbatt",
"REDMOND\\monacotools",
],
"instanceUrl": "https://msazure.visualstudio.com/defaultcollection",
"projectName": "One",
"areaPath": "One\\VSCode\\Client",
"iterationPath": "One",
"notifyAlways": true,
"tools": [
"BinSkim",
"CredScan",
"CodeQL"
]
}

View file

@ -224,7 +224,7 @@ steps:
set -e
APP_ROOT=$(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH)
APP_NAME="`ls $APP_ROOT | head -n 1`"
yarn smoketest-no-compile --build "$APP_ROOT/$APP_NAME"
yarn smoketest-no-compile --build "$APP_ROOT/$APP_NAME" --screenshots .build/logs/smoke-tests
timeoutInMinutes: 5
displayName: Run smoke tests (Electron)
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
@ -234,7 +234,7 @@ steps:
APP_ROOT=$(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH)
APP_NAME="`ls $APP_ROOT | head -n 1`"
VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-darwin" \
yarn smoketest-no-compile --build "$APP_ROOT/$APP_NAME" --remote
yarn smoketest-no-compile --build "$APP_ROOT/$APP_NAME" --remote --screenshots .build/logs/smoke-tests
timeoutInMinutes: 5
displayName: Run smoke tests (Remote)
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false'))

View file

@ -67,14 +67,32 @@ steps:
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), eq(variables['ENABLE_TERRAPIN'], 'true'))
displayName: Switch to Terrapin packages
- script: |
set -e
yarn --cwd build
yarn --cwd build compile
displayName: Compile build tools
- script: |
set -e
export npm_config_arch=$(NPM_ARCH)
export npm_config_build_from_source=true
if [ -z "$CC" ] || [ -z "$CXX" ]; then
export CC=$(which gcc-5)
export CXX=$(which g++-5)
# Download clang based on chromium revision used by vscode
curl -s https://raw.githubusercontent.com/chromium/chromium/91.0.4472.124/tools/clang/scripts/update.py | python - --output-dir=$PWD/.build/CR_Clang --host-os=linux
# Download libcxx headers and objects from upstream electron releases
DEBUG=libcxx-fetcher \
VSCODE_LIBCXX_OBJECTS_DIR=$PWD/.build/libcxx-objects \
VSCODE_LIBCXX_HEADERS_DIR=$PWD/.build/libcxx_headers \
VSCODE_LIBCXXABI_HEADERS_DIR=$PWD/.build/libcxxabi_headers \
VSCODE_ARCH="$(NPM_ARCH)" \
node build/linux/libcxx-fetcher.js
# Set compiler toolchain
export CC=$PWD/.build/CR_Clang/bin/clang
export CXX=$PWD/.build/CR_Clang/bin/clang++
export CXXFLAGS="-nostdinc++ -D_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS -isystem$PWD/.build/libcxx_headers/include -isystem$PWD/.build/libcxxabi_headers/include -fPIC -flto=thin -fsplit-lto-unit"
export LDFLAGS="-stdlib=libc++ -fuse-ld=lld -flto=thin -fsplit-lto-unit -L$PWD/.build/libcxx-objects -lc++abi"
fi
if [ "$VSCODE_ARCH" == "x64" ]; then
@ -194,7 +212,7 @@ steps:
- script: |
set -e
APP_PATH=$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)
yarn smoketest-no-compile --build "$APP_PATH" --electronArgs="--disable-dev-shm-usage --use-gl=swiftshader"
yarn smoketest-no-compile --build "$APP_PATH" --electronArgs="--disable-dev-shm-usage --use-gl=swiftshader" --screenshots .build/logs/smoke-tests
timeoutInMinutes: 5
displayName: Run smoke tests (Electron)
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
@ -203,7 +221,7 @@ steps:
set -e
APP_PATH=$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)
VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-linux-$(VSCODE_ARCH)" \
yarn smoketest-no-compile --build "$APP_PATH" --remote --electronArgs="--disable-dev-shm-usage --use-gl=swiftshader"
yarn smoketest-no-compile --build "$APP_PATH" --remote --electronArgs="--disable-dev-shm-usage --use-gl=swiftshader" --screenshots .build/logs/smoke-tests
timeoutInMinutes: 5
displayName: Run smoke tests (Remote)
condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false'))

View file

@ -0,0 +1,225 @@
trigger: none
pr: none
parameters:
- name: ENABLE_TERRAPIN
displayName: "Enable Terrapin"
type: boolean
default: true
- name: SCAN_WINDOWS
displayName: "Scan Windows"
type: boolean
default: true
- name: SCAN_LINUX
displayName: "Scan Linux"
type: boolean
default: false
variables:
- name: ENABLE_TERRAPIN
value: ${{ eq(parameters.ENABLE_TERRAPIN, true) }}
- name: SCAN_WINDOWS
value: ${{ eq(parameters.SCAN_WINDOWS, true) }}
- name: SCAN_LINUX
value: ${{ eq(parameters.SCAN_LINUX, true) }}
- name: VSCODE_MIXIN_REPO
value: microsoft/vscode-distro
- name: skipComponentGovernanceDetection
value: true
- name: NPM_ARCH
value: x64
- name: VSCODE_ARCH
value: x64
stages:
- stage: Windows
condition: eq(variables.SCAN_WINDOWS, 'true')
pool:
vmImage: VS2017-Win2016
jobs:
- job: WindowsJob
timeoutInMinutes: 0
steps:
- task: CredScan@3
continueOnError: true
inputs:
scanFolder: '$(Build.SourcesDirectory)'
outputFormat: 'pre'
- task: NodeTool@0
inputs:
versionSpec: "14.x"
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2
inputs:
versionSpec: "1.x"
- task: AzureKeyVault@1
displayName: "Azure Key Vault: Get Secrets"
inputs:
azureSubscription: "vscode-builds-subscription"
KeyVaultName: vscode
SecretsFilter: "github-distro-mixin-password,ESRP-SSL-AADAuth,vscode-storage-key,builds-docdb-key-readwrite"
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
"machine github.com`nlogin vscode`npassword $(github-distro-mixin-password)" | Out-File "$env:USERPROFILE\_netrc" -Encoding ASCII
exec { git config user.email "vscode@microsoft.com" }
exec { git config user.name "VSCode" }
displayName: Prepare tooling
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro") }
displayName: Merge distro
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { npx https://aka.ms/enablesecurefeed standAlone }
timeoutInMinutes: 5
condition: and(succeeded(), eq(variables['ENABLE_TERRAPIN'], 'true'))
displayName: Switch to Terrapin packages
- task: Semmle@1
inputs:
sourceCodeDirectory: '$(Build.SourcesDirectory)'
language: 'cpp'
buildCommandsString: 'yarn --frozen-lockfile'
querySuite: 'Required'
timeout: '1800'
ram: '16384'
addProjectDirToScanningExclusionList: true
env:
npm_config_arch: "$(NPM_ARCH)"
npm_config_build_from_source: true
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
GITHUB_TOKEN: "$(github-distro-mixin-password)"
displayName: CodeQL
- powershell: |
. build/azure-pipelines/win32/exec.ps1
. build/azure-pipelines/win32/retry.ps1
$ErrorActionPreference = "Stop"
$env:npm_config_arch="$(NPM_ARCH)"
$env:npm_config_build_from_source="true"
$env:CHILD_CONCURRENCY="1"
retry { exec { yarn --frozen-lockfile } }
env:
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
GITHUB_TOKEN: "$(github-distro-mixin-password)"
displayName: Install dependencies
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { yarn gulp "vscode-symbols-win32-$(VSCODE_ARCH)" }
displayName: Download Symbols
- task: BinSkim@4
inputs:
InputType: 'Basic'
Function: 'analyze'
TargetPattern: 'guardianGlob'
AnalyzeTargetGlob: '$(agent.builddirectory)\scanbin\**.dll;$(agent.builddirectory)\scanbin\**.exe;$(agent.builddirectory)\scanbin\**.node'
AnalyzeLocalSymbolDirectories: '$(agent.builddirectory)\scanbin\VSCode-win32-$(VSCODE_ARCH)\pdb'
- task: TSAUpload@2
inputs:
GdnPublishTsaOnboard: true
GdnPublishTsaConfigFile: '$(Build.SourcesDirectory)\build\azure-pipelines\.gdntsa'
- stage: Linux
dependsOn: []
condition: eq(variables.SCAN_LINUX, 'true')
pool:
vmImage: "Ubuntu-18.04"
jobs:
- job: LinuxJob
steps:
- task: CredScan@2
inputs:
toolMajorVersion: 'V2'
- task: NodeTool@0
inputs:
versionSpec: "14.x"
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@2
inputs:
versionSpec: "1.x"
- task: AzureKeyVault@1
displayName: "Azure Key Vault: Get Secrets"
inputs:
azureSubscription: "vscode-builds-subscription"
KeyVaultName: vscode
SecretsFilter: "github-distro-mixin-password,ESRP-SSL-AADAuth,vscode-storage-key,builds-docdb-key-readwrite"
- 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 pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro")
displayName: Merge distro
- script: |
set -e
npx https://aka.ms/enablesecurefeed standAlone
timeoutInMinutes: 5
condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), eq(variables['ENABLE_TERRAPIN'], 'true'))
displayName: Switch to Terrapin packages
- script: |
set -e
export npm_config_arch=$(NPM_ARCH)
export npm_config_build_from_source=true
if [ -z "$CC" ] || [ -z "$CXX" ]; then
export CC=$(which gcc-5)
export CXX=$(which g++-5)
fi
if [ "$VSCODE_ARCH" == "x64" ]; then
export VSCODE_REMOTE_CC=$(which gcc-4.8)
export VSCODE_REMOTE_CXX=$(which g++-4.8)
fi
for i in {1..3}; do # try 3 times, for Terrapin
yarn --frozen-lockfile && break
if [ $i -eq 3 ]; then
echo "Yarn failed too many times" >&2
exit 1
fi
echo "Yarn failed $i, trying again..."
done
env:
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
GITHUB_TOKEN: "$(github-distro-mixin-password)"
displayName: Install dependencies
- script: |
set -e
yarn gulp vscode-symbols-linux-$(VSCODE_ARCH)
displayName: Build
- task: BinSkim@3
inputs:
toolVersion: Latest
InputType: CommandLine
arguments: analyze $(agent.builddirectory)\scanbin\exe\*.* --recurse --local-symbol-directories $(agent.builddirectory)\scanbin\VSCode-linux-$(VSCODE_ARCH)\pdb
- task: TSAUpload@2
inputs:
GdnPublishTsaConfigFile: '$(Build.SourceDirectory)\build\azure-pipelines\.gdntsa'

View file

@ -200,7 +200,7 @@ steps:
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
$AppRoot = "$(agent.builddirectory)\VSCode-win32-$(VSCODE_ARCH)"
exec { yarn smoketest-no-compile --build "$AppRoot" }
exec { yarn smoketest-no-compile --build "$AppRoot" --screenshots .build\logs\smoke-tests }
displayName: Run smoke tests (Electron)
timeoutInMinutes: 5
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'), ne(variables['VSCODE_ARCH'], 'arm64'))

View file

@ -4,7 +4,8 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
const vscode_universal_1 = require("vscode-universal");
const vscode_universal_bundler_1 = require("vscode-universal-bundler");
const cross_spawn_promise_1 = require("@malept/cross-spawn-promise");
const fs = require("fs-extra");
const path = require("path");
const plist = require("plist");
@ -23,7 +24,7 @@ async function main() {
const outAppPath = path.join(buildDir, `VSCode-darwin-${arch}`, appName);
const productJsonPath = path.resolve(outAppPath, 'Contents', 'Resources', 'app', 'product.json');
const infoPlistPath = path.resolve(outAppPath, 'Contents', 'Info.plist');
await (0, vscode_universal_1.makeUniversalApp)({
await (0, vscode_universal_bundler_1.makeUniversalApp)({
x64AppPath,
arm64AppPath,
x64AsarPath,
@ -50,6 +51,12 @@ async function main() {
LSRequiresNativeExecution: true
});
await fs.writeFile(infoPlistPath, plist.build(infoPlistJson), 'utf8');
// Verify if native module architecture is correct
const findOutput = await (0, cross_spawn_promise_1.spawn)('find', [outAppPath, '-name', 'keytar.node']);
const lipoOutput = await (0, cross_spawn_promise_1.spawn)('lipo', ['-archs', findOutput.replace(/\n$/, "")]);
if (lipoOutput.replace(/\n$/, "") !== 'x86_64 arm64') {
throw new Error(`Invalid arch, got : ${lipoOutput}`);
}
}
if (require.main === module) {
main().catch(err => {

View file

@ -5,7 +5,8 @@
'use strict';
import { makeUniversalApp } from 'vscode-universal';
import { makeUniversalApp } from 'vscode-universal-bundler';
import { spawn } from '@malept/cross-spawn-promise';
import * as fs from 'fs-extra';
import * as path from 'path';
import * as plist from 'plist';
@ -57,6 +58,13 @@ async function main() {
LSRequiresNativeExecution: true
});
await fs.writeFile(infoPlistPath, plist.build(infoPlistJson), 'utf8');
// Verify if native module architecture is correct
const findOutput = await spawn('find', [outAppPath, '-name', 'keytar.node'])
const lipoOutput = await spawn('lipo', ['-archs', findOutput.replace(/\n$/, "")]);
if (lipoOutput.replace(/\n$/, "") !== 'x86_64 arm64') {
throw new Error(`Invalid arch, got : ${lipoOutput}`)
}
}
if (require.main === module) {

View file

@ -79,7 +79,7 @@ module.exports.indentationFilter = [
'!src/typings/**/*.d.ts',
'!extensions/**/*.d.ts',
'!**/*.{svg,exe,png,bmp,jpg,scpt,bat,cmd,cur,ttf,woff,eot,md,ps1,template,yaml,yml,d.ts.recipe,ico,icns,plist}',
'!build/{lib,download,darwin}/**/*.js',
'!build/{lib,download,linux,darwin}/**/*.js',
'!build/**/*.sh',
'!build/azure-pipelines/**/*.js',
'!build/azure-pipelines/**/*.config',
@ -113,6 +113,7 @@ module.exports.copyrightFilter = [
'!**/*.code-workspace',
'!**/*.js.map',
'!build/**/*.init',
'!build/linux/libcxx-fetcher.*',
'!resources/linux/snap/snapcraft.yaml',
'!resources/win32/bin/code.js',
'!resources/web/code-web.js',

View file

@ -16,10 +16,10 @@ const { monacoTypecheckTask/* , monacoTypecheckWatchTask */ } = require('./gulpf
const { compileExtensionsTask, watchExtensionsTask, compileExtensionMediaTask } = require('./gulpfile.extensions');
// Fast compile for development time
const compileClientTask = task.define('compile-client', task.series(util.rimraf('out'), compilation.compileTask('src', 'out', false)));
const compileClientTask = task.define('compile-client', task.series(util.rimraf('out'), util.buildWebNodePaths(), compilation.compileTask('src', 'out', false)));
gulp.task(compileClientTask);
const watchClientTask = task.define('watch-client', task.series(util.rimraf('out'), compilation.watchTask('out', false)));
const watchClientTask = task.define('watch-client', task.series(util.rimraf('out'), util.buildWebNodePaths(), compilation.watchTask('out', false)));
gulp.task(watchClientTask);
// All

104
build/gulpfile.scan.js Normal file
View file

@ -0,0 +1,104 @@
/*---------------------------------------------------------------------------------------------
* 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 task = require('./lib/task');
const util = require('./lib/util');
const _ = require('underscore');
const electron = require('gulp-atom-electron');
const { config } = require('./lib/electron');
const filter = require('gulp-filter');
const deps = require('./lib/dependencies');
const root = path.dirname(__dirname);
const BUILD_TARGETS = [
{ platform: 'win32', arch: 'ia32' },
{ platform: 'win32', arch: 'x64' },
{ platform: 'win32', arch: 'arm64' },
{ platform: 'darwin', arch: null, opts: { stats: true } },
{ platform: 'linux', arch: 'ia32' },
{ platform: 'linux', arch: 'x64' },
{ platform: 'linux', arch: 'armhf' },
{ platform: 'linux', arch: 'arm64' },
];
BUILD_TARGETS.forEach(buildTarget => {
const dashed = (str) => (str ? `-${str}` : ``);
const platform = buildTarget.platform;
const arch = buildTarget.arch;
const destinationExe = path.join(path.dirname(root), 'scanbin', `VSCode${dashed(platform)}${dashed(arch)}`, 'bin');
const destinationPdb = path.join(path.dirname(root), 'scanbin', `VSCode${dashed(platform)}${dashed(arch)}`, 'pdb');
const tasks = [];
// removal tasks
tasks.push(util.rimraf(destinationExe), util.rimraf(destinationPdb));
// electron
tasks.push(() => electron.dest(destinationExe, _.extend({}, config, { platform, arch: arch === 'armhf' ? 'arm' : arch })));
// pdbs for windows
if (platform === 'win32') {
tasks.push(
() => electron.dest(destinationPdb, _.extend({}, config, { platform, arch: arch === 'armhf' ? 'arm' : arch, pdbs: true })),
util.rimraf(path.join(destinationExe, 'swiftshader')),
util.rimraf(path.join(destinationExe, 'd3dcompiler_47.dll')));
}
if (platform === 'linux') {
tasks.push(
() => electron.dest(destinationPdb, _.extend({}, config, { platform, arch: arch === 'armhf' ? 'arm' : arch, symbols: true }))
);
}
// node modules
tasks.push(
nodeModules(destinationExe, destinationPdb, platform)
);
const setupSymbolsTask = task.define(`vscode-symbols${dashed(platform)}${dashed(arch)}`,
task.series(...tasks)
);
gulp.task(setupSymbolsTask);
});
function nodeModules(destinationExe, destinationPdb, platform) {
const productionDependencies = deps.getProductionDependencies(root);
const dependenciesSrc = _.flatten(productionDependencies.map(d => path.relative(root, d.path)).map(d => [`${d}/**`, `!${d}/**/{test,tests}/**`]));
const exe = () => {
return gulp.src(dependenciesSrc, { base: '.', dot: true })
.pipe(filter(['**/*.node']))
.pipe(gulp.dest(destinationExe));
};
if (platform === 'win32') {
const pdb = () => {
return gulp.src(dependenciesSrc, { base: '.', dot: true })
.pipe(filter(['**/*.pdb']))
.pipe(gulp.dest(destinationPdb));
};
return gulp.parallel(exe, pdb);
}
if (platform === 'linux') {
const pdb = () => {
return gulp.src(dependenciesSrc, { base: '.', dot: true })
.pipe(filter(['**/*.sym']))
.pipe(gulp.dest(destinationPdb));
};
return gulp.parallel(exe, pdb);
}
return exe;
}

View file

@ -39,6 +39,7 @@ const vscodeEntryPoints = _.flatten([
buildfile.base,
buildfile.workerExtensionHost,
buildfile.workerNotebook,
buildfile.workerLanguageDetection,
buildfile.workbenchDesktop,
buildfile.code
]);
@ -233,9 +234,6 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op
'**/node-pty/lib/worker/conoutSocketWorker.js',
'**/node-pty/lib/shared/conout.js',
'**/*.wasm',
// For language detection
'**/model.json',
'**/group1-shard1of1.bin'
], 'node_modules.asar'));
let all = es.merge(

View file

@ -12,7 +12,7 @@ const filter = require("gulp-filter");
const _ = require("underscore");
const util = require("./util");
function isDocumentSuffix(str) {
return str != undefined && (str === 'document' || str === 'script' || str === 'file' || str === 'source code');
return str === 'document' || str === 'script' || str === 'file' || str === 'source code';
}
const root = path.dirname(path.dirname(__dirname));
const product = JSON.parse(fs.readFileSync(path.join(root, 'product.json'), 'utf8'));

View file

@ -21,6 +21,8 @@ const fancyLog = require("fancy-log");
const ansiColors = require("ansi-colors");
const buffer = require('gulp-buffer');
const jsoncParser = require("jsonc-parser");
const dependencies_1 = require("./dependencies");
const _ = require("underscore");
const util = require('./util');
const root = path.dirname(path.dirname(__dirname));
const commit = util.getVersion(root);
@ -242,8 +244,10 @@ function packageLocalExtensionsStream(forWeb) {
result = localExtensionsStream;
}
else {
// also include shared node modules
result = es.merge(localExtensionsStream, gulp.src('extensions/node_modules/**', { base: '.' }));
// also include shared production node modules
const productionDependencies = (0, dependencies_1.getProductionDependencies)('extensions/');
const dependenciesSrc = _.flatten(productionDependencies.map(d => path.relative(root, d.path)).map(d => [`${d}/**`, `!${d}/**/{test,tests}/**`]));
result = es.merge(localExtensionsStream, gulp.src(dependenciesSrc, { base: '.' }));
}
return (result
.pipe(util2.setExecutableBit(['**/*.sh'])));

View file

@ -21,6 +21,8 @@ import * as ansiColors from 'ansi-colors';
const buffer = require('gulp-buffer');
import * as jsoncParser from 'jsonc-parser';
import webpack = require('webpack');
import { getProductionDependencies } from './dependencies';
import _ = require('underscore');
const util = require('./util');
const root = path.dirname(path.dirname(__dirname));
const commit = util.getVersion(root);
@ -302,8 +304,10 @@ export function packageLocalExtensionsStream(forWeb: boolean): Stream {
if (forWeb) {
result = localExtensionsStream;
} else {
// also include shared node modules
result = es.merge(localExtensionsStream, gulp.src('extensions/node_modules/**', { base: '.' }));
// also include shared production node modules
const productionDependencies = getProductionDependencies('extensions/');
const dependenciesSrc = _.flatten(productionDependencies.map(d => path.relative(root, d.path)).map(d => [`${d}/**`, `!${d}/**/{test,tests}/**`]));
result = es.merge(localExtensionsStream, gulp.src(dependenciesSrc, { base: '.' }));
}
return (

View file

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.getElectronVersion = exports.streamToPromise = exports.versionStringToNumber = exports.filter = exports.rebase = exports.getVersion = exports.ensureDir = exports.rreddir = exports.rimraf = exports.rewriteSourceMappingURL = exports.stripSourceMappingURL = exports.loadSourcemaps = exports.cleanNodeModules = exports.skipDirectories = exports.toFileUri = exports.setExecutableBit = exports.fixWin32DirectoryPermissions = exports.incremental = void 0;
exports.buildWebNodePaths = exports.getElectronVersion = exports.streamToPromise = exports.versionStringToNumber = exports.filter = exports.rebase = exports.getVersion = exports.ensureDir = exports.rreddir = exports.rimraf = exports.rewriteSourceMappingURL = exports.stripSourceMappingURL = exports.loadSourcemaps = exports.cleanNodeModules = exports.skipDirectories = exports.toFileUri = exports.setExecutableBit = exports.fixWin32DirectoryPermissions = exports.incremental = void 0;
const es = require("event-stream");
const debounce = require("debounce");
const _filter = require("gulp-filter");
@ -274,3 +274,45 @@ function getElectronVersion() {
return target;
}
exports.getElectronVersion = getElectronVersion;
function buildWebNodePaths() {
const result = () => new Promise((resolve, _) => {
var _a;
const root = path.join(__dirname, '..', '..');
const webPackageJSON = path.join(root, '/remote/web', 'package.json');
const webPackages = JSON.parse(fs.readFileSync(webPackageJSON, 'utf8')).dependencies;
const nodePaths = {};
for (const key of Object.keys(webPackages)) {
const packageJSON = path.join(root, 'node_modules', key, 'package.json');
const packageData = JSON.parse(fs.readFileSync(packageJSON, 'utf8'));
let entryPoint = (_a = packageData.browser) !== null && _a !== void 0 ? _a : packageData.main;
// On rare cases a package doesn't have an entrypoint so we assume it has a dist folder with a min.js
if (!entryPoint) {
console.warn(`No entry point for ${key} assuming dist/${key}.min.js`);
entryPoint = `dist/${key}.min.js`;
}
// Remove any starting path information so it's all relative info
if (entryPoint.startsWith('./')) {
entryPoint = entryPoint.substr(2);
}
else if (entryPoint.startsWith('/')) {
entryPoint = entryPoint.substr(1);
}
nodePaths[key] = entryPoint;
}
// Now we write the node paths to out/vs
const outDirectory = path.join(root, 'out', 'vs');
fs.mkdirSync(outDirectory, { recursive: true });
const headerWithGeneratedFileWarning = `/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// This file is generated by build/npm/postinstall.js. Do not edit.`;
const fileContents = `${headerWithGeneratedFileWarning}\nself.webPackagePaths = ${JSON.stringify(nodePaths, null, 2)};`;
fs.writeFileSync(path.join(outDirectory, 'webPackagePaths.js'), fileContents, 'utf8');
resolve();
});
result.taskName = 'build-web-node-paths';
return result;
}
exports.buildWebNodePaths = buildWebNodePaths;

View file

@ -340,3 +340,45 @@ export function getElectronVersion(): string {
const target = /^target "(.*)"$/m.exec(yarnrc)![1];
return target;
}
export function buildWebNodePaths() {
const result = () => new Promise<void>((resolve, _) => {
const root = path.join(__dirname, '..', '..');
const webPackageJSON = path.join(root, '/remote/web', 'package.json');
const webPackages = JSON.parse(fs.readFileSync(webPackageJSON, 'utf8')).dependencies;
const nodePaths: { [key: string]: string } = {};
for (const key of Object.keys(webPackages)) {
const packageJSON = path.join(root, 'node_modules', key, 'package.json');
const packageData = JSON.parse(fs.readFileSync(packageJSON, 'utf8'));
let entryPoint = packageData.browser ?? packageData.main;
// On rare cases a package doesn't have an entrypoint so we assume it has a dist folder with a min.js
if (!entryPoint) {
console.warn(`No entry point for ${key} assuming dist/${key}.min.js`);
entryPoint = `dist/${key}.min.js`;
}
// Remove any starting path information so it's all relative info
if (entryPoint.startsWith('./')) {
entryPoint = entryPoint.substr(2);
} else if (entryPoint.startsWith('/')) {
entryPoint = entryPoint.substr(1);
}
nodePaths[key] = entryPoint;
}
// Now we write the node paths to out/vs
const outDirectory = path.join(root, 'out', 'vs');
fs.mkdirSync(outDirectory, { recursive: true });
const headerWithGeneratedFileWarning = `/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// This file is generated by build/npm/postinstall.js. Do not edit.`;
const fileContents = `${headerWithGeneratedFileWarning}\nself.webPackagePaths = ${JSON.stringify(nodePaths, null, 2)};`;
fs.writeFileSync(path.join(outDirectory, 'webPackagePaths.js'), fileContents, 'utf8');
resolve();
});
result.taskName = 'build-web-node-paths';
return result;
}

View file

@ -0,0 +1,61 @@
// Can be removed once https://github.com/electron/electron-rebuild/pull/703 is available.
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
exports.downloadLibcxxObjects = exports.downloadLibcxxHeaders = void 0;
const debug = require("debug");
const extract = require("extract-zip");
const fs = require("fs-extra");
const path = require("path");
const packageJSON = require("../../package.json");
const get_1 = require("@electron/get");
const d = debug('libcxx-fetcher');
async function downloadLibcxxHeaders(outDir, electronVersion, lib_name) {
if (await fs.pathExists(path.resolve(outDir, 'include')))
return;
if (!await fs.pathExists(outDir))
await fs.mkdirp(outDir);
d(`downloading ${lib_name}_headers`);
const headers = await (0, get_1.downloadArtifact)({
version: electronVersion,
isGeneric: true,
artifactName: `${lib_name}_headers.zip`,
});
d(`unpacking ${lib_name}_headers from ${headers}`);
await extract(headers, { dir: outDir });
}
exports.downloadLibcxxHeaders = downloadLibcxxHeaders;
async function downloadLibcxxObjects(outDir, electronVersion, targetArch = 'x64') {
if (await fs.pathExists(path.resolve(outDir, 'libc++.a')))
return;
if (!await fs.pathExists(outDir))
await fs.mkdirp(outDir);
d(`downloading libcxx-objects-linux-${targetArch}`);
const objects = await (0, get_1.downloadArtifact)({
version: electronVersion,
platform: 'linux',
artifactName: 'libcxx-objects',
arch: targetArch,
});
d(`unpacking libcxx-objects from ${objects}`);
await extract(objects, { dir: outDir });
}
exports.downloadLibcxxObjects = downloadLibcxxObjects;
async function main() {
const libcxxObjectsDirPath = process.env['VSCODE_LIBCXX_OBJECTS_DIR'];
const libcxxHeadersDownloadDir = process.env['VSCODE_LIBCXX_HEADERS_DIR'];
const libcxxabiHeadersDownloadDir = process.env['VSCODE_LIBCXXABI_HEADERS_DIR'];
const arch = process.env['VSCODE_ARCH'];
const electronVersion = packageJSON.devDependencies.electron;
if (!libcxxObjectsDirPath || !libcxxHeadersDownloadDir || !libcxxabiHeadersDownloadDir) {
throw new Error('Required build env not set');
}
await downloadLibcxxObjects(libcxxObjectsDirPath, electronVersion, arch);
await downloadLibcxxHeaders(libcxxHeadersDownloadDir, electronVersion, 'libcxx');
await downloadLibcxxHeaders(libcxxabiHeadersDownloadDir, electronVersion, 'libcxxabi');
}
if (require.main === module) {
main().catch(err => {
console.error(err);
process.exit(1);
});
}

View file

@ -0,0 +1,66 @@
// Can be removed once https://github.com/electron/electron-rebuild/pull/703 is available.
'use strict';
import * as debug from 'debug';
import * as extract from 'extract-zip';
import * as fs from 'fs-extra';
import * as path from 'path';
import * as packageJSON from '../../package.json';
import { downloadArtifact } from '@electron/get';
const d = debug('libcxx-fetcher');
export async function downloadLibcxxHeaders(outDir: string, electronVersion: string, lib_name: string): Promise<void> {
if (await fs.pathExists(path.resolve(outDir, 'include'))) return;
if (!await fs.pathExists(outDir)) await fs.mkdirp(outDir);
d(`downloading ${lib_name}_headers`);
const headers = await downloadArtifact({
version: electronVersion,
isGeneric: true,
artifactName: `${lib_name}_headers.zip`,
});
d(`unpacking ${lib_name}_headers from ${headers}`);
await extract(headers, { dir: outDir });
}
export async function downloadLibcxxObjects(outDir: string, electronVersion: string, targetArch: string = 'x64'): Promise<void> {
if (await fs.pathExists(path.resolve(outDir, 'libc++.a'))) return;
if (!await fs.pathExists(outDir)) await fs.mkdirp(outDir);
d(`downloading libcxx-objects-linux-${targetArch}`);
const objects = await downloadArtifact({
version: electronVersion,
platform: 'linux',
artifactName: 'libcxx-objects',
arch: targetArch,
});
d(`unpacking libcxx-objects from ${objects}`);
await extract(objects, { dir: outDir });
}
async function main(): Promise<void> {
const libcxxObjectsDirPath = process.env['VSCODE_LIBCXX_OBJECTS_DIR'];
const libcxxHeadersDownloadDir = process.env['VSCODE_LIBCXX_HEADERS_DIR'];
const libcxxabiHeadersDownloadDir = process.env['VSCODE_LIBCXXABI_HEADERS_DIR'];
const arch = process.env['VSCODE_ARCH'];
const electronVersion = packageJSON.devDependencies.electron;
if (!libcxxObjectsDirPath || !libcxxHeadersDownloadDir || !libcxxabiHeadersDownloadDir) {
throw new Error('Required build env not set');
}
await downloadLibcxxObjects(libcxxObjectsDirPath, electronVersion, arch);
await downloadLibcxxHeaders(libcxxHeadersDownloadDir, electronVersion, 'libcxx');
await downloadLibcxxHeaders(libcxxabiHeadersDownloadDir, electronVersion, 'libcxxabi');
}
if (require.main === module) {
main().catch(err => {
console.error(err);
process.exit(1);
});
}

View file

@ -61,6 +61,8 @@ for (let dir of dirs) {
const env = { ...process.env };
if (process.env['VSCODE_REMOTE_CC']) { env['CC'] = process.env['VSCODE_REMOTE_CC']; }
if (process.env['VSCODE_REMOTE_CXX']) { env['CXX'] = process.env['VSCODE_REMOTE_CXX']; }
if (process.env['CXXFLAGS']) { delete env['CXXFLAGS']; }
if (process.env['LDFLAGS']) { delete env['LDFLAGS']; }
if (process.env['VSCODE_REMOTE_NODE_GYP']) { env['npm_config_node_gyp'] = process.env['VSCODE_REMOTE_NODE_GYP']; }
opts = { env };
} else if (/^extensions\//.test(dir)) {

View file

@ -5,6 +5,7 @@
"devDependencies": {
"@azure/cosmos": "^3.9.3",
"@azure/storage-blob": "^12.4.0",
"@electron/get": "^1.12.4",
"@types/ansi-colors": "^3.2.0",
"@types/azure": "0.9.19",
"@types/byline": "^4.2.32",
@ -12,6 +13,7 @@
"@types/debounce": "^1.0.0",
"@types/eslint": "4.16.1",
"@types/fancy-log": "^1.3.0",
"@types/fs-extra": "^9.0.12",
"@types/glob": "^7.1.1",
"@types/gulp": "^4.0.5",
"@types/gulp-concat": "^0.0.32",
@ -45,8 +47,10 @@
"byline": "^5.0.0",
"colors": "^1.4.0",
"commander": "^7.0.0",
"debug": "^4.3.2",
"electron-osx-sign": "^0.4.16",
"esbuild": "^0.12.6",
"extract-zip": "^2.0.1",
"fs-extra": "^9.1.0",
"got": "11.8.1",
"iconv-lite-umd": "0.6.8",
@ -57,9 +61,9 @@
"plist": "^3.0.1",
"source-map": "0.6.1",
"tmp": "^0.2.1",
"typescript": "^4.4.0-dev.20210719",
"typescript": "^4.5.0-dev.20210810",
"vsce": "1.48.0",
"vscode-universal": "deepak1556/universal#61454d96223b774c53cda10f72c2098c0ce02d58"
"vscode-universal-bundler": "^0.0.2"
},
"scripts": {
"compile": "tsc -p tsconfig.build.json",

View file

@ -1,26 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
let TelemetryReporter = (function () {
function TelemetryReporter(extensionId, extensionVersion, key) {
}
TelemetryReporter.prototype.updateUserOptIn = function (key) {
};
TelemetryReporter.prototype.createAppInsightsClient = function (key) {
};
TelemetryReporter.prototype.getCommonProperties = function () {
};
TelemetryReporter.prototype.sendTelemetryEvent = function (eventName, properties, measurements) {
};
TelemetryReporter.prototype.dispose = function () {
};
TelemetryReporter.TELEMETRY_CONFIG_ID = 'telemetry';
TelemetryReporter.TELEMETRY_CONFIG_ENABLED_ID = 'enableTelemetry';
return TelemetryReporter;
}());
exports.default = TelemetryReporter;

View file

@ -108,6 +108,22 @@
events "^3.0.0"
tslib "^2.0.0"
"@electron/get@^1.12.4":
version "1.12.4"
resolved "https://registry.yarnpkg.com/@electron/get/-/get-1.12.4.tgz#a5971113fc1bf8fa12a8789dc20152a7359f06ab"
integrity sha512-6nr9DbJPUR9Xujw6zD3y+rS95TyItEVM0NVjt1EehY2vUWfIgPiIPVHxCvaTS0xr2B+DRxovYVKbuOWqC35kjg==
dependencies:
debug "^4.1.1"
env-paths "^2.2.0"
fs-extra "^8.1.0"
got "^9.6.0"
progress "^2.0.3"
semver "^6.2.0"
sumchecker "^3.0.1"
optionalDependencies:
global-agent "^2.0.2"
global-tunnel-ng "^2.7.1"
"@malept/cross-spawn-promise@^1.1.0":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz#504af200af6b98e198bce768bc1730c6936ae01d"
@ -132,11 +148,23 @@
resolved "https://registry.yarnpkg.com/@opentelemetry/context-base/-/context-base-0.10.2.tgz#55bea904b2b91aa8a8675df9eaba5961bddb1def"
integrity sha512-hZNKjKOYsckoOEgBziGMnBcX0M7EtstnCmwz5jZUOUYwlZ+/xxX6z3jPu1XVO2Jivk0eLfuP9GP+vFD49CMetw==
"@sindresorhus/is@^0.14.0":
version "0.14.0"
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==
"@sindresorhus/is@^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.0.0.tgz#2ff674e9611b45b528896d820d3d7a812de2f0e4"
integrity sha512-FyD2meJpDPjyNQejSjvnhpgI/azsQkA4lGbuu5BQZfjvJ9cbRZXzeWL2HceCekW4lixO9JPesIIQkSoLjeJHNQ==
"@szmarczak/http-timer@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==
dependencies:
defer-to-connect "^1.0.1"
"@szmarczak/http-timer@^4.0.5":
version "4.0.5"
resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.5.tgz#bfbd50211e9dfa51ba07da58a14cdfd333205152"
@ -198,7 +226,7 @@
resolved "https://registry.yarnpkg.com/@types/debounce/-/debounce-1.0.0.tgz#417560200331e1bb84d72da85391102c2fcd61b7"
integrity sha1-QXVgIAMx4buE1y2oU5EQLC/NYbc=
"@types/debug@^4.1.4", "@types/debug@^4.1.5":
"@types/debug@^4.1.4":
version "4.1.5"
resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.5.tgz#b14efa8852b7768d898906613c23f688713e02cd"
integrity sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==
@ -238,10 +266,10 @@
dependencies:
"@types/node" "*"
"@types/fs-extra@^9.0.6":
version "9.0.6"
resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-9.0.6.tgz#488e56b77299899a608b8269719c1d133027a6ab"
integrity sha512-ecNRHw4clCkowNOBJH1e77nvbPxHYnWIXMv1IAoG/9+MYGkgoyr3Ppxr7XYFNL41V422EDhyV4/4SSK8L2mlig==
"@types/fs-extra@^9.0.12":
version "9.0.12"
resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-9.0.12.tgz#9b8f27973df8a7a3920e8461517ebf8a7d4fdfaf"
integrity sha512-I+bsBr67CurCGnSenZZ7v94gd3tc3+Aj2taxMT4yu4ABLuOgOjeFxX3dokG24ztSRg5tnT00sL8BszO7gSMoIw==
dependencies:
"@types/node" "*"
@ -391,11 +419,6 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.43.tgz#26bcbb0595b305400e8ceaf9a127a7f905ae49c8"
integrity sha512-3pwDJjp1PWacPTpH0LcfhgjvurQvrZFBrC6xxjaUEZ7ifUtT32jtjPxEMMblpqd2Mvx+k8haqQJLQxolyGN/cQ==
"@types/node@^14.14.21":
version "14.14.22"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.22.tgz#0d29f382472c4ccf3bd96ff0ce47daf5b7b84b18"
integrity sha512-g+f/qj/cNcqKkc3tFqlXOYjrmZA+jNBiDzbP3kH+B+otKFqAdPgVTGP1IeKRdMml/aE69as5S4FqtxAbl+LaMw==
"@types/p-limit@^2.2.0":
version "2.2.0"
resolved "https://registry.yarnpkg.com/@types/p-limit/-/p-limit-2.2.0.tgz#94a608e9b258a6c6156a13d1a14fd720dba70b97"
@ -552,6 +575,13 @@
resolved "https://registry.yarnpkg.com/@types/xml2js/-/xml2js-0.0.33.tgz#20c5dd6460245284d64a55690015b95e409fb7de"
integrity sha1-IMXdZGAkUoTWSlVpABW5XkCft94=
"@types/yauzl@^2.9.1":
version "2.9.2"
resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.9.2.tgz#c48e5d56aff1444409e39fa164b0b4d4552a7b7a"
integrity sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==
dependencies:
"@types/node" "*"
"@typescript-eslint/experimental-utils@3.10.1":
version "3.10.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-3.10.1.tgz#e179ffc81a80ebcae2ea04e0332f8b251345a686"
@ -725,9 +755,9 @@ azure-storage@^2.1.0:
xmlbuilder "^9.0.7"
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=
version "1.0.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
base64-js@^1.2.3:
version "1.3.1"
@ -751,6 +781,11 @@ boolbase@~1.0.0:
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
boolean@^3.0.1:
version "3.1.2"
resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.1.2.tgz#e30f210a26b02458482a8cc353ab06f262a780c2"
integrity sha512-YN6UmV0FfLlBVvRvNPx3pz5W/mUoYB24J4WSXOKP/OOJpi+Oq6WYqPaNTHzjI0QzwWtnvEd5CGYyQPgp1jFxnw==
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
@ -802,6 +837,19 @@ cacheable-lookup@^5.0.3:
resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005"
integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==
cacheable-request@^6.0.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912"
integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==
dependencies:
clone-response "^1.0.2"
get-stream "^5.1.0"
http-cache-semantics "^4.0.0"
keyv "^3.0.0"
lowercase-keys "^2.0.0"
normalize-url "^4.1.0"
responselike "^1.0.2"
cacheable-request@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.1.tgz#062031c2856232782ed694a257fa35da93942a58"
@ -914,6 +962,19 @@ concat-map@0.0.1:
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
config-chain@^1.1.11:
version "1.1.13"
resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4"
integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==
dependencies:
ini "^1.3.4"
proto-list "~1.2.1"
core-js@^3.6.5:
version "3.15.2"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.15.2.tgz#740660d2ff55ef34ce664d7e2455119c5bdd3d61"
integrity sha512-tKs41J7NJVuaya8DxIOCnl8QuPHx5/ZVbFo1oKgVl1qHFBBrDctzQGtuLjPpRdNTWmKPH6oEvgN/MUID+l485Q==
core-util-is@1.0.2, 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"
@ -957,6 +1018,13 @@ debug@^2.6.8:
dependencies:
ms "2.0.0"
debug@^4.1.0, debug@^4.3.2:
version "4.3.2"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b"
integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==
dependencies:
ms "2.1.2"
debug@^4.1.1, debug@^4.3.1:
version "4.3.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
@ -964,6 +1032,13 @@ debug@^4.1.1, debug@^4.3.1:
dependencies:
ms "2.1.2"
decompress-response@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3"
integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=
dependencies:
mimic-response "^1.0.0"
decompress-response@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc"
@ -971,11 +1046,23 @@ decompress-response@^6.0.0:
dependencies:
mimic-response "^3.1.0"
defer-to-connect@^1.0.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591"
integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==
defer-to-connect@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.0.tgz#83d6b199db041593ac84d781b5222308ccf4c2c1"
integrity sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg==
define-properties@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==
dependencies:
object-keys "^1.0.12"
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
@ -986,6 +1073,11 @@ denodeify@^1.2.1:
resolved "https://registry.yarnpkg.com/denodeify/-/denodeify-1.2.1.tgz#3a36287f5034e699e7577901052c2e6c94251631"
integrity sha1-OjYof1A05pnnV3kBBSwubJQlFjE=
detect-node@^2.0.4:
version "2.1.0"
resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1"
integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==
diagnostic-channel-publishers@0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz#8e2d607a8b6d79fe880b548bc58cc6beb288c4f3"
@ -1054,6 +1146,11 @@ domutils@^1.5.1:
dom-serializer "0"
domelementtype "1"
duplexer3@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=
ecc-jsbn@~0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
@ -1074,6 +1171,11 @@ electron-osx-sign@^0.4.16:
minimist "^1.2.0"
plist "^3.0.1"
encodeurl@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
end-of-stream@^1.1.0:
version "1.4.4"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
@ -1086,6 +1188,16 @@ entities@^1.1.1, entities@~1.1.1:
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
env-paths@^2.2.0:
version "2.2.1"
resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"
integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==
es6-error@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d"
integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==
esbuild@^0.12.6:
version "0.12.6"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.12.6.tgz#85bc755c7cf3005d4f34b4f10f98049ce0ee67ce"
@ -1096,6 +1208,11 @@ escape-string-regexp@^1.0.5:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
escape-string-regexp@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
eslint-scope@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9"
@ -1138,6 +1255,17 @@ extend@^3.0.2, extend@~3.0.2:
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
extract-zip@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a"
integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==
dependencies:
debug "^4.1.1"
get-stream "^5.1.0"
yauzl "^2.10.0"
optionalDependencies:
"@types/yauzl" "^2.9.1"
extsprintf@1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
@ -1188,6 +1316,15 @@ form-data@~2.3.2:
combined-stream "^1.0.6"
mime-types "^2.1.12"
fs-extra@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
dependencies:
graceful-fs "^4.2.0"
jsonfile "^4.0.0"
universalify "^0.1.0"
fs-extra@^9.0.1, fs-extra@^9.1.0:
version "9.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d"
@ -1203,6 +1340,13 @@ fs.realpath@^1.0.0:
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
get-stream@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==
dependencies:
pump "^3.0.0"
get-stream@^5.1.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3"
@ -1229,7 +1373,7 @@ glob@^7.0.6:
once "^1.3.0"
path-is-absolute "^1.0.0"
glob@^7.1.3:
glob@^7.1.3, glob@^7.1.6:
version "7.1.7"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90"
integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==
@ -1241,17 +1385,35 @@ glob@^7.1.3:
once "^1.3.0"
path-is-absolute "^1.0.0"
glob@^7.1.6:
version "7.1.6"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
global-agent@^2.0.2:
version "2.2.0"
resolved "https://registry.yarnpkg.com/global-agent/-/global-agent-2.2.0.tgz#566331b0646e6bf79429a16877685c4a1fbf76dc"
integrity sha512-+20KpaW6DDLqhG7JDiJpD1JvNvb8ts+TNl7BPOYcURqCrXqnN1Vf+XVOrkKJAFPqfX+oEhsdzOj1hLWkBTdNJg==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.4"
once "^1.3.0"
path-is-absolute "^1.0.0"
boolean "^3.0.1"
core-js "^3.6.5"
es6-error "^4.1.1"
matcher "^3.0.0"
roarr "^2.15.3"
semver "^7.3.2"
serialize-error "^7.0.1"
global-tunnel-ng@^2.7.1:
version "2.7.1"
resolved "https://registry.yarnpkg.com/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz#d03b5102dfde3a69914f5ee7d86761ca35d57d8f"
integrity sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==
dependencies:
encodeurl "^1.0.2"
lodash "^4.17.10"
npm-conf "^1.1.3"
tunnel "^0.0.6"
globalthis@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.2.tgz#2a235d34f4d8036219f7e34929b5de9e18166b8b"
integrity sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==
dependencies:
define-properties "^1.1.3"
got@11.8.1:
version "11.8.1"
@ -1270,10 +1432,27 @@ got@11.8.1:
p-cancelable "^2.0.0"
responselike "^2.0.0"
got@^9.6.0:
version "9.6.0"
resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85"
integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==
dependencies:
"@sindresorhus/is" "^0.14.0"
"@szmarczak/http-timer" "^1.1.2"
cacheable-request "^6.0.0"
decompress-response "^3.3.0"
duplexer3 "^0.1.4"
get-stream "^4.1.0"
lowercase-keys "^1.0.1"
mimic-response "^1.0.1"
p-cancelable "^1.0.0"
to-readable-stream "^1.0.0"
url-parse-lax "^3.0.0"
graceful-fs@^4.1.6, graceful-fs@^4.2.0:
version "4.2.4"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==
version "4.2.8"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a"
integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==
"graceful-readlink@>= 1.0.0":
version "1.0.1"
@ -1364,6 +1543,11 @@ inherits@^2.0.3:
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
ini@^1.3.4:
version "1.3.8"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
is-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
@ -1413,6 +1597,11 @@ jsbn@~0.1.0:
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
json-buffer@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898"
integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=
json-buffer@3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
@ -1435,7 +1624,7 @@ json-schema@0.2.3:
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
json-stringify-safe@~5.0.1:
json-stringify-safe@^5.0.1, 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=
@ -1445,6 +1634,13 @@ jsonc-parser@^2.3.0:
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.3.0.tgz#7c7fc988ee1486d35734faaaa866fadb00fa91ee"
integrity sha512-b0EBt8SWFNnixVdvoR2ZtEGa9ZqLhbJnOjezn+WP+8kspFm+PFYDN8Z4Bc7pRlDjvuVcADSUkroIuTWWn/YiIA==
jsonfile@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=
optionalDependencies:
graceful-fs "^4.1.6"
jsonfile@^6.0.1:
version "6.1.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
@ -1469,6 +1665,13 @@ jsprim@^1.2.2:
json-schema "0.2.3"
verror "1.10.0"
keyv@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9"
integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==
dependencies:
json-buffer "3.0.0"
keyv@^4.0.0:
version "4.0.3"
resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.3.tgz#4f3aa98de254803cafcd2896734108daa35e4254"
@ -1493,6 +1696,11 @@ lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.15:
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
lowercase-keys@^1.0.0, lowercase-keys@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f"
integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==
lowercase-keys@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"
@ -1516,6 +1724,13 @@ markdown-it@^8.3.1:
mdurl "^1.0.1"
uc.micro "^1.0.5"
matcher@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/matcher/-/matcher-3.0.0.tgz#bd9060f4c5b70aa8041ccc6f80368760994f30ca"
integrity sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==
dependencies:
escape-string-regexp "^4.0.0"
md5.js@1.3.4:
version "1.3.4"
resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d"
@ -1551,7 +1766,7 @@ mime@^1.4.1:
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
mimic-response@^1.0.0:
mimic-response@^1.0.0, mimic-response@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
@ -1613,6 +1828,14 @@ normalize-url@^4.1.0:
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a"
integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==
npm-conf@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9"
integrity sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==
dependencies:
config-chain "^1.1.11"
pify "^3.0.0"
nth-check@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c"
@ -1625,6 +1848,11 @@ oauth-sign@~0.9.0:
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
object-keys@^1.0.12:
version "1.1.1"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
once@^1.3.0, once@^1.3.1, once@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
@ -1650,6 +1878,11 @@ osenv@^0.1.3:
os-homedir "^1.0.0"
os-tmpdir "^1.0.0"
p-cancelable@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc"
integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==
p-cancelable@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.0.0.tgz#4a3740f5bdaf5ed5d7c3e34882c6fb5d6b266a6e"
@ -1701,6 +1934,11 @@ picomatch@^2.0.4:
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
pify@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"
integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=
plist@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.1.tgz#a9b931d17c304e8912ef0ba3bdd6182baf2e1f8c"
@ -1719,6 +1957,11 @@ plist@^3.0.1:
source-map "^0.6.1"
supports-color "^6.1.0"
prepend-http@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897"
integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=
priorityqueuejs@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/priorityqueuejs/-/priorityqueuejs-1.0.0.tgz#2ee4f23c2560913e08c07ce5ccdd6de3df2c5af8"
@ -1734,6 +1977,16 @@ process@^0.11.10:
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI=
progress@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
proto-list@~1.2.1:
version "1.2.4"
resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=
psl@^1.1.28, psl@^1.1.33:
version "1.8.0"
resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24"
@ -1835,6 +2088,13 @@ resolve-alpn@^1.0.0:
resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.0.0.tgz#745ad60b3d6aff4b4a48e01b8c0bdc70959e0e8c"
integrity sha512-rTuiIEqFmGxne4IovivKSDzld2lWW9QCjqv80SYjPgf+gS35eaCAjaP54CCwGAwBtnCsvNLYtqxe1Nw+i6JEmA==
responselike@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7"
integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=
dependencies:
lowercase-keys "^1.0.0"
responselike@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.0.tgz#26391bcc3174f750f9a79eacc40a12a5c42d7723"
@ -1849,6 +2109,18 @@ rimraf@^3.0.0:
dependencies:
glob "^7.1.3"
roarr@^2.15.3:
version "2.15.4"
resolved "https://registry.yarnpkg.com/roarr/-/roarr-2.15.4.tgz#f5fe795b7b838ccfe35dc608e0282b9eba2e7afd"
integrity sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==
dependencies:
boolean "^3.0.1"
detect-node "^2.0.4"
globalthis "^1.0.1"
json-stringify-safe "^5.0.1"
semver-compare "^1.0.0"
sprintf-js "^1.1.2"
safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0:
version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
@ -1879,12 +2151,17 @@ semaphore@^1.0.5:
resolved "https://registry.yarnpkg.com/semaphore/-/semaphore-1.1.0.tgz#aaad8b86b20fe8e9b32b16dc2ee682a8cd26a8aa"
integrity sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==
semver-compare@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w=
semver@^5.1.0, semver@^5.3.0:
version "5.6.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004"
integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==
semver@^6.3.0:
semver@^6.2.0, semver@^6.3.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
@ -1896,6 +2173,13 @@ semver@^7.3.2:
dependencies:
lru-cache "^6.0.0"
serialize-error@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-7.0.1.tgz#f1360b0447f61ffb483ec4157c737fab7d778e18"
integrity sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==
dependencies:
type-fest "^0.13.1"
shebang-command@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
@ -1918,6 +2202,11 @@ source-map@^0.7.3:
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==
sprintf-js@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673"
integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==
sprintf-js@~1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
@ -1950,6 +2239,13 @@ string_decoder@~0.10.x:
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=
sumchecker@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-3.0.1.tgz#6377e996795abb0b6d348e9b3e1dfb24345a8e42"
integrity sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==
dependencies:
debug "^4.1.0"
supports-color@^5.3.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
@ -1978,6 +2274,11 @@ tmp@^0.2.1:
dependencies:
rimraf "^3.0.0"
to-readable-stream@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771"
integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==
tough-cookie@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4"
@ -2034,6 +2335,11 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0:
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
type-fest@^0.13.1:
version "0.13.1"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934"
integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==
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"
@ -2042,15 +2348,10 @@ typed-rest-client@^0.9.0:
tunnel "0.0.4"
underscore "1.8.3"
typescript@^4.1.3:
version "4.1.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.3.tgz#519d582bd94cba0cf8934c7d8e8467e473f53bb7"
integrity sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==
typescript@^4.4.0-dev.20210719:
version "4.4.0-dev.20210719"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.0-dev.20210719.tgz#e8d559ca3d8ab61cd1ac21a2c64f634664edc05d"
integrity sha512-dPi0te3zlBNIp4D2McbQjt7LyQPthQvPyAJgknLQNoxsVSLpVyG5tO3yINgFgHlK968uD7B/wPLFq82CgOjy8Q==
typescript@^4.5.0-dev.20210810:
version "4.5.0-dev.20210810"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.0-dev.20210810.tgz#e29c56a180a3ea43dca880000f8b1cbb4da5af48"
integrity sha512-9d8OrY8J3LbkWgjrPLE8pXOI4Z8bfS9N2SudgvrZOgYUmEODJYfA+MIZ6Zv/qrVSRH3M5632/0CjJr0Zk/sqWA==
uc.micro@^1.0.1, uc.micro@^1.0.5:
version "1.0.5"
@ -2072,7 +2373,7 @@ universal-user-agent@^6.0.0:
resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee"
integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==
universalify@^0.1.2:
universalify@^0.1.0, universalify@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
@ -2094,6 +2395,13 @@ url-join@^1.1.0:
resolved "https://registry.yarnpkg.com/url-join/-/url-join-1.1.0.tgz#741c6c2f4596c4830d6718460920d0c92202dc78"
integrity sha1-dBxsL0WWxIMNZxhGCSDQySIC3Hg=
url-parse-lax@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c"
integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=
dependencies:
prepend-http "^2.0.0"
util-deprecate@^1.0.1, util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
@ -2146,19 +2454,16 @@ vsce@1.48.0:
yauzl "^2.3.1"
yazl "^2.2.2"
vscode-universal@deepak1556/universal#61454d96223b774c53cda10f72c2098c0ce02d58:
vscode-universal-bundler@^0.0.2:
version "0.0.2"
resolved "https://codeload.github.com/deepak1556/universal/tar.gz/61454d96223b774c53cda10f72c2098c0ce02d58"
resolved "https://registry.yarnpkg.com/vscode-universal-bundler/-/vscode-universal-bundler-0.0.2.tgz#2c988dac681d3ffe6baec6defac0995cb833c55a"
integrity sha512-FPJcvKnQGBqFzy6M6Nm2yvAczNLUeXsfYM6GwCex/pUOkvIM2icIHmiSvtMJINlLW1iG+oEwE3/LVbABmcjEmQ==
dependencies:
"@malept/cross-spawn-promise" "^1.1.0"
"@types/debug" "^4.1.5"
"@types/fs-extra" "^9.0.6"
"@types/node" "^14.14.21"
asar "^3.0.3"
debug "^4.3.1"
dir-compare "^2.4.0"
fs-extra "^9.0.1"
typescript "^4.1.3"
vso-node-api@6.1.2-preview:
version "6.1.2-preview"
@ -2222,7 +2527,7 @@ yallist@^4.0.0:
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yauzl@^2.3.1:
yauzl@^2.10.0, yauzl@^2.3.1:
version "2.10.0"
resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"
integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=

View file

@ -147,5 +147,37 @@
"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS",
"SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
]
},
{
// Reason: Repository lacks license text.
// https://github.com/Stuk/eslint-plugin-header/blob/main/package.json declares MIT.
// https://github.com/Stuk/eslint-plugin-header/issues/43
"name": "eslint-plugin-header",
"fullLicenseText": [
"MIT License",
"Copyright (c) 2015 - present, Stuart Knightley",
"",
"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:",
"",
"The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.",
"",
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
]
},
{
// Reason: Repository lacks license text.
// https://github.com/tjwebb/fnv-plus/blob/master/package.json declares MIT.
// https://github.com/tjwebb/fnv-plus/issues/14
"name": "@enonic/fnv-plus",
"fullLicenseText": [
"MIT License",
"Copyright (c) 2014 - present, Travis Webb <me@traviswebb.com>",
"",
"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:",
"",
"The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.",
"",
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
]
}
]

View file

@ -6,7 +6,7 @@
"git": {
"name": "chromium",
"repositoryUrl": "https://chromium.googlesource.com/chromium/src",
"commitHash": "7a7e35991d61ce564ed3641222da2c4ed7a65535"
"commitHash": "8a33e05d162c4f39afa2dcb150e8c2548aa4ccea"
}
},
"licenseDetail": [
@ -40,7 +40,7 @@
"SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
],
"isOnlyProductionDependency": true,
"version": "91.0.4472.124"
"version": "91.0.4472.164"
},
{
"component": {
@ -60,12 +60,12 @@
"git": {
"name": "electron",
"repositoryUrl": "https://github.com/electron/electron",
"commitHash": "971ec77b966ef6924418d3e766d383d4b4d1900f"
"commitHash": "0436a27d4f0fd7d1cb8246137a07fa0c8eb9337e"
}
},
"isOnlyProductionDependency": true,
"license": "MIT",
"version": "13.1.7"
"version": "13.1.8"
},
{
"component": {

View file

@ -42,6 +42,8 @@
".inl",
".ipp",
".ixx",
".tpp",
".txx",
".hpp.in",
".h.in"
],

View file

@ -6,7 +6,7 @@
"git": {
"name": "dart-lang/dart-syntax-highlight",
"repositoryUrl": "https://github.com/dart-lang/dart-syntax-highlight",
"commitHash": "e0055eb2f95dd206689f5b1527dadb7bebbfae3d"
"commitHash": "0aaacde81aa9a12cfed8ca4ab619be5d9e9ed00a"
}
},
"licenseDetail": [

View file

@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/dart-lang/dart-syntax-highlight/commit/e0055eb2f95dd206689f5b1527dadb7bebbfae3d",
"version": "https://github.com/dart-lang/dart-syntax-highlight/commit/0aaacde81aa9a12cfed8ca4ab619be5d9e9ed00a",
"name": "Dart",
"scopeName": "source.dart",
"patterns": [
@ -323,16 +323,31 @@
"string-interp": {
"patterns": [
{
"match": "\\$(([a-zA-Z0-9_]+)|\\{([^{}]+)\\})",
"match": "\\$([a-zA-Z0-9_]+)",
"captures": {
"2": {
"name": "variable.parameter.dart"
},
"3": {
"1": {
"name": "variable.parameter.dart"
}
}
},
{
"name": "string.interpolated.expression.dart",
"begin": "\\$\\{",
"end": "\\}",
"patterns": [
{
"include": "#constants-and-special-vars",
"name": "variable.parameter.dart"
},
{
"include": "#strings"
},
{
"name": "variable.parameter.dart",
"match": "[a-zA-Z0-9_]+"
}
]
},
{
"name": "constant.character.escape.dart",
"match": "\\\\."

View file

@ -68,6 +68,9 @@
"default": "UTF-8"
}
},
"additionalProperties": {
"type": "string"
},
"default": {},
"markdownDescription": "%emmetVariables%"
},
@ -78,6 +81,9 @@
},
"emmet.excludeLanguages": {
"type": "array",
"items": {
"type": "string"
},
"default": [
"markdown"
],

View file

@ -1553,10 +1553,10 @@
"command": "git.branchFrom",
"group": "branch@4"
},
{
"command": "git.renameBranch",
"group": "branch@5"
},
{
"command": "git.renameBranch",
"group": "branch@5"
},
{
"command": "git.deleteBranch",
"group": "branch@6"
@ -1692,8 +1692,15 @@
"default": true
},
"git.autofetch": {
"type": ["boolean", "string"],
"enum": [true, false, "all"],
"type": [
"boolean",
"string"
],
"enum": [
true,
false,
"all"
],
"scope": "resource",
"markdownDescription": "%config.autofetch%",
"default": false,
@ -2376,7 +2383,7 @@
"file-type": "^7.2.0",
"iconv-lite-umd": "0.6.8",
"jschardet": "2.3.0",
"vscode-extension-telemetry": "0.1.7",
"vscode-extension-telemetry": "0.2.8",
"vscode-nls": "^4.0.0",
"vscode-uri": "^2.0.0",
"which": "^1.3.0"

View file

@ -169,7 +169,7 @@
"config.useForcePushWithLease": "Controls whether force pushing uses the safer force-with-lease variant.",
"config.confirmForcePush": "Controls whether to ask for confirmation before force-pushing.",
"config.allowNoVerifyCommit": "Controls whether commits without running pre-commit and commit-msg hooks are allowed.",
"config.confirmNoVerifyCommit": "Controls whether to ask for confirmation before commiting without verification.",
"config.confirmNoVerifyCommit": "Controls whether to ask for confirmation before committing without verification.",
"config.openDiffOnClick": "Controls whether the diff editor should be opened when clicking a change. Otherwise the regular editor will be opened.",
"config.supportCancellation": "Controls whether a notification comes up when running the Sync action, which allows the user to cancel the operation.",
"config.branchSortOrder": "Controls the sort order for branches.",

View file

@ -1916,7 +1916,7 @@ export class Repository implements Disposable {
this.setCountBadge();
// Update context key with changed resources
commands.executeCommand('setContext', 'git.changedResources', workingTree.map(r => r.resourceUri.fsPath.toString()));
commands.executeCommand('setContext', 'git.changedResources', [...merge, ...index, ...workingTree, ...untracked].map(r => r.resourceUri.fsPath.toString()));
this._onDidChangeStatus.fire();

View file

@ -36,72 +36,11 @@
resolved "https://registry.yarnpkg.com/@types/which/-/which-1.0.28.tgz#016e387629b8817bed653fe32eab5d11279c8df6"
integrity sha1-AW44dim4gXvtZT/jLqtdESecjfY=
applicationinsights@1.7.4:
version "1.7.4"
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-1.7.4.tgz#e7d96435594d893b00cf49f70a5927105dbb8749"
integrity sha512-XFLsNlcanpjFhHNvVWEfcm6hr7lu9znnb6Le1Lk5RE03YUV9X2B2n2MfM4kJZRrUdV+C0hdHxvWyv+vWoLfY7A==
dependencies:
cls-hooked "^4.2.2"
continuation-local-storage "^3.2.1"
diagnostic-channel "0.2.0"
diagnostic-channel-publishers "^0.3.3"
async-hook-jl@^1.7.6:
version "1.7.6"
resolved "https://registry.yarnpkg.com/async-hook-jl/-/async-hook-jl-1.7.6.tgz#4fd25c2f864dbaf279c610d73bf97b1b28595e68"
integrity sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==
dependencies:
stack-chain "^1.3.7"
async-listener@^0.6.0:
version "0.6.10"
resolved "https://registry.yarnpkg.com/async-listener/-/async-listener-0.6.10.tgz#a7c97abe570ba602d782273c0de60a51e3e17cbc"
integrity sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==
dependencies:
semver "^5.3.0"
shimmer "^1.1.0"
byline@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1"
integrity sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE=
cls-hooked@^4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908"
integrity sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==
dependencies:
async-hook-jl "^1.7.6"
emitter-listener "^1.0.1"
semver "^5.4.1"
continuation-local-storage@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz#11f613f74e914fe9b34c92ad2d28fe6ae1db7ffb"
integrity sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==
dependencies:
async-listener "^0.6.0"
emitter-listener "^1.1.1"
diagnostic-channel-publishers@^0.3.3:
version "0.3.5"
resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.5.tgz#a84a05fd6cc1d7619fdd17791c17e540119a7536"
integrity sha512-AOIjw4T7Nxl0G2BoBPhkQ6i7T4bUd9+xvdYizwvG7vVAM1dvr+SDrcUudlmzwH0kbEwdR2V1EcnKT0wAeYLQNQ==
diagnostic-channel@0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz#cc99af9612c23fb1fff13612c72f2cbfaa8d5a17"
integrity sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=
dependencies:
semver "^5.3.0"
emitter-listener@^1.0.1, emitter-listener@^1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/emitter-listener/-/emitter-listener-1.1.2.tgz#56b140e8f6992375b3d7cb2cab1cc7432d9632e8"
integrity sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==
dependencies:
shimmer "^1.2.0"
file-type@^7.2.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/file-type/-/file-type-7.2.0.tgz#113cfed52e1d6959ab80248906e2f25a8cdccb74"
@ -122,32 +61,10 @@ jschardet@2.3.0:
resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-2.3.0.tgz#06e2636e16c8ada36feebbdc08aa34e6a9b3ff75"
integrity sha512-6I6xT7XN/7sBB7q8ObzKbmv5vN+blzLcboDE1BNEsEfmRXJValMxO6OIRT69ylPBRemS3rw6US+CMCar0OBc9g==
semver@^5.3.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
integrity sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==
semver@^5.4.1:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
shimmer@^1.1.0, shimmer@^1.2.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337"
integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==
stack-chain@^1.3.7:
version "1.3.7"
resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285"
integrity sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=
vscode-extension-telemetry@0.1.7:
version "0.1.7"
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.7.tgz#18389bc24127c89dade29cd2b71ba69a6ee6ad26"
integrity sha512-pZuZTHO9OpsrwlerOKotWBRLRYJ53DobYb7aWiRAXjlqkuqE+YJJaP+2WEy8GrLIF1EnitXTDMaTAKsmLQ5ORQ==
dependencies:
applicationinsights "1.7.4"
vscode-extension-telemetry@0.2.8:
version "0.2.8"
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.2.8.tgz#670c625c44791237c040cee2cb9f567ca34784ac"
integrity sha512-Vf52im5qzORRD2K5Ryp8PXo31YXVcJAYRSDDZGegWlt0OATOd83DYabS1U/WIq9nR5g80UQKH3+BsenhpQHUaA==
vscode-nls@^4.0.0:
version "4.0.0"

View file

@ -39,7 +39,6 @@
"command": "github-enterprise.provide-token",
"title": "Manually Provide Token",
"category": "GitHub Enterprise"
}
],
"menus": {
@ -67,7 +66,7 @@
"configuration": {
"title": "GitHub Enterprise Authentication Provider",
"properties": {
"github-enterprise.uri" : {
"github-enterprise.uri": {
"type": "string",
"description": "URI of your GitHub Enterprise Instance"
}
@ -87,7 +86,7 @@
"dependencies": {
"node-fetch": "2.6.1",
"uuid": "8.1.0",
"vscode-extension-telemetry": "0.1.7",
"vscode-extension-telemetry": "0.2.8",
"vscode-nls": "^5.0.0",
"vscode-tas-client": "^0.1.22"
},

View file

@ -9,10 +9,41 @@ import { getExperimentationService, IExperimentationService, IExperimentationTel
export class ExperimentationTelemetry implements IExperimentationTelemetry {
private sharedProperties: Record<string, string> = {};
private experimentationServicePromise: Promise<IExperimentationService> | undefined;
constructor(private baseReporter: TelemetryReporter) { }
constructor(private readonly context: vscode.ExtensionContext, private baseReporter: TelemetryReporter) { }
private async createExperimentationService(): Promise<IExperimentationService> {
let targetPopulation: TargetPopulation;
switch (vscode.env.uriScheme) {
case 'vscode':
targetPopulation = TargetPopulation.Public;
case 'vscode-insiders':
targetPopulation = TargetPopulation.Insiders;
case 'vscode-exploration':
targetPopulation = TargetPopulation.Internal;
case 'code-oss':
targetPopulation = TargetPopulation.Team;
default:
targetPopulation = TargetPopulation.Public;
}
const id = this.context.extension.id;
const version = this.context.extension.packageJSON.version;
const experimentationService = getExperimentationService(id, version, targetPopulation, this, this.context.globalState);
await experimentationService.initialFetch;
return experimentationService;
}
/**
* @returns A promise that you shouldn't need to await because this is just telemetry.
*/
async sendTelemetryEvent(eventName: string, properties?: Record<string, string>, measurements?: Record<string, number>) {
if (!this.experimentationServicePromise) {
this.experimentationServicePromise = this.createExperimentationService();
}
await this.experimentationServicePromise;
sendTelemetryEvent(eventName: string, properties?: Record<string, string>, measurements?: Record<string, number>) {
this.baseReporter.sendTelemetryEvent(
eventName,
{
@ -23,11 +54,19 @@ export class ExperimentationTelemetry implements IExperimentationTelemetry {
);
}
sendTelemetryErrorEvent(
/**
* @returns A promise that you shouldn't need to await because this is just telemetry.
*/
async sendTelemetryErrorEvent(
eventName: string,
properties?: Record<string, string>,
_measurements?: Record<string, number>,
_measurements?: Record<string, number>
) {
if (!this.experimentationServicePromise) {
this.experimentationServicePromise = this.createExperimentationService();
}
await this.experimentationServicePromise;
this.baseReporter.sendTelemetryErrorEvent(eventName, {
...this.sharedProperties,
...properties,
@ -50,24 +89,3 @@ export class ExperimentationTelemetry implements IExperimentationTelemetry {
return this.baseReporter.dispose();
}
}
function getTargetPopulation(): TargetPopulation {
switch (vscode.env.uriScheme) {
case 'vscode':
return TargetPopulation.Public;
case 'vscode-insiders':
return TargetPopulation.Insiders;
case 'vscode-exploration':
return TargetPopulation.Internal;
case 'code-oss':
return TargetPopulation.Team;
default:
return TargetPopulation.Public;
}
}
export async function createExperimentationService(context: vscode.ExtensionContext, telemetry: ExperimentationTelemetry): Promise<IExperimentationService> {
const id = context.extension.id;
const version = context.extension.packageJSON.version;
return getExperimentationService(id, version, getTargetPopulation(), telemetry, context.globalState);
}

View file

@ -5,24 +5,8 @@
import * as vscode from 'vscode';
import { GitHubAuthenticationProvider, AuthProviderType } from './github';
import TelemetryReporter from 'vscode-extension-telemetry';
import { createExperimentationService, ExperimentationTelemetry } from './experimentationService';
export async function activate(context: vscode.ExtensionContext) {
const { name, version, aiKey } = require('../package.json') as { name: string, version: string, aiKey: string };
const telemetryReporter = new ExperimentationTelemetry(new TelemetryReporter(name, version, aiKey));
const experimentationService = await createExperimentationService(context, telemetryReporter);
await experimentationService.initialFetch;
[
AuthProviderType.github,
AuthProviderType['github-enterprise']
].forEach(async type => {
const loginService = new GitHubAuthenticationProvider(context, type, telemetryReporter);
await loginService.initialize();
});
context.subscriptions.push(new GitHubAuthenticationProvider(context, AuthProviderType.github));
context.subscriptions.push(new GitHubAuthenticationProvider(context, AuthProviderType.githubEnterprise));
}
// this method is called when your extension is deactivated
export function deactivate() { }

View file

@ -6,10 +6,11 @@
import * as vscode from 'vscode';
import { v4 as uuid } from 'uuid';
import { Keychain } from './common/keychain';
import { GitHubServer, uriHandler, NETWORK_ERROR } from './githubServer';
import { GitHubServer, uriHandler } from './githubServer';
import Logger from './common/logger';
import { arrayEquals } from './common/utils';
import { ExperimentationTelemetry } from './experimentationService';
import TelemetryReporter from 'vscode-extension-telemetry';
interface SessionData {
id: string;
@ -24,118 +25,88 @@ interface SessionData {
export enum AuthProviderType {
github = 'github',
'github-enterprise' = 'github-enterprise'
githubEnterprise = 'github-enterprise'
}
export class GitHubAuthenticationProvider implements vscode.AuthenticationProvider {
private _sessions: vscode.AuthenticationSession[] = [];
export class GitHubAuthenticationProvider implements vscode.AuthenticationProvider, vscode.Disposable {
private _sessionChangeEmitter = new vscode.EventEmitter<vscode.AuthenticationProviderAuthenticationSessionsChangeEvent>();
private _githubServer: GitHubServer;
private _telemetryReporter: ExperimentationTelemetry;
private _keychain: Keychain;
private _sessionsPromise: Promise<vscode.AuthenticationSession[]>;
private _disposable: vscode.Disposable;
constructor(private context: vscode.ExtensionContext, private type: AuthProviderType) {
const { name, version, aiKey } = context.extension.packageJSON as { name: string, version: string, aiKey: string };
this._telemetryReporter = new ExperimentationTelemetry(context, new TelemetryReporter(name, version, aiKey));
constructor(private context: vscode.ExtensionContext, private type: AuthProviderType, private telemetryReporter: ExperimentationTelemetry) {
this._keychain = new Keychain(context, `${type}.auth`);
this._githubServer = new GitHubServer(type, telemetryReporter);
this._githubServer = new GitHubServer(type, this._telemetryReporter);
// Contains the current state of the sessions we have available.
this._sessionsPromise = this.readSessions();
const friendlyName = this.type === AuthProviderType.github ? 'GitHub' : 'GitHub Enterprise';
this._disposable = vscode.Disposable.from(
this._telemetryReporter,
this.type === AuthProviderType.github ? vscode.window.registerUriHandler(uriHandler) : { dispose() { } },
vscode.commands.registerCommand(`${this.type}.provide-token`, () => this.manuallyProvideToken()),
vscode.authentication.registerAuthenticationProvider(this.type, friendlyName, this, { supportsMultipleAccounts: false }),
this.context.secrets.onDidChange(() => this.checkForUpdates())
);
}
dispose() {
this._disposable.dispose();
}
get onDidChangeSessions() {
return this._sessionChangeEmitter.event;
}
public async initialize(): Promise<void> {
try {
this._sessions = await this.readSessions();
await this.verifySessions();
} catch (e) {
// Ignore, network request failed
}
let friendlyName = 'GitHub';
if (this.type === AuthProviderType.github) {
this.context.subscriptions.push(vscode.window.registerUriHandler(uriHandler));
}
if (this.type === AuthProviderType['github-enterprise']) {
friendlyName = 'GitHub Enterprise';
}
this.context.subscriptions.push(vscode.commands.registerCommand(`${this.type}.provide-token`, () => this.manuallyProvideToken()));
this.context.subscriptions.push(vscode.authentication.registerAuthenticationProvider(this.type, friendlyName, this, { supportsMultipleAccounts: false }));
this.context.subscriptions.push(this.context.secrets.onDidChange(() => this.checkForUpdates()));
}
async getSessions(scopes?: string[]): Promise<vscode.AuthenticationSession[]> {
return scopes
? this._sessions.filter(session => arrayEquals([...session.scopes].sort(), scopes.sort()))
: this._sessions;
Logger.info(`Getting sessions for ${scopes?.join(',') || 'all scopes'}...`);
const sessions = await this._sessionsPromise;
const finalSessions = scopes
? sessions.filter(session => arrayEquals([...session.scopes].sort(), scopes.sort()))
: sessions;
Logger.info(`Got ${finalSessions.length} sessions for ${scopes?.join(',') || 'all scopes'}...`);
return finalSessions;
}
private async afterTokenLoad(token: string): Promise<void> {
if (this.type === AuthProviderType.github) {
this._githubServer.checkIsEdu(token);
}
if (this.type === AuthProviderType['github-enterprise']) {
if (this.type === AuthProviderType.githubEnterprise) {
this._githubServer.checkEnterpriseVersion(token);
}
}
private async verifySessions(): Promise<void> {
const verifiedSessions: vscode.AuthenticationSession[] = [];
const verificationPromises = this._sessions.map(async session => {
try {
await this._githubServer.getUserInfo(session.accessToken);
this.afterTokenLoad(session.accessToken);
Logger.info(`Verified session with the following scopes: ${session.scopes}`);
verifiedSessions.push(session);
} catch (e) {
// Remove sessions that return unauthorized response
if (e.message !== 'Unauthorized') {
verifiedSessions.push(session);
}
}
});
Promise.all(verificationPromises).then(_ => {
if (this._sessions.length !== verifiedSessions.length) {
this._sessions = verifiedSessions;
this.storeSessions();
}
});
}
private async checkForUpdates() {
let storedSessions: vscode.AuthenticationSession[];
try {
storedSessions = await this.readSessions();
} catch (e) {
// Ignore, network request failed
return;
}
const previousSessions = await this._sessionsPromise;
this._sessionsPromise = this.readSessions();
const storedSessions = await this._sessionsPromise;
const added: vscode.AuthenticationSession[] = [];
const removed: vscode.AuthenticationSession[] = [];
storedSessions.forEach(session => {
const matchesExisting = this._sessions.some(s => s.id === session.id);
const matchesExisting = previousSessions.some(s => s.id === session.id);
// Another window added a session to the keychain, add it to our state as well
if (!matchesExisting) {
Logger.info('Adding session found in keychain');
this._sessions.push(session);
added.push(session);
}
});
this._sessions.forEach(session => {
previousSessions.forEach(session => {
const matchesExisting = storedSessions.some(s => s.id === session.id);
// Another window has logged out, remove from our state
if (!matchesExisting) {
Logger.info('Removing session no longer found in keychain');
const sessionIndex = this._sessions.findIndex(s => s.id === session.id);
if (sessionIndex > -1) {
this._sessions.splice(sessionIndex, 1);
}
removed.push(session);
}
});
@ -146,51 +117,74 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid
}
private async readSessions(): Promise<vscode.AuthenticationSession[]> {
const storedSessions = await this._keychain.getToken() || await this._keychain.tryMigrate();
if (storedSessions) {
try {
const sessionData: SessionData[] = JSON.parse(storedSessions);
const sessionPromises = sessionData.map(async (session: SessionData): Promise<vscode.AuthenticationSession> => {
const needsUserInfo = !session.account;
let userInfo: { id: string, accountName: string };
if (needsUserInfo) {
userInfo = await this._githubServer.getUserInfo(session.accessToken);
}
Logger.trace(`Read the following session from the keychain with the following scopes: ${session.scopes}`);
return {
id: session.id,
account: {
label: session.account
? session.account.label || session.account.displayName!
: userInfo!.accountName,
id: session.account?.id ?? userInfo!.id
},
scopes: session.scopes,
accessToken: session.accessToken
};
});
return Promise.all(sessionPromises);
} catch (e) {
if (e === NETWORK_ERROR) {
return [];
}
Logger.error(`Error reading sessions: ${e}`);
await this._keychain.deleteToken();
let sessionData: SessionData[];
try {
Logger.info('Reading sessions from keychain...');
const storedSessions = await this._keychain.getToken() || await this._keychain.tryMigrate();
if (!storedSessions) {
return [];
}
Logger.info('Got stored sessions!');
try {
sessionData = JSON.parse(storedSessions);
} catch (e) {
await this._keychain.deleteToken();
throw e;
}
} catch (e) {
Logger.error(`Error reading token: ${e}`);
return [];
}
return [];
const sessionPromises = sessionData.map(async (session: SessionData) => {
let userInfo: { id: string, accountName: string } | undefined;
if (!session.account) {
try {
userInfo = await this._githubServer.getUserInfo(session.accessToken);
Logger.info(`Verified session with the following scopes: ${session.scopes}`);
} catch (e) {
// Remove sessions that return unauthorized response
if (e.message === 'Unauthorized') {
return undefined;
}
}
}
setTimeout(() => this.afterTokenLoad(session.accessToken), 1000);
Logger.trace(`Read the following session from the keychain with the following scopes: ${session.scopes}`);
return {
id: session.id,
account: {
label: session.account
? session.account.label ?? session.account.displayName ?? '<unknown>'
: userInfo?.accountName ?? '<unknown>',
id: session.account?.id ?? userInfo?.id ?? '<unknown>'
},
scopes: session.scopes,
accessToken: session.accessToken
};
});
const verifiedSessions = (await Promise.allSettled(sessionPromises))
.filter(p => p.status === 'fulfilled')
.map(p => (p as PromiseFulfilledResult<vscode.AuthenticationSession | undefined>).value)
.filter(<T>(p?: T): p is T => Boolean(p));
Logger.info(`Got ${verifiedSessions.length} verified sessions.`);
if (verifiedSessions.length !== sessionData.length) {
await this.storeSessions(verifiedSessions);
}
return verifiedSessions;
}
private async storeSessions(): Promise<void> {
await this._keychain.setToken(JSON.stringify(this._sessions));
}
get sessions(): vscode.AuthenticationSession[] {
return this._sessions;
private async storeSessions(sessions: vscode.AuthenticationSession[]): Promise<void> {
Logger.info(`Storing ${sessions.length} sessions...`);
this._sessionsPromise = Promise.resolve(sessions);
await this._keychain.setToken(JSON.stringify(sessions));
Logger.info(`Stored ${sessions.length} sessions!`);
}
public async createSession(scopes: string[]): Promise<vscode.AuthenticationSession> {
@ -200,14 +194,23 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid
"scopes": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" }
}
*/
this.telemetryReporter?.sendTelemetryEvent('login', {
this._telemetryReporter?.sendTelemetryEvent('login', {
scopes: JSON.stringify(scopes),
});
const token = await this._githubServer.login(scopes.join(' '));
this.afterTokenLoad(token);
const session = await this.tokenToSession(token, scopes);
await this.setToken(session);
const sessions = await this._sessionsPromise;
const sessionIndex = sessions.findIndex(s => s.id === session.id);
if (sessionIndex > -1) {
sessions.splice(sessionIndex, 1, session);
} else {
sessions.push(session);
}
await this.storeSessions(sessions);
this._sessionChangeEmitter.fire({ added: [session], removed: [], changed: [] });
Logger.info('Login success!');
@ -219,14 +222,14 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid
/* __GDPR__
"loginCancelled" : { }
*/
this.telemetryReporter?.sendTelemetryEvent('loginCancelled');
this._telemetryReporter?.sendTelemetryEvent('loginCancelled');
throw e;
}
/* __GDPR__
"loginFailed" : { }
*/
this.telemetryReporter?.sendTelemetryEvent('loginFailed');
this._telemetryReporter?.sendTelemetryEvent('loginFailed');
vscode.window.showErrorMessage(`Sign in failed: ${e}`);
Logger.error(e);
@ -248,40 +251,32 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid
};
}
private async setToken(session: vscode.AuthenticationSession): Promise<void> {
const sessionIndex = this._sessions.findIndex(s => s.id === session.id);
if (sessionIndex > -1) {
this._sessions.splice(sessionIndex, 1, session);
} else {
this._sessions.push(session);
}
await this.storeSessions();
}
public async removeSession(id: string) {
try {
/* __GDPR__
"logout" : { }
*/
this.telemetryReporter?.sendTelemetryEvent('logout');
this._telemetryReporter?.sendTelemetryEvent('logout');
Logger.info(`Logging out of ${id}`);
const sessionIndex = this._sessions.findIndex(session => session.id === id);
const sessions = await this._sessionsPromise;
const sessionIndex = sessions.findIndex(session => session.id === id);
if (sessionIndex > -1) {
const session = this._sessions[sessionIndex];
this._sessions.splice(sessionIndex, 1);
const session = sessions[sessionIndex];
sessions.splice(sessionIndex, 1);
await this.storeSessions(sessions);
this._sessionChangeEmitter.fire({ added: [], removed: [session], changed: [] });
} else {
Logger.error('Session not found');
}
await this.storeSessions();
} catch (e) {
/* __GDPR__
"logoutFailed" : { }
*/
this.telemetryReporter?.sendTelemetryEvent('logoutFailed');
this._telemetryReporter?.sendTelemetryEvent('logoutFailed');
vscode.window.showErrorMessage(`Sign out failed: ${e}`);
Logger.error(e);

View file

@ -45,7 +45,7 @@ export class GitHubServer {
constructor(private type: AuthProviderType, private readonly telemetryReporter: ExperimentationTelemetry) { }
private isTestEnvironment(url: vscode.Uri): boolean {
return this.type === AuthProviderType['github-enterprise'] || /\.azurewebsites\.net$/.test(url.authority) || url.authority.startsWith('localhost:');
return this.type === AuthProviderType.githubEnterprise || /\.azurewebsites\.net$/.test(url.authority) || url.authority.startsWith('localhost:');
}
// TODO@joaomoreno TODO@RMacfarlane
@ -169,14 +169,14 @@ export class GitHubServer {
};
private getServerUri(path?: string) {
const apiUri = this.type === AuthProviderType['github-enterprise']
const apiUri = this.type === AuthProviderType.githubEnterprise
? vscode.Uri.parse(vscode.workspace.getConfiguration('github-enterprise').get<string>('uri') || '', true)
: vscode.Uri.parse('https://api.github.com');
if (!path) {
path = '';
}
if (this.type === AuthProviderType['github-enterprise']) {
if (this.type === AuthProviderType.githubEnterprise) {
path = '/api/v3' + path;
}

View file

@ -25,31 +25,6 @@
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.0.0.tgz#165aae4819ad2174a17476dbe66feebd549556c0"
integrity sha512-xSQfNcvOiE5f9dyd4Kzxbof1aTrLobL278pGLKOZI6esGfZ7ts9Ka16CzIN6Y8hFHE1C7jIBZokULhK1bOgjRw==
applicationinsights@1.7.4:
version "1.7.4"
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-1.7.4.tgz#e7d96435594d893b00cf49f70a5927105dbb8749"
integrity sha512-XFLsNlcanpjFhHNvVWEfcm6hr7lu9znnb6Le1Lk5RE03YUV9X2B2n2MfM4kJZRrUdV+C0hdHxvWyv+vWoLfY7A==
dependencies:
cls-hooked "^4.2.2"
continuation-local-storage "^3.2.1"
diagnostic-channel "0.2.0"
diagnostic-channel-publishers "^0.3.3"
async-hook-jl@^1.7.6:
version "1.7.6"
resolved "https://registry.yarnpkg.com/async-hook-jl/-/async-hook-jl-1.7.6.tgz#4fd25c2f864dbaf279c610d73bf97b1b28595e68"
integrity sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==
dependencies:
stack-chain "^1.3.7"
async-listener@^0.6.0:
version "0.6.10"
resolved "https://registry.yarnpkg.com/async-listener/-/async-listener-0.6.10.tgz#a7c97abe570ba602d782273c0de60a51e3e17cbc"
integrity sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==
dependencies:
semver "^5.3.0"
shimmer "^1.1.0"
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
@ -62,15 +37,6 @@ axios@^0.21.1:
dependencies:
follow-redirects "^1.10.0"
cls-hooked@^4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908"
integrity sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==
dependencies:
async-hook-jl "^1.7.6"
emitter-listener "^1.0.1"
semver "^5.4.1"
combined-stream@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
@ -78,38 +44,11 @@ combined-stream@^1.0.8:
dependencies:
delayed-stream "~1.0.0"
continuation-local-storage@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz#11f613f74e914fe9b34c92ad2d28fe6ae1db7ffb"
integrity sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==
dependencies:
async-listener "^0.6.0"
emitter-listener "^1.1.1"
delayed-stream@~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=
diagnostic-channel-publishers@^0.3.3:
version "0.3.5"
resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.5.tgz#a84a05fd6cc1d7619fdd17791c17e540119a7536"
integrity sha512-AOIjw4T7Nxl0G2BoBPhkQ6i7T4bUd9+xvdYizwvG7vVAM1dvr+SDrcUudlmzwH0kbEwdR2V1EcnKT0wAeYLQNQ==
diagnostic-channel@0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz#cc99af9612c23fb1fff13612c72f2cbfaa8d5a17"
integrity sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=
dependencies:
semver "^5.3.0"
emitter-listener@^1.0.1, emitter-listener@^1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/emitter-listener/-/emitter-listener-1.1.2.tgz#56b140e8f6992375b3d7cb2cab1cc7432d9632e8"
integrity sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==
dependencies:
shimmer "^1.2.0"
follow-redirects@^1.10.0:
version "1.13.3"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.3.tgz#e5598ad50174c1bc4e872301e82ac2cd97f90267"
@ -141,21 +80,6 @@ node-fetch@2.6.1:
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
semver@^5.3.0, semver@^5.4.1:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
shimmer@^1.1.0, shimmer@^1.2.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337"
integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==
stack-chain@^1.3.7:
version "1.3.7"
resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285"
integrity sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=
tas-client@0.1.21:
version "0.1.21"
resolved "https://registry.yarnpkg.com/tas-client/-/tas-client-0.1.21.tgz#62275d5f75266eaae408f7463364748cb92f220d"
@ -168,12 +92,10 @@ uuid@8.1.0:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.1.0.tgz#6f1536eb43249f473abc6bd58ff983da1ca30d8d"
integrity sha512-CI18flHDznR0lq54xBycOVmphdCYnQLKn8abKn7PXUiKUGdEd+/l9LWNJmugXel4hXq7S+RMNl34ecyC9TntWg==
vscode-extension-telemetry@0.1.7:
version "0.1.7"
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.7.tgz#18389bc24127c89dade29cd2b71ba69a6ee6ad26"
integrity sha512-pZuZTHO9OpsrwlerOKotWBRLRYJ53DobYb7aWiRAXjlqkuqE+YJJaP+2WEy8GrLIF1EnitXTDMaTAKsmLQ5ORQ==
dependencies:
applicationinsights "1.7.4"
vscode-extension-telemetry@0.2.8:
version "0.2.8"
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.2.8.tgz#670c625c44791237c040cee2cb9f567ca34784ac"
integrity sha512-Vf52im5qzORRD2K5Ryp8PXo31YXVcJAYRSDDZGegWlt0OATOd83DYabS1U/WIq9nR5g80UQKH3+BsenhpQHUaA==
vscode-nls@^5.0.0:
version "5.0.0"

View file

@ -1,3 +1,4 @@
build/**
test/**
.vscode/**
server/.vscode/**

View file

@ -240,7 +240,7 @@
]
},
"dependencies": {
"vscode-extension-telemetry": "0.1.7",
"vscode-extension-telemetry": "0.2.8",
"vscode-languageclient": "^7.0.0",
"vscode-nls": "^5.0.0"
},

View file

@ -10,7 +10,7 @@
"main": "./out/node/htmlServerMain",
"dependencies": {
"vscode-css-languageservice": "^5.1.4",
"vscode-html-languageservice": "^4.0.6",
"vscode-html-languageservice": "^4.0.7",
"vscode-languageserver": "^7.0.0",
"vscode-languageserver-textdocument": "^1.0.1",
"vscode-nls": "^5.0.0",

View file

@ -22,10 +22,10 @@ vscode-css-languageservice@^5.1.4:
vscode-nls "^5.0.0"
vscode-uri "^3.0.2"
vscode-html-languageservice@^4.0.6:
version "4.0.6"
resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-4.0.6.tgz#c0a538077eb491730f49a47ab13ed7991bd8a45a"
integrity sha512-p1VK0+7JLzBFfbUrENm3QcBNbDzJUVhVnXOxHdC9XmgcubQBUINyzNeYio93srOafjRMQcJmzugB4vfmUnbCQg==
vscode-html-languageservice@^4.0.7:
version "4.0.7"
resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-4.0.7.tgz#94f2ed22c821965f828222d13b5aa541b358d992"
integrity sha512-P5TQMYpgxAdLs+PwpC7Lm+0lXCyQAC6kZ41YuPYNHVooC4XO7Y2+ncHBcQJVK4C9LU2cTOAl0lzq4WAxuwRHYw==
dependencies:
vscode-languageserver-textdocument "^1.0.1"
vscode-languageserver-types "^3.16.0"

View file

@ -7,31 +7,6 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.43.tgz#26bcbb0595b305400e8ceaf9a127a7f905ae49c8"
integrity sha512-3pwDJjp1PWacPTpH0LcfhgjvurQvrZFBrC6xxjaUEZ7ifUtT32jtjPxEMMblpqd2Mvx+k8haqQJLQxolyGN/cQ==
applicationinsights@1.7.4:
version "1.7.4"
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-1.7.4.tgz#e7d96435594d893b00cf49f70a5927105dbb8749"
integrity sha512-XFLsNlcanpjFhHNvVWEfcm6hr7lu9znnb6Le1Lk5RE03YUV9X2B2n2MfM4kJZRrUdV+C0hdHxvWyv+vWoLfY7A==
dependencies:
cls-hooked "^4.2.2"
continuation-local-storage "^3.2.1"
diagnostic-channel "0.2.0"
diagnostic-channel-publishers "^0.3.3"
async-hook-jl@^1.7.6:
version "1.7.6"
resolved "https://registry.yarnpkg.com/async-hook-jl/-/async-hook-jl-1.7.6.tgz#4fd25c2f864dbaf279c610d73bf97b1b28595e68"
integrity sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==
dependencies:
stack-chain "^1.3.7"
async-listener@^0.6.0:
version "0.6.10"
resolved "https://registry.yarnpkg.com/async-listener/-/async-listener-0.6.10.tgz#a7c97abe570ba602d782273c0de60a51e3e17cbc"
integrity sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==
dependencies:
semver "^5.3.0"
shimmer "^1.1.0"
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
@ -45,47 +20,11 @@ brace-expansion@^1.1.7:
balanced-match "^1.0.0"
concat-map "0.0.1"
cls-hooked@^4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908"
integrity sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==
dependencies:
async-hook-jl "^1.7.6"
emitter-listener "^1.0.1"
semver "^5.4.1"
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
continuation-local-storage@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz#11f613f74e914fe9b34c92ad2d28fe6ae1db7ffb"
integrity sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==
dependencies:
async-listener "^0.6.0"
emitter-listener "^1.1.1"
diagnostic-channel-publishers@^0.3.3:
version "0.3.5"
resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.5.tgz#a84a05fd6cc1d7619fdd17791c17e540119a7536"
integrity sha512-AOIjw4T7Nxl0G2BoBPhkQ6i7T4bUd9+xvdYizwvG7vVAM1dvr+SDrcUudlmzwH0kbEwdR2V1EcnKT0wAeYLQNQ==
diagnostic-channel@0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz#cc99af9612c23fb1fff13612c72f2cbfaa8d5a17"
integrity sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=
dependencies:
semver "^5.3.0"
emitter-listener@^1.0.1, emitter-listener@^1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/emitter-listener/-/emitter-listener-1.1.2.tgz#56b140e8f6992375b3d7cb2cab1cc7432d9632e8"
integrity sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==
dependencies:
shimmer "^1.2.0"
lru-cache@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
@ -100,16 +39,6 @@ minimatch@^3.0.4:
dependencies:
brace-expansion "^1.1.7"
semver@^5.3.0:
version "5.5.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477"
integrity sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==
semver@^5.4.1:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
semver@^7.3.4:
version "7.3.4"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97"
@ -117,22 +46,10 @@ semver@^7.3.4:
dependencies:
lru-cache "^6.0.0"
shimmer@^1.1.0, shimmer@^1.2.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337"
integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==
stack-chain@^1.3.7:
version "1.3.7"
resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285"
integrity sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=
vscode-extension-telemetry@0.1.7:
version "0.1.7"
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.7.tgz#18389bc24127c89dade29cd2b71ba69a6ee6ad26"
integrity sha512-pZuZTHO9OpsrwlerOKotWBRLRYJ53DobYb7aWiRAXjlqkuqE+YJJaP+2WEy8GrLIF1EnitXTDMaTAKsmLQ5ORQ==
dependencies:
applicationinsights "1.7.4"
vscode-extension-telemetry@0.2.8:
version "0.2.8"
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.2.8.tgz#670c625c44791237c040cee2cb9f567ca34784ac"
integrity sha512-Vf52im5qzORRD2K5Ryp8PXo31YXVcJAYRSDDZGegWlt0OATOd83DYabS1U/WIq9nR5g80UQKH3+BsenhpQHUaA==
vscode-jsonrpc@6.0.0:
version "6.0.0"

View file

@ -1,2 +1,3 @@
build/**
test/**
cgmanifest.json

View file

@ -81,7 +81,7 @@
"watch-web": "npx webpack-cli --config extension-browser.webpack.config --mode none --watch --info-verbosity verbose"
},
"dependencies": {
"vscode-extension-telemetry": "0.1.7",
"vscode-extension-telemetry": "0.2.8",
"vscode-nls": "^5.0.0"
},
"repository": {

View file

@ -12,7 +12,6 @@ import { BinarySizeStatusBarEntry } from './binarySizeStatusBarEntry';
const localize = nls.loadMessageBundle();
export class PreviewManager implements vscode.CustomReadonlyEditorProvider {
public static readonly viewType = 'imagePreview.previewEditor';
@ -262,6 +261,8 @@ class Preview extends Disposable {
}
}
declare const process: undefined | { readonly platform: string };
function isMac(): boolean {
if (typeof process === 'undefined') {
return false;

View file

@ -5,4 +5,3 @@
/// <reference path='../../../../src/vs/vscode.d.ts'/>
/// <reference path='../../../../src/vs/vscode.proposed.d.ts'/>
/// <reference types='@types/node'/>

View file

@ -2,7 +2,7 @@
"extends": "../tsconfig.base.json",
"compilerOptions": {
"outDir": "./out",
"experimentalDecorators": true
"types": []
},
"include": [
"src/**/*"

View file

@ -2,93 +2,10 @@
# yarn lockfile v1
applicationinsights@1.7.4:
version "1.7.4"
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-1.7.4.tgz#e7d96435594d893b00cf49f70a5927105dbb8749"
integrity sha512-XFLsNlcanpjFhHNvVWEfcm6hr7lu9znnb6Le1Lk5RE03YUV9X2B2n2MfM4kJZRrUdV+C0hdHxvWyv+vWoLfY7A==
dependencies:
cls-hooked "^4.2.2"
continuation-local-storage "^3.2.1"
diagnostic-channel "0.2.0"
diagnostic-channel-publishers "^0.3.3"
async-hook-jl@^1.7.6:
version "1.7.6"
resolved "https://registry.yarnpkg.com/async-hook-jl/-/async-hook-jl-1.7.6.tgz#4fd25c2f864dbaf279c610d73bf97b1b28595e68"
integrity sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==
dependencies:
stack-chain "^1.3.7"
async-listener@^0.6.0:
version "0.6.10"
resolved "https://registry.yarnpkg.com/async-listener/-/async-listener-0.6.10.tgz#a7c97abe570ba602d782273c0de60a51e3e17cbc"
integrity sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==
dependencies:
semver "^5.3.0"
shimmer "^1.1.0"
cls-hooked@^4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908"
integrity sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==
dependencies:
async-hook-jl "^1.7.6"
emitter-listener "^1.0.1"
semver "^5.4.1"
continuation-local-storage@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz#11f613f74e914fe9b34c92ad2d28fe6ae1db7ffb"
integrity sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==
dependencies:
async-listener "^0.6.0"
emitter-listener "^1.1.1"
diagnostic-channel-publishers@^0.3.3:
version "0.3.5"
resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.5.tgz#a84a05fd6cc1d7619fdd17791c17e540119a7536"
integrity sha512-AOIjw4T7Nxl0G2BoBPhkQ6i7T4bUd9+xvdYizwvG7vVAM1dvr+SDrcUudlmzwH0kbEwdR2V1EcnKT0wAeYLQNQ==
diagnostic-channel@0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz#cc99af9612c23fb1fff13612c72f2cbfaa8d5a17"
integrity sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=
dependencies:
semver "^5.3.0"
emitter-listener@^1.0.1, emitter-listener@^1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/emitter-listener/-/emitter-listener-1.1.2.tgz#56b140e8f6992375b3d7cb2cab1cc7432d9632e8"
integrity sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==
dependencies:
shimmer "^1.2.0"
semver@^5.3.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
integrity sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==
semver@^5.4.1:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
shimmer@^1.1.0, shimmer@^1.2.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337"
integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==
stack-chain@^1.3.7:
version "1.3.7"
resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285"
integrity sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=
vscode-extension-telemetry@0.1.7:
version "0.1.7"
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.7.tgz#18389bc24127c89dade29cd2b71ba69a6ee6ad26"
integrity sha512-pZuZTHO9OpsrwlerOKotWBRLRYJ53DobYb7aWiRAXjlqkuqE+YJJaP+2WEy8GrLIF1EnitXTDMaTAKsmLQ5ORQ==
dependencies:
applicationinsights "1.7.4"
vscode-extension-telemetry@0.2.8:
version "0.2.8"
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.2.8.tgz#670c625c44791237c040cee2cb9f567ca34784ac"
integrity sha512-Vf52im5qzORRD2K5Ryp8PXo31YXVcJAYRSDDZGegWlt0OATOd83DYabS1U/WIq9nR5g80UQKH3+BsenhpQHUaA==
vscode-nls@^5.0.0:
version "5.0.0"

View file

@ -7,4 +7,3 @@
This extension provides the following Jupyter-related features for VS Code:
- Open, edit and save .ipynb files
- Create New Jupyter Notebook command

View file

@ -12,9 +12,9 @@
"onNotebook:jupyter-notebook"
],
"extensionKind": [
"web",
"ui",
"workspace"
"workspace",
"web",
"ui"
],
"main": "./out/ipynbMain.js",
"browser": "./dist/browser/ipynbMain.js",
@ -36,6 +36,16 @@
]
}
],
"grammars": [
{
"language": "jupyter",
"scopeName": "source.jupyter",
"path": "./syntaxes/jupyter.tmLanguage.json",
"embeddedLanguages": {
"source.json": "json"
}
}
],
"notebooks": [
{
"type": "jupyter-notebook",
@ -54,6 +64,7 @@
"watch": "npx gulp watch-extension:ipynb"
},
"dependencies": {
"@enonic/fnv-plus": "^1.3.0",
"detect-indent": "^6.0.0"
},
"devDependencies": {

View file

@ -0,0 +1,42 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { nbformat } from '@jupyterlab/coreutils';
/**
* Metadata we store in VS Code cell output items.
* This contains the original metadata from the Jupyter outputs.
*/
export interface CellOutputMetadata {
/**
* Cell output metadata.
*/
metadata?: any;
/**
* Transient data from Jupyter.
*/
transient?: {
/**
* This is used for updating the output in other cells.
* We don't know of other properties, but this is definitely used.
*/
display_id?: string;
} & any;
/**
* Original cell output type
*/
outputType: nbformat.OutputType | string;
executionCount?: nbformat.IExecuteResult['ExecutionCount'];
/**
* Whether the original Mime data is JSON or not.
* This properly only exists in metadata for NotebookCellOutputItems
* (this is something we have added)
*/
__isJson?: boolean;
}

View file

@ -0,0 +1,347 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { nbformat } from '@jupyterlab/coreutils';
import { extensions, NotebookCellData, NotebookCellExecutionSummary, NotebookCellKind, NotebookCellOutput, NotebookCellOutputItem, NotebookData } from 'vscode';
import { CellOutputMetadata } from './common';
const jupyterLanguageToMonacoLanguageMapping = new Map([
['c#', 'csharp'],
['f#', 'fsharp'],
['q#', 'qsharp'],
['c++11', 'c++'],
['c++12', 'c++'],
['c++14', 'c++']
]);
export function getPreferredLanguage(metadata?: nbformat.INotebookMetadata) {
const jupyterLanguage =
metadata?.language_info?.name ||
(metadata?.kernelspec as any)?.language;
// Default to python language only if the Python extension is installed.
const defaultLanguage = extensions.getExtension('ms-python.python') ? 'python' : 'plaintext';
// Note, whatever language is returned here, when the user selects a kernel, the cells (of blank documents) get updated based on that kernel selection.
return translateKernelLanguageToMonaco(jupyterLanguage || defaultLanguage);
}
function translateKernelLanguageToMonaco(language: string): string {
language = language.toLowerCase();
if (language.length === 2 && language.endsWith('#')) {
return `${language.substring(0, 1)}sharp`;
}
return jupyterLanguageToMonacoLanguageMapping.get(language) || language;
}
const orderOfMimeTypes = [
'application/vnd.*',
'application/vdom.*',
'application/geo+json',
'application/x-nteract-model-debug+json',
'text/html',
'application/javascript',
'image/gif',
'text/latex',
'text/markdown',
'image/png',
'image/svg+xml',
'image/jpeg',
'application/json',
'text/plain'
];
function sortOutputItemsBasedOnDisplayOrder(outputItems: NotebookCellOutputItem[]): NotebookCellOutputItem[] {
return outputItems.sort((outputItemA, outputItemB) => {
const isMimeTypeMatch = (value: string, compareWith: string) => {
if (value.endsWith('.*')) {
value = value.substr(0, value.indexOf('.*'));
}
return compareWith.startsWith(value);
};
const indexOfMimeTypeA = orderOfMimeTypes.findIndex(mime => isMimeTypeMatch(outputItemA.mime, mime));
const indexOfMimeTypeB = orderOfMimeTypes.findIndex(mime => isMimeTypeMatch(outputItemB.mime, mime));
return indexOfMimeTypeA - indexOfMimeTypeB;
});
}
enum CellOutputMimeTypes {
error = 'application/vnd.code.notebook.error',
stderr = 'application/vnd.code.notebook.stderr',
stdout = 'application/vnd.code.notebook.stdout'
}
const textMimeTypes = ['text/plain', 'text/markdown', CellOutputMimeTypes.stderr, CellOutputMimeTypes.stdout];
function concatMultilineString(str: string | string[], trim?: boolean): string {
const nonLineFeedWhiteSpaceTrim = /(^[\t\f\v\r ]+|[\t\f\v\r ]+$)/g;
if (Array.isArray(str)) {
let result = '';
for (let i = 0; i < str.length; i += 1) {
const s = str[i];
if (i < str.length - 1 && !s.endsWith('\n')) {
result = result.concat(`${s}\n`);
} else {
result = result.concat(s);
}
}
// Just trim whitespace. Leave \n in place
return trim ? result.replace(nonLineFeedWhiteSpaceTrim, '') : result;
}
return trim ? str.toString().replace(nonLineFeedWhiteSpaceTrim, '') : str.toString();
}
function convertJupyterOutputToBuffer(mime: string, value: unknown): NotebookCellOutputItem {
if (!value) {
return NotebookCellOutputItem.text('', mime);
}
try {
if (
(mime.startsWith('text/') || textMimeTypes.includes(mime)) &&
(Array.isArray(value) || typeof value === 'string')
) {
const stringValue = Array.isArray(value) ? concatMultilineString(value) : value;
return NotebookCellOutputItem.text(stringValue, mime);
} else if (mime.startsWith('image/') && typeof value === 'string' && mime !== 'image/svg+xml') {
// Images in Jupyter are stored in base64 encoded format.
// VS Code expects bytes when rendering images.
if (typeof Buffer !== 'undefined' && typeof Buffer.from === 'function') {
return new NotebookCellOutputItem(Buffer.from(value, 'base64'), mime);
} else {
const data = Uint8Array.from(atob(value), c => c.charCodeAt(0));
return new NotebookCellOutputItem(data, mime);
}
} else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
return NotebookCellOutputItem.text(JSON.stringify(value), mime);
} else {
// For everything else, treat the data as strings (or multi-line strings).
value = Array.isArray(value) ? concatMultilineString(value) : value;
return NotebookCellOutputItem.text(value as string, mime);
}
} catch (ex) {
return NotebookCellOutputItem.error(ex);
}
}
/**
* Metadata we store in VS Code cells.
* This contains the original metadata from the Jupyuter cells.
*/
interface CellMetadata {
/**
* Stores attachments for cells.
*/
attachments?: nbformat.IAttachments;
/**
* Stores cell metadata.
*/
metadata?: Partial<nbformat.ICellMetadata>;
}
function getNotebookCellMetadata(cell: nbformat.IBaseCell): CellMetadata {
// We put this only for VSC to display in diff view.
// Else we don't use this.
const propertiesToClone: (keyof CellMetadata)[] = ['metadata', 'attachments'];
const custom: CellMetadata = {};
propertiesToClone.forEach((propertyToClone) => {
if (cell[propertyToClone]) {
custom[propertyToClone] = JSON.parse(JSON.stringify(cell[propertyToClone]));
}
});
return custom;
}
function getOutputMetadata(output: nbformat.IOutput): CellOutputMetadata {
// Add on transient data if we have any. This should be removed by our save functions elsewhere.
const metadata: CellOutputMetadata = {
outputType: output.output_type
};
if (output.transient) {
metadata.transient = output.transient;
}
switch (output.output_type as nbformat.OutputType) {
case 'display_data':
case 'execute_result':
case 'update_display_data': {
metadata.executionCount = output.execution_count;
metadata.metadata = output.metadata ? JSON.parse(JSON.stringify(output.metadata)) : {};
break;
}
default:
break;
}
return metadata;
}
function translateDisplayDataOutput(
output: nbformat.IDisplayData | nbformat.IDisplayUpdate | nbformat.IExecuteResult
): NotebookCellOutput {
// Metadata could be as follows:
// We'll have metadata specific to each mime type as well as generic metadata.
/*
IDisplayData = {
output_type: 'display_data',
data: {
'image/jpg': '/////'
'image/png': '/////'
'text/plain': '/////'
},
metadata: {
'image/png': '/////',
'background': true,
'xyz': '///
}
}
*/
const metadata = getOutputMetadata(output);
const items: NotebookCellOutputItem[] = [];
if (output.data) {
for (const key in output.data) {
items.push(convertJupyterOutputToBuffer(key, output.data[key]));
}
}
return new NotebookCellOutput(sortOutputItemsBasedOnDisplayOrder(items), metadata);
}
function translateErrorOutput(output?: nbformat.IError): NotebookCellOutput {
output = output || { output_type: 'error', ename: '', evalue: '', traceback: [] };
return new NotebookCellOutput(
[
NotebookCellOutputItem.error({
name: output?.ename || '',
message: output?.evalue || '',
stack: (output?.traceback || []).join('\n')
})
],
{ ...getOutputMetadata(output), originalError: output }
);
}
function translateStreamOutput(output: nbformat.IStream): NotebookCellOutput {
const value = concatMultilineString(output.text);
const item = output.name === 'stderr' ? NotebookCellOutputItem.stderr(value) : NotebookCellOutputItem.stdout(value);
return new NotebookCellOutput([item], getOutputMetadata(output));
}
const cellOutputMappers = new Map<nbformat.OutputType, (output: any) => NotebookCellOutput>();
cellOutputMappers.set('display_data', translateDisplayDataOutput);
cellOutputMappers.set('execute_result', translateDisplayDataOutput);
cellOutputMappers.set('update_display_data', translateDisplayDataOutput);
cellOutputMappers.set('error', translateErrorOutput);
cellOutputMappers.set('stream', translateStreamOutput);
function jupyterCellOutputToCellOutput(output: nbformat.IOutput): NotebookCellOutput {
/**
* Stream, `application/x.notebook.stream`
* Error, `application/x.notebook.error-traceback`
* Rich, { mime: value }
*
* outputs: [
new vscode.NotebookCellOutput([
new vscode.NotebookCellOutputItem('application/x.notebook.stream', 2),
new vscode.NotebookCellOutputItem('application/x.notebook.stream', 3),
]),
new vscode.NotebookCellOutput([
new vscode.NotebookCellOutputItem('text/markdown', '## header 2'),
new vscode.NotebookCellOutputItem('image/svg+xml', [
"<svg baseProfile=\"full\" height=\"200\" version=\"1.1\" width=\"300\" xmlns=\"http://www.w3.org/2000/svg\">\n",
" <rect fill=\"blue\" height=\"100%\" width=\"100%\"/>\n",
" <circle cx=\"150\" cy=\"100\" fill=\"green\" r=\"80\"/>\n",
" <text fill=\"white\" font-size=\"60\" text-anchor=\"middle\" x=\"150\" y=\"125\">SVG</text>\n",
"</svg>"
]),
]),
]
*
*/
const fn = cellOutputMappers.get(output.output_type as nbformat.OutputType);
let result: NotebookCellOutput;
if (fn) {
result = fn(output);
} else {
result = translateDisplayDataOutput(output as any);
}
return result;
}
function createNotebookCellDataFromRawCell(cell: nbformat.IRawCell): NotebookCellData {
const cellData = new NotebookCellData(NotebookCellKind.Code, concatMultilineString(cell.source), 'raw');
cellData.outputs = [];
cellData.metadata = { custom: getNotebookCellMetadata(cell) };
return cellData;
}
function createNotebookCellDataFromMarkdownCell(cell: nbformat.IMarkdownCell): NotebookCellData {
const cellData = new NotebookCellData(
NotebookCellKind.Markup,
concatMultilineString(cell.source),
'markdown'
);
cellData.outputs = [];
cellData.metadata = { custom: getNotebookCellMetadata(cell) };
return cellData;
}
function createNotebookCellDataFromCodeCell(cell: nbformat.ICodeCell, cellLanguage: string): NotebookCellData {
const cellOutputs = Array.isArray(cell.outputs) ? cell.outputs : [];
const outputs = cellOutputs.map(jupyterCellOutputToCellOutput);
const hasExecutionCount = typeof cell.execution_count === 'number' && cell.execution_count > 0;
const source = concatMultilineString(cell.source);
const executionSummary: NotebookCellExecutionSummary = hasExecutionCount
? { executionOrder: cell.execution_count as number }
: {};
const cellData = new NotebookCellData(NotebookCellKind.Code, source, cellLanguage);
cellData.outputs = outputs;
cellData.metadata = { custom: getNotebookCellMetadata(cell) };
cellData.executionSummary = executionSummary;
return cellData;
}
function createNotebookCellDataFromJupyterCell(
cellLanguage: string,
cell: nbformat.IBaseCell
): NotebookCellData | undefined {
switch (cell.cell_type) {
case 'raw': {
return createNotebookCellDataFromRawCell(cell as nbformat.IRawCell);
}
case 'markdown': {
return createNotebookCellDataFromMarkdownCell(cell as nbformat.IMarkdownCell);
}
case 'code': {
return createNotebookCellDataFromCodeCell(cell as nbformat.ICodeCell, cellLanguage);
}
}
return;
}
/**
* Converts a NotebookModel into VS Code format.
*/
export function jupyterNotebookModelToNotebookData(
notebookContent: Partial<nbformat.INotebookContent>,
preferredLanguage: string
): NotebookData {
const notebookContentWithoutCells = { ...notebookContent, cells: [] };
if (!notebookContent.cells || notebookContent.cells.length === 0) {
throw new Error('Notebook content is missing cells');
}
const cells = notebookContent.cells
.map(cell => createNotebookCellDataFromJupyterCell(preferredLanguage, cell))
.filter((item): item is NotebookCellData => !!item);
const notebookData = new NotebookData(cells);
notebookData.metadata = { custom: notebookContentWithoutCells };
return notebookData;
}

View file

@ -1,709 +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 { nbformat } from '@jupyterlab/coreutils';
import { extensions, NotebookCell, NotebookCellData, NotebookCellExecutionSummary, NotebookCellKind, NotebookCellOutput, NotebookCellOutputItem, NotebookData } from 'vscode';
const jupyterLanguageToMonacoLanguageMapping = new Map([
['c#', 'csharp'],
['f#', 'fsharp'],
['q#', 'qsharp'],
['c++11', 'c++'],
['c++12', 'c++'],
['c++14', 'c++']
]);
export function getPreferredLanguage(metadata?: nbformat.INotebookMetadata) {
const jupyterLanguage =
metadata?.language_info?.name ||
(metadata?.kernelspec as any)?.language;
// Default to python language only if the Python extension is installed.
const defaultLanguage = extensions.getExtension('ms-python.python') ? 'python' : 'plaintext';
// Note, whatever language is returned here, when the user selects a kernel, the cells (of blank documents) get updated based on that kernel selection.
return translateKernelLanguageToMonaco(jupyterLanguage || defaultLanguage);
}
function translateKernelLanguageToMonaco(language: string): string {
language = language.toLowerCase();
if (language.length === 2 && language.endsWith('#')) {
return `${language.substring(0, 1)}sharp`;
}
return jupyterLanguageToMonacoLanguageMapping.get(language) || language;
}
const orderOfMimeTypes = [
'application/vnd.*',
'application/vdom.*',
'application/geo+json',
'application/x-nteract-model-debug+json',
'text/html',
'application/javascript',
'image/gif',
'text/latex',
'text/markdown',
'image/svg+xml',
'image/png',
'image/jpeg',
'application/json',
'text/plain'
];
function sortOutputItemsBasedOnDisplayOrder(outputItems: NotebookCellOutputItem[]): NotebookCellOutputItem[] {
return outputItems.sort((outputItemA, outputItemB) => {
const isMimeTypeMatch = (value: string, compareWith: string) => {
if (value.endsWith('.*')) {
value = value.substr(0, value.indexOf('.*'));
}
return compareWith.startsWith(value);
};
const indexOfMimeTypeA = orderOfMimeTypes.findIndex(mime => isMimeTypeMatch(outputItemA.mime, mime));
const indexOfMimeTypeB = orderOfMimeTypes.findIndex(mime => isMimeTypeMatch(outputItemB.mime, mime));
return indexOfMimeTypeA - indexOfMimeTypeB;
});
}
enum CellOutputMimeTypes {
error = 'application/vnd.code.notebook.error',
stderr = 'application/vnd.code.notebook.stderr',
stdout = 'application/vnd.code.notebook.stdout'
}
const textMimeTypes = ['text/plain', 'text/markdown', CellOutputMimeTypes.stderr, CellOutputMimeTypes.stdout];
function concatMultilineString(str: string | string[], trim?: boolean): string {
const nonLineFeedWhiteSpaceTrim = /(^[\t\f\v\r ]+|[\t\f\v\r ]+$)/g;
if (Array.isArray(str)) {
let result = '';
for (let i = 0; i < str.length; i += 1) {
const s = str[i];
if (i < str.length - 1 && !s.endsWith('\n')) {
result = result.concat(`${s}\n`);
} else {
result = result.concat(s);
}
}
// Just trim whitespace. Leave \n in place
return trim ? result.replace(nonLineFeedWhiteSpaceTrim, '') : result;
}
return trim ? str.toString().replace(nonLineFeedWhiteSpaceTrim, '') : str.toString();
}
function convertJupyterOutputToBuffer(mime: string, value: unknown): NotebookCellOutputItem {
if (!value) {
return NotebookCellOutputItem.text('', mime);
}
try {
if (
(mime.startsWith('text/') || textMimeTypes.includes(mime)) &&
(Array.isArray(value) || typeof value === 'string')
) {
const stringValue = Array.isArray(value) ? concatMultilineString(value) : value;
return NotebookCellOutputItem.text(stringValue, mime);
} else if (mime.startsWith('image/') && typeof value === 'string' && mime !== 'image/svg+xml') {
// Images in Jupyter are stored in base64 encoded format.
// VS Code expects bytes when rendering images.
const data = Uint8Array.from(atob(value), c => c.charCodeAt(0));
return new NotebookCellOutputItem(data, mime);
} else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
return NotebookCellOutputItem.text(JSON.stringify(value), mime);
} else {
// For everything else, treat the data as strings (or multi-line strings).
value = Array.isArray(value) ? concatMultilineString(value) : value;
return NotebookCellOutputItem.text(value as string, mime);
}
} catch (ex) {
return NotebookCellOutputItem.error(ex);
}
}
export function createJupyterCellFromNotebookCell(
vscCell: NotebookCell | NotebookCellData
): nbformat.IRawCell | nbformat.IMarkdownCell | nbformat.ICodeCell {
let cell: nbformat.IRawCell | nbformat.IMarkdownCell | nbformat.ICodeCell;
if (vscCell.kind === NotebookCellKind.Markup) {
cell = createMarkdownCellFromNotebookCell(vscCell);
} else if (
('document' in vscCell && vscCell.document.languageId === 'raw') ||
('languageId' in vscCell && vscCell.languageId === 'raw')
) {
cell = createRawCellFromNotebookCell(vscCell);
} else {
cell = createCodeCellFromNotebookCell(vscCell);
}
return cell;
}
function createCodeCellFromNotebookCell(cell: NotebookCell | NotebookCellData): nbformat.ICodeCell {
const cellMetadata = cell.metadata?.custom as CellMetadata | undefined;
const code = 'document' in cell ? cell.document.getText() : cell.value;
const codeCell: any = {
cell_type: 'code',
execution_count: cell.executionSummary?.executionOrder ?? null,
source: splitMultilineString(code),
outputs: (cell.outputs || []).map(translateCellDisplayOutput),
metadata: cellMetadata?.metadata || {} // This cannot be empty.
};
return codeCell;
}
function createRawCellFromNotebookCell(cell: NotebookCell | NotebookCellData): nbformat.IRawCell {
const cellMetadata = cell.metadata?.custom as CellMetadata | undefined;
const rawCell: any = {
cell_type: 'raw',
source: splitMultilineString('document' in cell ? cell.document.getText() : cell.value),
metadata: cellMetadata?.metadata || {} // This cannot be empty.
};
if (cellMetadata?.attachments) {
rawCell.attachments = cellMetadata.attachments;
}
return rawCell;
}
function splitMultilineString(source: nbformat.MultilineString): string[] {
if (Array.isArray(source)) {
return source as string[];
}
const str = source.toString();
if (str.length > 0) {
// Each line should be a separate entry, but end with a \n if not last entry
const arr = str.split('\n');
return arr
.map((s, i) => {
if (i < arr.length - 1) {
return `${s}\n`;
}
return s;
})
.filter(s => s.length > 0); // Skip last one if empty (it's the only one that could be length 0)
}
return [];
}
/**
* Metadata we store in VS Code cell output items.
* This contains the original metadata from the Jupyuter Outputs.
*/
interface CellOutputMetadata {
/**
* Cell output metadata.
*/
metadata?: any;
/**
* Transient data from Jupyter.
*/
transient?: {
/**
* This is used for updating the output in other cells.
* We don't know of others properties, but this is definitely used.
*/
display_id?: string;
} & any;
/**
* Original cell output type
*/
outputType: nbformat.OutputType | string;
executionCount?: nbformat.IExecuteResult['ExecutionCount'];
/**
* Whether the original Mime data is JSON or not.
* This properly only exists in metadata for NotebookCellOutputItems
* (this is something we have added)
*/
__isJson?: boolean;
}
function translateCellDisplayOutput(output: NotebookCellOutput): JupyterOutput {
const customMetadata = output.metadata as CellOutputMetadata | undefined;
let result: JupyterOutput;
// Possible some other extension added some output (do best effort to translate & save in ipynb).
// In which case metadata might not contain `outputType`.
const outputType = customMetadata?.outputType as nbformat.OutputType;
switch (outputType) {
case 'error': {
result = translateCellErrorOutput(output);
break;
}
case 'stream': {
result = convertStreamOutput(output);
break;
}
case 'display_data': {
result = {
output_type: 'display_data',
data: output.items.reduceRight((prev: any, curr) => {
prev[curr.mime] = convertOutputMimeToJupyterOutput(curr.mime, curr.data as Uint8Array);
return prev;
}, {}),
metadata: customMetadata?.metadata || {} // This can never be undefined.
};
break;
}
case 'execute_result': {
result = {
output_type: 'execute_result',
data: output.items.reduceRight((prev: any, curr) => {
prev[curr.mime] = convertOutputMimeToJupyterOutput(curr.mime, curr.data as Uint8Array);
return prev;
}, {}),
metadata: customMetadata?.metadata || {}, // This can never be undefined.
execution_count:
typeof customMetadata?.executionCount === 'number' ? customMetadata?.executionCount : null // This can never be undefined, only a number or `null`.
};
break;
}
case 'update_display_data': {
result = {
output_type: 'update_display_data',
data: output.items.reduceRight((prev: any, curr) => {
prev[curr.mime] = convertOutputMimeToJupyterOutput(curr.mime, curr.data as Uint8Array);
return prev;
}, {}),
metadata: customMetadata?.metadata || {} // This can never be undefined.
};
break;
}
default: {
const isError =
output.items.length === 1 && output.items.every((item) => item.mime === CellOutputMimeTypes.error);
const isStream = output.items.every(
(item) => item.mime === CellOutputMimeTypes.stderr || item.mime === CellOutputMimeTypes.stdout
);
if (isError) {
return translateCellErrorOutput(output);
}
// In the case of .NET & other kernels, we need to ensure we save ipynb correctly.
// Hence if we have stream output, save the output as Jupyter `stream` else `display_data`
// Unless we already know its an unknown output type.
const outputType: nbformat.OutputType =
<nbformat.OutputType>customMetadata?.outputType || (isStream ? 'stream' : 'display_data');
let unknownOutput: nbformat.IUnrecognizedOutput | nbformat.IDisplayData | nbformat.IStream;
if (outputType === 'stream') {
// If saving as `stream` ensure the mandatory properties are set.
unknownOutput = convertStreamOutput(output);
} else if (outputType === 'display_data') {
// If saving as `display_data` ensure the mandatory properties are set.
const displayData: nbformat.IDisplayData = {
data: {},
metadata: {},
output_type: 'display_data'
};
unknownOutput = displayData;
} else {
unknownOutput = {
output_type: outputType
};
}
if (customMetadata?.metadata) {
unknownOutput.metadata = customMetadata.metadata;
}
if (output.items.length > 0) {
unknownOutput.data = output.items.reduceRight((prev: any, curr) => {
prev[curr.mime] = convertOutputMimeToJupyterOutput(curr.mime, curr.data as Uint8Array);
return prev;
}, {});
}
result = unknownOutput;
break;
}
}
// Account for transient data as well
// `transient.display_id` is used to update cell output in other cells, at least thats one use case we know of.
if (result && customMetadata && customMetadata.transient) {
result.transient = customMetadata.transient;
}
return result;
}
function translateCellErrorOutput(output: NotebookCellOutput): nbformat.IError {
// it should have at least one output item
const firstItem = output.items[0];
// Bug in VS Code.
if (!firstItem.data) {
return {
output_type: 'error',
ename: '',
evalue: '',
traceback: []
};
}
const originalError: undefined | nbformat.IError = output.metadata?.originalError;
const value: Error = JSON.parse(new TextDecoder().decode(firstItem.data.buffer.slice(firstItem.data.byteOffset)));
return {
output_type: 'error',
ename: value.name,
evalue: value.message,
// VS Code needs an `Error` object which requires a `stack` property as a string.
// Its possible the format could change when converting from `traceback` to `string` and back again to `string`
// When .NET stores errors in output (with their .NET kernel),
// stack is empty, hence store the message instead of stack (so that somethign gets displayed in ipynb).
traceback: originalError?.traceback || splitMultilineString(value.stack || value.message || '')
};
}
function getOutputStreamType(output: NotebookCellOutput): string | undefined {
if (output.items.length > 0) {
return output.items[0].mime === CellOutputMimeTypes.stderr ? 'stderr' : 'stdout';
}
return;
}
type JupyterOutput =
| nbformat.IUnrecognizedOutput
| nbformat.IExecuteResult
| nbformat.IDisplayData
| nbformat.IStream
| nbformat.IError;
function convertStreamOutput(output: NotebookCellOutput): JupyterOutput {
const outputs = output.items
.filter((opit) => opit.mime === CellOutputMimeTypes.stderr || opit.mime === CellOutputMimeTypes.stdout)
.map((opit) => convertOutputMimeToJupyterOutput(opit.mime, opit.data as Uint8Array) as string)
.reduceRight<string[]>((prev, curr) => (Array.isArray(curr) ? prev.concat(...curr) : prev.concat(curr)), []);
const streamType = getOutputStreamType(output) || 'stdout';
return {
output_type: 'stream',
name: streamType,
text: splitMultilineString(outputs.join(''))
};
}
function convertOutputMimeToJupyterOutput(mime: string, value: Uint8Array) {
if (!value) {
return '';
}
try {
const stringValue = new TextDecoder().decode(value.buffer.slice(value.byteOffset));
if (mime === CellOutputMimeTypes.error) {
return JSON.parse(stringValue);
} else if (mime.startsWith('text/') || textMimeTypes.includes(mime)) {
return splitMultilineString(stringValue);
} else if (mime.startsWith('image/') && mime !== 'image/svg+xml') {
// Images in Jupyter are stored in base64 encoded format.
// VS Code expects bytes when rendering images.
// https://developer.mozilla.org/en-US/docs/Glossary/Base64#solution_1_%E2%80%93_escaping_the_string_before_encoding_it
return btoa(encodeURIComponent(stringValue).replace(/%([0-9A-F]{2})/g, function (_match, p1) {
return String.fromCharCode(Number.parseInt('0x' + p1));
}));
} else if (mime.toLowerCase().includes('json')) {
return stringValue.length > 0 ? JSON.parse(stringValue) : stringValue;
} else {
return stringValue;
}
} catch (ex) {
return '';
}
}
function createMarkdownCellFromNotebookCell(cell: NotebookCell | NotebookCellData): nbformat.IMarkdownCell {
const cellMetadata = cell.metadata?.custom as CellMetadata | undefined;
const markdownCell: any = {
cell_type: 'markdown',
source: splitMultilineString('document' in cell ? cell.document.getText() : cell.value),
metadata: cellMetadata?.metadata || {} // This cannot be empty.
};
if (cellMetadata?.attachments) {
markdownCell.attachments = cellMetadata.attachments;
}
return markdownCell;
}
/**
* Metadata we store in VS Code cells.
* This contains the original metadata from the Jupyuter cells.
*/
interface CellMetadata {
/**
* Stores attachments for cells.
*/
attachments?: nbformat.IAttachments;
/**
* Stores cell metadata.
*/
metadata?: Partial<nbformat.ICellMetadata>;
}
export function pruneCell(cell: nbformat.ICell): nbformat.ICell {
// Source is usually a single string on input. Convert back to an array
const result = {
...cell,
source: splitMultilineString(cell.source)
} as nbformat.ICell;
// Remove outputs and execution_count from non code cells
if (result.cell_type !== 'code') {
delete (<any>result).outputs;
delete (<any>result).execution_count;
} else {
// Clean outputs from code cells
result.outputs = result.outputs ? (result.outputs as nbformat.IOutput[]).map(fixupOutput) : [];
}
return result;
}
const dummyStreamObj: nbformat.IStream = {
output_type: 'stream',
name: 'stdout',
text: ''
};
const dummyErrorObj: nbformat.IError = {
output_type: 'error',
ename: '',
evalue: '',
traceback: ['']
};
const dummyDisplayObj: nbformat.IDisplayData = {
output_type: 'display_data',
data: {},
metadata: {}
};
const dummyExecuteResultObj: nbformat.IExecuteResult = {
output_type: 'execute_result',
name: '',
execution_count: 0,
data: {},
metadata: {}
};
const AllowedCellOutputKeys = {
['stream']: new Set(Object.keys(dummyStreamObj)),
['error']: new Set(Object.keys(dummyErrorObj)),
['display_data']: new Set(Object.keys(dummyDisplayObj)),
['execute_result']: new Set(Object.keys(dummyExecuteResultObj))
};
function fixupOutput(output: nbformat.IOutput): nbformat.IOutput {
let allowedKeys: Set<string>;
switch (output.output_type) {
case 'stream':
case 'error':
case 'execute_result':
case 'display_data':
allowedKeys = AllowedCellOutputKeys[output.output_type];
break;
default:
return output;
}
const result = { ...output };
for (const k of Object.keys(output)) {
if (!allowedKeys.has(k)) {
delete result[k];
}
}
return result;
}
function getNotebookCellMetadata(cell: nbformat.IBaseCell): CellMetadata {
// We put this only for VSC to display in diff view.
// Else we don't use this.
const propertiesToClone: (keyof CellMetadata)[] = ['metadata', 'attachments'];
const custom: CellMetadata = {};
propertiesToClone.forEach((propertyToClone) => {
if (cell[propertyToClone]) {
custom[propertyToClone] = JSON.parse(JSON.stringify(cell[propertyToClone]));
}
});
return custom;
}
function getOutputMetadata(output: nbformat.IOutput): CellOutputMetadata {
// Add on transient data if we have any. This should be removed by our save functions elsewhere.
const metadata: CellOutputMetadata = {
outputType: output.output_type
};
if (output.transient) {
metadata.transient = output.transient;
}
switch (output.output_type as nbformat.OutputType) {
case 'display_data':
case 'execute_result':
case 'update_display_data': {
metadata.executionCount = output.execution_count;
metadata.metadata = output.metadata ? JSON.parse(JSON.stringify(output.metadata)) : {};
break;
}
default:
break;
}
return metadata;
}
function translateDisplayDataOutput(
output: nbformat.IDisplayData | nbformat.IDisplayUpdate | nbformat.IExecuteResult
): NotebookCellOutput {
// Metadata could be as follows:
// We'll have metadata specific to each mime type as well as generic metadata.
/*
IDisplayData = {
output_type: 'display_data',
data: {
'image/jpg': '/////'
'image/png': '/////'
'text/plain': '/////'
},
metadata: {
'image/png': '/////',
'background': true,
'xyz': '///
}
}
*/
const metadata = getOutputMetadata(output);
const items: NotebookCellOutputItem[] = [];
if (output.data) {
for (const key in output.data) {
items.push(convertJupyterOutputToBuffer(key, output.data[key]));
}
}
return new NotebookCellOutput(sortOutputItemsBasedOnDisplayOrder(items), metadata);
}
function translateErrorOutput(output?: nbformat.IError): NotebookCellOutput {
output = output || { output_type: 'error', ename: '', evalue: '', traceback: [] };
return new NotebookCellOutput(
[
NotebookCellOutputItem.error({
name: output?.ename || '',
message: output?.evalue || '',
stack: (output?.traceback || []).join('\n')
})
],
{ ...getOutputMetadata(output), originalError: output }
);
}
function translateStreamOutput(output: nbformat.IStream): NotebookCellOutput {
const value = concatMultilineString(output.text);
const item = output.name === 'stderr' ? NotebookCellOutputItem.stderr(value) : NotebookCellOutputItem.stdout(value);
return new NotebookCellOutput([item], getOutputMetadata(output));
}
const cellOutputMappers = new Map<nbformat.OutputType, (output: any) => NotebookCellOutput>();
cellOutputMappers.set('display_data', translateDisplayDataOutput);
cellOutputMappers.set('execute_result', translateDisplayDataOutput);
cellOutputMappers.set('update_display_data', translateDisplayDataOutput);
cellOutputMappers.set('error', translateErrorOutput);
cellOutputMappers.set('stream', translateStreamOutput);
function jupyterCellOutputToCellOutput(output: nbformat.IOutput): NotebookCellOutput {
/**
* Stream, `application/x.notebook.stream`
* Error, `application/x.notebook.error-traceback`
* Rich, { mime: value }
*
* outputs: [
new vscode.NotebookCellOutput([
new vscode.NotebookCellOutputItem('application/x.notebook.stream', 2),
new vscode.NotebookCellOutputItem('application/x.notebook.stream', 3),
]),
new vscode.NotebookCellOutput([
new vscode.NotebookCellOutputItem('text/markdown', '## header 2'),
new vscode.NotebookCellOutputItem('image/svg+xml', [
"<svg baseProfile=\"full\" height=\"200\" version=\"1.1\" width=\"300\" xmlns=\"http://www.w3.org/2000/svg\">\n",
" <rect fill=\"blue\" height=\"100%\" width=\"100%\"/>\n",
" <circle cx=\"150\" cy=\"100\" fill=\"green\" r=\"80\"/>\n",
" <text fill=\"white\" font-size=\"60\" text-anchor=\"middle\" x=\"150\" y=\"125\">SVG</text>\n",
"</svg>"
]),
]),
]
*
*/
const fn = cellOutputMappers.get(output.output_type as nbformat.OutputType);
let result: NotebookCellOutput;
if (fn) {
result = fn(output);
} else {
result = translateDisplayDataOutput(output as any);
}
return result;
}
function createNotebookCellDataFromRawCell(cell: nbformat.IRawCell): NotebookCellData {
const cellData = new NotebookCellData(NotebookCellKind.Code, concatMultilineString(cell.source), 'raw');
cellData.outputs = [];
cellData.metadata = { custom: getNotebookCellMetadata(cell) };
return cellData;
}
function createNotebookCellDataFromMarkdownCell(cell: nbformat.IMarkdownCell): NotebookCellData {
const cellData = new NotebookCellData(
NotebookCellKind.Markup,
concatMultilineString(cell.source),
'markdown'
);
cellData.outputs = [];
cellData.metadata = { custom: getNotebookCellMetadata(cell) };
return cellData;
}
function createNotebookCellDataFromCodeCell(cell: nbformat.ICodeCell, cellLanguage: string): NotebookCellData {
const cellOutputs = Array.isArray(cell.outputs) ? cell.outputs : [];
const outputs = cellOutputs.map(jupyterCellOutputToCellOutput);
const hasExecutionCount = typeof cell.execution_count === 'number' && cell.execution_count > 0;
const source = concatMultilineString(cell.source);
const executionSummary: NotebookCellExecutionSummary = hasExecutionCount
? { executionOrder: cell.execution_count as number }
: {};
const cellData = new NotebookCellData(NotebookCellKind.Code, source, cellLanguage);
cellData.outputs = outputs;
cellData.metadata = { custom: getNotebookCellMetadata(cell) };
cellData.executionSummary = executionSummary;
return cellData;
}
function createNotebookCellDataFromJupyterCell(
cellLanguage: string,
cell: nbformat.IBaseCell
): NotebookCellData | undefined {
switch (cell.cell_type) {
case 'raw': {
return createNotebookCellDataFromRawCell(cell as nbformat.IRawCell);
}
case 'markdown': {
return createNotebookCellDataFromMarkdownCell(cell as nbformat.IMarkdownCell);
}
case 'code': {
return createNotebookCellDataFromCodeCell(cell as nbformat.ICodeCell, cellLanguage);
}
}
return;
}
/**
* Converts a NotebookModel into VS Code format.
*/
export function jupyterNotebookModelToNotebookData(
notebookContent: Partial<nbformat.INotebookContent>,
preferredLanguage: string
): NotebookData {
const notebookContentWithoutCells = { ...notebookContent, cells: [] };
if (!notebookContent.cells || notebookContent.cells.length === 0) {
throw new Error('Notebook content is missing cells');
}
const cells = notebookContent.cells
.map(cell => createNotebookCellDataFromJupyterCell(preferredLanguage, cell))
.filter((item): item is NotebookCellData => !!item);
const notebookData = new NotebookData(cells);
notebookData.metadata = { custom: notebookContentWithoutCells };
return notebookData;
}

View file

@ -4,10 +4,11 @@
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { NotebookSerializer } from './serializer';
import { NotebookSerializer } from './notebookSerializer';
export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(vscode.workspace.registerNotebookSerializer('jupyter-notebook', new NotebookSerializer(), {
const serializer = new NotebookSerializer(context);
context.subscriptions.push(vscode.workspace.registerNotebookSerializer('jupyter-notebook', serializer, {
transientOutputs: false,
transientCellMetadata: {
breakpointMargin: true,
@ -16,6 +17,16 @@ export function activate(context: vscode.ExtensionContext) {
custom: false
}
}));
return {
exportNotebook: (notebook: vscode.NotebookData): string => {
return exportNotebook(notebook, serializer);
}
};
}
function exportNotebook(notebook: vscode.NotebookData, serializer: NotebookSerializer): string {
return serializer.serializeNotebookToString(notebook);
}
export function deactivate() { }

View file

@ -7,23 +7,37 @@ import type { nbformat } from '@jupyterlab/coreutils';
import * as detectIndent from 'detect-indent';
import * as vscode from 'vscode';
import { defaultNotebookFormat } from './constants';
import { createJupyterCellFromNotebookCell, getPreferredLanguage, jupyterNotebookModelToNotebookData, pruneCell } from './helpers';
import { getPreferredLanguage, jupyterNotebookModelToNotebookData } from './deserializers';
import { createJupyterCellFromNotebookCell, pruneCell } from './serializers';
import * as fnv from '@enonic/fnv-plus';
export class NotebookSerializer implements vscode.NotebookSerializer {
public deserializeNotebook(content: Uint8Array, _token: vscode.CancellationToken): vscode.NotebookData {
constructor(readonly context: vscode.ExtensionContext) {
}
public async deserializeNotebook(content: Uint8Array, _token: vscode.CancellationToken): Promise<vscode.NotebookData> {
let contents = '';
try {
contents = new TextDecoder().decode(content);
} catch {
}
let json: Partial<nbformat.INotebookContent>;
try {
json = contents ? (JSON.parse(contents) as Partial<nbformat.INotebookContent>) : {};
} catch (e) {
console.log(contents);
console.log(e);
throw e;
let json = contents ? (JSON.parse(contents) as Partial<nbformat.INotebookContent>) : {};
if (json.__webview_backup) {
const backupId = json.__webview_backup;
const uri = this.context.globalStorageUri;
const folder = uri.with({ path: this.context.globalStorageUri.path.replace('vscode.ipynb', 'ms-toolsai.jupyter') });
const fileHash = fnv.fast1a32hex(backupId) as string;
const fileName = `${fileHash}.ipynb`;
const file = vscode.Uri.joinPath(folder, fileName);
const data = await vscode.workspace.fs.readFile(file);
json = data ? JSON.parse(data.toString()) : {};
if (json.contents && typeof json.contents === 'string') {
contents = json.contents;
json = JSON.parse(contents) as Partial<nbformat.INotebookContent>;
}
}
// Then compute indent from the contents
@ -59,26 +73,18 @@ export class NotebookSerializer implements vscode.NotebookSerializer {
return data;
}
public serializeNotebookDocument(data: vscode.NotebookDocument): string {
return this.serialize(data);
}
public serializeNotebook(data: vscode.NotebookData, _token: vscode.CancellationToken): Uint8Array {
return new TextEncoder().encode(this.serialize(data));
return new TextEncoder().encode(this.serializeNotebookToString(data));
}
private serialize(data: vscode.NotebookDocument | vscode.NotebookData): string {
public serializeNotebookToString(data: vscode.NotebookData): string {
const notebookContent: Partial<nbformat.INotebookContent> = data.metadata?.custom || {};
notebookContent.cells = notebookContent.cells || [];
notebookContent.nbformat = notebookContent.nbformat || 4;
notebookContent.nbformat_minor = notebookContent.nbformat_minor || 2;
notebookContent.metadata = notebookContent.metadata || { orig_nbformat: 4 };
const cells = 'notebookType' in data ?
data.getCells() :
data.cells;
notebookContent.cells = cells
notebookContent.cells = data.cells
.map(cell => createJupyterCellFromNotebookCell(cell))
.map(pruneCell);

View file

@ -0,0 +1,371 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { nbformat } from '@jupyterlab/coreutils';
import { NotebookCellData, NotebookCellKind, NotebookCellOutput } from 'vscode';
import { CellOutputMetadata } from './common';
const textDecoder = new TextDecoder();
enum CellOutputMimeTypes {
error = 'application/vnd.code.notebook.error',
stderr = 'application/vnd.code.notebook.stderr',
stdout = 'application/vnd.code.notebook.stdout'
}
const textMimeTypes = ['text/plain', 'text/markdown', CellOutputMimeTypes.stderr, CellOutputMimeTypes.stdout];
export function createJupyterCellFromNotebookCell(
vscCell: NotebookCellData
): nbformat.IRawCell | nbformat.IMarkdownCell | nbformat.ICodeCell {
let cell: nbformat.IRawCell | nbformat.IMarkdownCell | nbformat.ICodeCell;
if (vscCell.kind === NotebookCellKind.Markup) {
cell = createMarkdownCellFromNotebookCell(vscCell);
} else if (vscCell.languageId === 'raw') {
cell = createRawCellFromNotebookCell(vscCell);
} else {
cell = createCodeCellFromNotebookCell(vscCell);
}
return cell;
}
function createCodeCellFromNotebookCell(cell: NotebookCellData): nbformat.ICodeCell {
const cellMetadata = cell.metadata?.custom as CellMetadata | undefined;
const codeCell: any = {
cell_type: 'code',
execution_count: cell.executionSummary?.executionOrder ?? null,
source: splitMultilineString(cell.value),
outputs: (cell.outputs || []).map(translateCellDisplayOutput),
metadata: cellMetadata?.metadata || {} // This cannot be empty.
};
return codeCell;
}
function createRawCellFromNotebookCell(cell: NotebookCellData): nbformat.IRawCell {
const cellMetadata = cell.metadata?.custom as CellMetadata | undefined;
const rawCell: any = {
cell_type: 'raw',
source: splitMultilineString(cell.value),
metadata: cellMetadata?.metadata || {} // This cannot be empty.
};
if (cellMetadata?.attachments) {
rawCell.attachments = cellMetadata.attachments;
}
return rawCell;
}
function splitMultilineString(source: nbformat.MultilineString): string[] {
if (Array.isArray(source)) {
return source as string[];
}
const str = source.toString();
if (str.length > 0) {
// Each line should be a separate entry, but end with a \n if not last entry
const arr = str.split('\n');
return arr
.map((s, i) => {
if (i < arr.length - 1) {
return `${s}\n`;
}
return s;
})
.filter(s => s.length > 0); // Skip last one if empty (it's the only one that could be length 0)
}
return [];
}
function translateCellDisplayOutput(output: NotebookCellOutput): JupyterOutput {
const customMetadata = output.metadata as CellOutputMetadata | undefined;
let result: JupyterOutput;
// Possible some other extension added some output (do best effort to translate & save in ipynb).
// In which case metadata might not contain `outputType`.
const outputType = customMetadata?.outputType as nbformat.OutputType;
switch (outputType) {
case 'error': {
result = translateCellErrorOutput(output);
break;
}
case 'stream': {
result = convertStreamOutput(output);
break;
}
case 'display_data': {
result = {
output_type: 'display_data',
data: output.items.reduceRight((prev: any, curr) => {
prev[curr.mime] = convertOutputMimeToJupyterOutput(curr.mime, curr.data as Uint8Array);
return prev;
}, {}),
metadata: customMetadata?.metadata || {} // This can never be undefined.
};
break;
}
case 'execute_result': {
result = {
output_type: 'execute_result',
data: output.items.reduceRight((prev: any, curr) => {
prev[curr.mime] = convertOutputMimeToJupyterOutput(curr.mime, curr.data as Uint8Array);
return prev;
}, {}),
metadata: customMetadata?.metadata || {}, // This can never be undefined.
execution_count:
typeof customMetadata?.executionCount === 'number' ? customMetadata?.executionCount : null // This can never be undefined, only a number or `null`.
};
break;
}
case 'update_display_data': {
result = {
output_type: 'update_display_data',
data: output.items.reduceRight((prev: any, curr) => {
prev[curr.mime] = convertOutputMimeToJupyterOutput(curr.mime, curr.data as Uint8Array);
return prev;
}, {}),
metadata: customMetadata?.metadata || {} // This can never be undefined.
};
break;
}
default: {
const isError =
output.items.length === 1 && output.items.every((item) => item.mime === CellOutputMimeTypes.error);
const isStream = output.items.every(
(item) => item.mime === CellOutputMimeTypes.stderr || item.mime === CellOutputMimeTypes.stdout
);
if (isError) {
return translateCellErrorOutput(output);
}
// In the case of .NET & other kernels, we need to ensure we save ipynb correctly.
// Hence if we have stream output, save the output as Jupyter `stream` else `display_data`
// Unless we already know its an unknown output type.
const outputType: nbformat.OutputType =
<nbformat.OutputType>customMetadata?.outputType || (isStream ? 'stream' : 'display_data');
let unknownOutput: nbformat.IUnrecognizedOutput | nbformat.IDisplayData | nbformat.IStream;
if (outputType === 'stream') {
// If saving as `stream` ensure the mandatory properties are set.
unknownOutput = convertStreamOutput(output);
} else if (outputType === 'display_data') {
// If saving as `display_data` ensure the mandatory properties are set.
const displayData: nbformat.IDisplayData = {
data: {},
metadata: {},
output_type: 'display_data'
};
unknownOutput = displayData;
} else {
unknownOutput = {
output_type: outputType
};
}
if (customMetadata?.metadata) {
unknownOutput.metadata = customMetadata.metadata;
}
if (output.items.length > 0) {
unknownOutput.data = output.items.reduceRight((prev: any, curr) => {
prev[curr.mime] = convertOutputMimeToJupyterOutput(curr.mime, curr.data as Uint8Array);
return prev;
}, {});
}
result = unknownOutput;
break;
}
}
// Account for transient data as well
// `transient.display_id` is used to update cell output in other cells, at least thats one use case we know of.
if (result && customMetadata && customMetadata.transient) {
result.transient = customMetadata.transient;
}
return result;
}
function translateCellErrorOutput(output: NotebookCellOutput): nbformat.IError {
// it should have at least one output item
const firstItem = output.items[0];
// Bug in VS Code.
if (!firstItem.data) {
return {
output_type: 'error',
ename: '',
evalue: '',
traceback: []
};
}
const originalError: undefined | nbformat.IError = output.metadata?.originalError;
const value: Error = JSON.parse(textDecoder.decode(firstItem.data));
return {
output_type: 'error',
ename: value.name,
evalue: value.message,
// VS Code needs an `Error` object which requires a `stack` property as a string.
// Its possible the format could change when converting from `traceback` to `string` and back again to `string`
// When .NET stores errors in output (with their .NET kernel),
// stack is empty, hence store the message instead of stack (so that somethign gets displayed in ipynb).
traceback: originalError?.traceback || splitMultilineString(value.stack || value.message || '')
};
}
function getOutputStreamType(output: NotebookCellOutput): string | undefined {
if (output.items.length > 0) {
return output.items[0].mime === CellOutputMimeTypes.stderr ? 'stderr' : 'stdout';
}
return;
}
type JupyterOutput =
| nbformat.IUnrecognizedOutput
| nbformat.IExecuteResult
| nbformat.IDisplayData
| nbformat.IStream
| nbformat.IError;
function convertStreamOutput(output: NotebookCellOutput): JupyterOutput {
const outputs = output.items
.filter((opit) => opit.mime === CellOutputMimeTypes.stderr || opit.mime === CellOutputMimeTypes.stdout)
.map((opit) => convertOutputMimeToJupyterOutput(opit.mime, opit.data as Uint8Array) as string)
.reduceRight<string[]>((prev, curr) => prev.concat(curr), []);
const streamType = getOutputStreamType(output) || 'stdout';
return {
output_type: 'stream',
name: streamType,
text: splitMultilineString(outputs.join(''))
};
}
function convertOutputMimeToJupyterOutput(mime: string, value: Uint8Array) {
if (!value) {
return '';
}
try {
if (mime === CellOutputMimeTypes.error) {
const stringValue = textDecoder.decode(value);
return JSON.parse(stringValue);
} else if (mime.startsWith('text/') || textMimeTypes.includes(mime)) {
const stringValue = textDecoder.decode(value);
return splitMultilineString(stringValue);
} else if (mime.startsWith('image/') && mime !== 'image/svg+xml') {
// Images in Jupyter are stored in base64 encoded format.
// VS Code expects bytes when rendering images.
if (typeof Buffer !== 'undefined' && typeof Buffer.from === 'function') {
return Buffer.from(value).toString('base64');
} else {
// https://developer.mozilla.org/en-US/docs/Glossary/Base64#solution_1_%E2%80%93_escaping_the_string_before_encoding_it
const stringValue = textDecoder.decode(value);
return btoa(encodeURIComponent(stringValue).replace(/%([0-9A-F]{2})/g, function (_match, p1) {
return String.fromCharCode(Number.parseInt('0x' + p1));
}));
}
} else if (mime.toLowerCase().includes('json')) {
const stringValue = textDecoder.decode(value);
return stringValue.length > 0 ? JSON.parse(stringValue) : stringValue;
} else {
const stringValue = textDecoder.decode(value);
return stringValue;
}
} catch (ex) {
return '';
}
}
function createMarkdownCellFromNotebookCell(cell: NotebookCellData): nbformat.IMarkdownCell {
const cellMetadata = cell.metadata?.custom as CellMetadata | undefined;
const markdownCell: any = {
cell_type: 'markdown',
source: splitMultilineString(cell.value),
metadata: cellMetadata?.metadata || {} // This cannot be empty.
};
if (cellMetadata?.attachments) {
markdownCell.attachments = cellMetadata.attachments;
}
return markdownCell;
}
/**
* Metadata we store in VS Code cells.
* This contains the original metadata from the Jupyuter cells.
*/
interface CellMetadata {
/**
* Stores attachments for cells.
*/
attachments?: nbformat.IAttachments;
/**
* Stores cell metadata.
*/
metadata?: Partial<nbformat.ICellMetadata>;
}
export function pruneCell(cell: nbformat.ICell): nbformat.ICell {
// Source is usually a single string on input. Convert back to an array
const result = {
...cell,
source: splitMultilineString(cell.source)
} as nbformat.ICell;
// Remove outputs and execution_count from non code cells
if (result.cell_type !== 'code') {
delete (<any>result).outputs;
delete (<any>result).execution_count;
} else {
// Clean outputs from code cells
result.outputs = result.outputs ? (result.outputs as nbformat.IOutput[]).map(fixupOutput) : [];
}
return result;
}
const dummyStreamObj: nbformat.IStream = {
output_type: 'stream',
name: 'stdout',
text: ''
};
const dummyErrorObj: nbformat.IError = {
output_type: 'error',
ename: '',
evalue: '',
traceback: ['']
};
const dummyDisplayObj: nbformat.IDisplayData = {
output_type: 'display_data',
data: {},
metadata: {}
};
const dummyExecuteResultObj: nbformat.IExecuteResult = {
output_type: 'execute_result',
name: '',
execution_count: 0,
data: {},
metadata: {}
};
const AllowedCellOutputKeys = {
['stream']: new Set(Object.keys(dummyStreamObj)),
['error']: new Set(Object.keys(dummyErrorObj)),
['display_data']: new Set(Object.keys(dummyDisplayObj)),
['execute_result']: new Set(Object.keys(dummyExecuteResultObj))
};
function fixupOutput(output: nbformat.IOutput): nbformat.IOutput {
let allowedKeys: Set<string>;
switch (output.output_type) {
case 'stream':
case 'error':
case 'execute_result':
case 'display_data':
allowedKeys = AllowedCellOutputKeys[output.output_type];
break;
default:
return output;
}
const result = { ...output };
for (const k of Object.keys(output)) {
if (!allowedKeys.has(k)) {
delete result[k];
}
}
return result;
}

View file

@ -0,0 +1,40 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
const path = require('path');
const testRunner = require('../../../../test/integration/electron/testrunner');
const options: any = {
ui: 'tdd',
color: true,
timeout: 60000
};
// These integration tests is being run in multiple environments (electron, web, remote)
// so we need to set the suite name based on the environment as the suite name is used
// for the test results file name
let suite = '';
if (process.env.VSCODE_BROWSER) {
suite = `${process.env.VSCODE_BROWSER} Browser Integration .ipynb Tests`;
} else if (process.env.REMOTE_VSCODE) {
suite = 'Remote Integration .ipynb Tests';
} else {
suite = 'Integration .ipynb Tests';
}
if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) {
options.reporter = 'mocha-multi-reporters';
options.reporterOptions = {
reporterEnabled: 'spec, mocha-junit-reporter',
mochaJunitReporterReporterOptions: {
testsuitesTitle: `${suite} ${process.platform}`,
mochaFile: path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${process.arch}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`)
}
};
}
testRunner.configure(options);
export = testRunner;

View file

@ -0,0 +1,394 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { nbformat } from '@jupyterlab/coreutils';
import * as assert from 'assert';
import * as vscode from 'vscode';
import { jupyterNotebookModelToNotebookData } from '../deserializers';
function deepStripProperties(obj: any, props: string[]) {
for (let prop in obj) {
if (obj[prop]) {
delete obj[prop];
} else if (typeof obj[prop] === 'object') {
deepStripProperties(obj[prop], props);
}
}
}
suite('ipynb serializer', () => {
const base64EncodedImage =
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mOUlZL6DwAB/wFSU1jVmgAAAABJRU5ErkJggg==';
test('Deserialize', async () => {
const cells: nbformat.ICell[] = [
{
cell_type: 'code',
execution_count: 10,
outputs: [],
source: 'print(1)',
metadata: {}
},
{
cell_type: 'markdown',
source: '# HEAD',
metadata: {}
}
];
const notebook = jupyterNotebookModelToNotebookData({ cells }, 'python');
assert.ok(notebook);
const expectedCodeCell = new vscode.NotebookCellData(vscode.NotebookCellKind.Code, 'print(1)', 'python');
expectedCodeCell.outputs = [];
expectedCodeCell.metadata = { custom: { metadata: {} } };
expectedCodeCell.executionSummary = { executionOrder: 10 };
const expectedMarkdownCell = new vscode.NotebookCellData(vscode.NotebookCellKind.Markup, '# HEAD', 'markdown');
expectedMarkdownCell.outputs = [];
expectedMarkdownCell.metadata = {
custom: { metadata: {} }
};
assert.deepStrictEqual(notebook.cells, [expectedCodeCell, expectedMarkdownCell]);
});
suite('Outputs', () => {
function validateCellOutputTranslation(
outputs: nbformat.IOutput[],
expectedOutputs: vscode.NotebookCellOutput[],
propertiesToExcludeFromComparison: string[] = []
) {
const cells: nbformat.ICell[] = [
{
cell_type: 'code',
execution_count: 10,
outputs,
source: 'print(1)',
metadata: {}
}
];
const notebook = jupyterNotebookModelToNotebookData({ cells }, 'python');
// OutputItems contain an `id` property generated by VSC.
// Exclude that property when comparing.
const propertiesToExclude = propertiesToExcludeFromComparison.concat(['id']);
const actualOuts = notebook.cells[0].outputs;
deepStripProperties(actualOuts, propertiesToExclude);
deepStripProperties(expectedOutputs, propertiesToExclude);
assert.deepStrictEqual(actualOuts, expectedOutputs);
}
test('Empty output', () => {
validateCellOutputTranslation([], []);
});
test('Stream output', () => {
validateCellOutputTranslation(
[
{
output_type: 'stream',
name: 'stderr',
text: 'Error'
},
{
output_type: 'stream',
name: 'stdout',
text: 'NoError'
}
],
[
new vscode.NotebookCellOutput([vscode.NotebookCellOutputItem.stderr('Error')], {
outputType: 'stream'
}),
new vscode.NotebookCellOutput([vscode.NotebookCellOutputItem.stdout('NoError')], {
outputType: 'stream'
})
]
);
});
test('Streamed text with Ansi characters', async () => {
validateCellOutputTranslation(
[
{
name: 'stderr',
text: '\u001b[K\u001b[33m✅ \u001b[0m Loading\n',
output_type: 'stream'
}
],
[
new vscode.NotebookCellOutput(
[vscode.NotebookCellOutputItem.stderr('\u001b[K\u001b[33m✅ \u001b[0m Loading\n')],
{
outputType: 'stream'
}
)
]
);
});
test('Streamed text with angle bracket characters', async () => {
validateCellOutputTranslation(
[
{
name: 'stderr',
text: '1 is < 2',
output_type: 'stream'
}
],
[
new vscode.NotebookCellOutput([vscode.NotebookCellOutputItem.stderr('1 is < 2')], {
outputType: 'stream'
})
]
);
});
test('Streamed text with angle bracket characters and ansi chars', async () => {
validateCellOutputTranslation(
[
{
name: 'stderr',
text: '1 is < 2\u001b[K\u001b[33m✅ \u001b[0m Loading\n',
output_type: 'stream'
}
],
[
new vscode.NotebookCellOutput(
[vscode.NotebookCellOutputItem.stderr('1 is < 2\u001b[K\u001b[33m✅ \u001b[0m Loading\n')],
{
outputType: 'stream'
}
)
]
);
});
test('Error', async () => {
validateCellOutputTranslation(
[
{
ename: 'Error Name',
evalue: 'Error Value',
traceback: ['stack1', 'stack2', 'stack3'],
output_type: 'error'
}
],
[
new vscode.NotebookCellOutput(
[
vscode.NotebookCellOutputItem.error({
name: 'Error Name',
message: 'Error Value',
stack: ['stack1', 'stack2', 'stack3'].join('\n')
})
],
{
outputType: 'error',
originalError: {
ename: 'Error Name',
evalue: 'Error Value',
traceback: ['stack1', 'stack2', 'stack3'],
output_type: 'error'
}
}
)
]
);
});
['display_data', 'execute_result'].forEach(output_type => {
suite(`Rich output for output_type = ${output_type}`, () => {
// Properties to exclude when comparing.
let propertiesToExcludeFromComparison: string[] = [];
setup(() => {
if (output_type === 'display_data') {
// With display_data the execution_count property will never exist in the output.
// We can ignore that (as it will never exist).
// But we leave it in the case of `output_type === 'execute_result'`
propertiesToExcludeFromComparison = ['execution_count', 'executionCount'];
}
});
test('Text mimeType output', async () => {
validateCellOutputTranslation(
[
{
data: {
'text/plain': 'Hello World!'
},
output_type,
metadata: {},
execution_count: 1
}
],
[
new vscode.NotebookCellOutput(
[new vscode.NotebookCellOutputItem(Buffer.from('Hello World!', 'utf8'), 'text/plain')],
{
outputType: output_type,
metadata: {}, // display_data & execute_result always have metadata.
executionCount: 1
}
)
],
propertiesToExcludeFromComparison
);
});
test('png,jpeg images', async () => {
validateCellOutputTranslation(
[
{
execution_count: 1,
data: {
'image/png': base64EncodedImage,
'image/jpeg': base64EncodedImage
},
metadata: {},
output_type
}
],
[
new vscode.NotebookCellOutput(
[
new vscode.NotebookCellOutputItem(Buffer.from(base64EncodedImage, 'base64'), 'image/png'),
new vscode.NotebookCellOutputItem(Buffer.from(base64EncodedImage, 'base64'), 'image/jpeg')
],
{
executionCount: 1,
outputType: output_type,
metadata: {} // display_data & execute_result always have metadata.
}
)
],
propertiesToExcludeFromComparison
);
});
test('png image with a light background', async () => {
validateCellOutputTranslation(
[
{
execution_count: 1,
data: {
'image/png': base64EncodedImage
},
metadata: {
needs_background: 'light'
},
output_type
}
],
[
new vscode.NotebookCellOutput(
[new vscode.NotebookCellOutputItem(Buffer.from(base64EncodedImage, 'base64'), 'image/png')],
{
executionCount: 1,
metadata: {
needs_background: 'light'
},
outputType: output_type
}
)
],
propertiesToExcludeFromComparison
);
});
test('png image with a dark background', async () => {
validateCellOutputTranslation(
[
{
execution_count: 1,
data: {
'image/png': base64EncodedImage
},
metadata: {
needs_background: 'dark'
},
output_type
}
],
[
new vscode.NotebookCellOutput(
[new vscode.NotebookCellOutputItem(Buffer.from(base64EncodedImage, 'base64'), 'image/png')],
{
executionCount: 1,
metadata: {
needs_background: 'dark'
},
outputType: output_type
}
)
],
propertiesToExcludeFromComparison
);
});
test('png image with custom dimensions', async () => {
validateCellOutputTranslation(
[
{
execution_count: 1,
data: {
'image/png': base64EncodedImage
},
metadata: {
'image/png': { height: '111px', width: '999px' }
},
output_type
}
],
[
new vscode.NotebookCellOutput(
[new vscode.NotebookCellOutputItem(Buffer.from(base64EncodedImage, 'base64'), 'image/png')],
{
executionCount: 1,
metadata: {
'image/png': { height: '111px', width: '999px' }
},
outputType: output_type
}
)
],
propertiesToExcludeFromComparison
);
});
test('png allowed to scroll', async () => {
validateCellOutputTranslation(
[
{
execution_count: 1,
data: {
'image/png': base64EncodedImage
},
metadata: {
unconfined: true,
'image/png': { width: '999px' }
},
output_type
}
],
[
new vscode.NotebookCellOutput(
[new vscode.NotebookCellOutputItem(Buffer.from(base64EncodedImage, 'base64'), 'image/png')],
{
executionCount: 1,
metadata: {
unconfined: true,
'image/png': { width: '999px' }
},
outputType: output_type
}
)
],
propertiesToExcludeFromComparison
);
});
});
});
});
});

View file

@ -6,3 +6,5 @@
/// <reference path='../../../src/vs/vscode.d.ts'/>
/// <reference path='../../../src/vs/vscode.proposed.d.ts'/>
declare module '@enonic/fnv-plus';

View file

@ -0,0 +1,8 @@
{
"scopeName": "source.jupyter",
"patterns": [
{
"include": "source.json"
}
]
}

View file

@ -2,6 +2,11 @@
# yarn lockfile v1
"@enonic/fnv-plus@^1.3.0":
version "1.3.0"
resolved "https://registry.yarnpkg.com/@enonic/fnv-plus/-/fnv-plus-1.3.0.tgz#be65a7b128a3b544f60aea3ef978d938e85869f3"
integrity sha512-BCN9uNWH8AmiP7BXBJqEinUY9KXalmRzo+L0cB/mQsmFfzODxwQrbvxCHXUNH2iP+qKkWYtB4vyy8N62PViMFw==
"@jupyterlab/coreutils@^3.1.0":
version "3.2.0"
resolved "https://registry.yarnpkg.com/@jupyterlab/coreutils/-/coreutils-3.2.0.tgz#dd4d887bdedfea4c8545d46d297531749cb13724"

View file

@ -62,6 +62,7 @@
"meta.embedded.expression.js": "javascriptreact"
},
"tokenTypes": {
"meta.template.expression": "other",
"entity.name.type.instance.jsdoc": "other",
"entity.name.function.tagged-template": "other",
"meta.import string.quoted": "other",
@ -79,6 +80,7 @@
"meta.embedded.expression.js": "javascript"
},
"tokenTypes": {
"meta.template.expression": "other",
"entity.name.type.instance.jsdoc": "other",
"entity.name.function.tagged-template": "other",
"meta.import string.quoted": "other",

View file

@ -134,8 +134,8 @@
]
},
"dependencies": {
"request-light": "^0.5.3",
"vscode-extension-telemetry": "0.1.7",
"request-light": "^0.5.4",
"vscode-extension-telemetry": "0.2.8",
"vscode-languageclient": "^7.0.0",
"vscode-nls": "^5.0.0"
},

View file

@ -13,8 +13,8 @@
"main": "./out/node/jsonServerMain",
"dependencies": {
"jsonc-parser": "^3.0.0",
"request-light": "^0.5.3",
"vscode-json-languageservice": "^4.1.5",
"request-light": "^0.5.4",
"vscode-json-languageservice": "^4.1.6",
"vscode-languageserver": "^7.0.0",
"vscode-uri": "^3.0.2"
},

View file

@ -12,48 +12,22 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.43.tgz#26bcbb0595b305400e8ceaf9a127a7f905ae49c8"
integrity sha512-3pwDJjp1PWacPTpH0LcfhgjvurQvrZFBrC6xxjaUEZ7ifUtT32jtjPxEMMblpqd2Mvx+k8haqQJLQxolyGN/cQ==
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
jsonc-parser@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.0.0.tgz#abdd785701c7e7eaca8a9ec8cf070ca51a745a22"
integrity sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==
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==
dependencies:
brace-expansion "^1.1.7"
request-light@^0.5.4:
version "0.5.4"
resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.5.4.tgz#497a98c6d8ae49536417a5e2d7f383b934f3e38c"
integrity sha512-t3566CMweOFlUk7Y1DJMu5OrtpoZEb6aSTsLQVT3wtrIEJ5NhcY9G/Oqxvjllzl4a15zXfFlcr9q40LbLVQJqw==
request-light@^0.5.3:
version "0.5.3"
resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.5.3.tgz#bc5b103b939cde7c0653fff8ab4f43440779a5fb"
integrity sha512-wlHI5WbSZ2PcoLW2qE616PKDFCFJWaJjgRg2VaNXF9pa8MJ7+dKveJzw2HhJF8Et5uOmh9nAUJUX4iFI3Mvm/g==
vscode-json-languageservice@^4.1.5:
version "4.1.5"
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-4.1.5.tgz#e429987d9e4693d8cd88338fa3c96616772b6e8c"
integrity sha512-oRVPj2UY6BQ8PQ1LIz/FigUEZQVqsB9msNCFlxRBHE9sSEIJkCbYG6aCB2n7WR17VIisYQdO3MDheuoyI48G2w==
vscode-json-languageservice@^4.1.6:
version "4.1.6"
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-4.1.6.tgz#4275e8daf1cba80273c318f33fbf7a2ede307053"
integrity sha512-DIKb3tcfRtb3tIE6g9SLOl5E9tNSt6kljH08Wa5RwFlVshtXGrDDzttchze4CYy9pJpE9mBtCbRHmLvY1Z1ZXA==
dependencies:
jsonc-parser "^3.0.0"
minimatch "^3.0.4"
vscode-languageserver-textdocument "^1.0.1"
vscode-languageserver-types "^3.16.0"
vscode-nls "^5.0.0"

View file

@ -7,31 +7,6 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.43.tgz#26bcbb0595b305400e8ceaf9a127a7f905ae49c8"
integrity sha512-3pwDJjp1PWacPTpH0LcfhgjvurQvrZFBrC6xxjaUEZ7ifUtT32jtjPxEMMblpqd2Mvx+k8haqQJLQxolyGN/cQ==
applicationinsights@1.7.4:
version "1.7.4"
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-1.7.4.tgz#e7d96435594d893b00cf49f70a5927105dbb8749"
integrity sha512-XFLsNlcanpjFhHNvVWEfcm6hr7lu9znnb6Le1Lk5RE03YUV9X2B2n2MfM4kJZRrUdV+C0hdHxvWyv+vWoLfY7A==
dependencies:
cls-hooked "^4.2.2"
continuation-local-storage "^3.2.1"
diagnostic-channel "0.2.0"
diagnostic-channel-publishers "^0.3.3"
async-hook-jl@^1.7.6:
version "1.7.6"
resolved "https://registry.yarnpkg.com/async-hook-jl/-/async-hook-jl-1.7.6.tgz#4fd25c2f864dbaf279c610d73bf97b1b28595e68"
integrity sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==
dependencies:
stack-chain "^1.3.7"
async-listener@^0.6.0:
version "0.6.10"
resolved "https://registry.yarnpkg.com/async-listener/-/async-listener-0.6.10.tgz#a7c97abe570ba602d782273c0de60a51e3e17cbc"
integrity sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==
dependencies:
semver "^5.3.0"
shimmer "^1.1.0"
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
@ -45,47 +20,11 @@ brace-expansion@^1.1.7:
balanced-match "^1.0.0"
concat-map "0.0.1"
cls-hooked@^4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908"
integrity sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==
dependencies:
async-hook-jl "^1.7.6"
emitter-listener "^1.0.1"
semver "^5.4.1"
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
continuation-local-storage@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz#11f613f74e914fe9b34c92ad2d28fe6ae1db7ffb"
integrity sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==
dependencies:
async-listener "^0.6.0"
emitter-listener "^1.1.1"
diagnostic-channel-publishers@^0.3.3:
version "0.3.5"
resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.5.tgz#a84a05fd6cc1d7619fdd17791c17e540119a7536"
integrity sha512-AOIjw4T7Nxl0G2BoBPhkQ6i7T4bUd9+xvdYizwvG7vVAM1dvr+SDrcUudlmzwH0kbEwdR2V1EcnKT0wAeYLQNQ==
diagnostic-channel@0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz#cc99af9612c23fb1fff13612c72f2cbfaa8d5a17"
integrity sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=
dependencies:
semver "^5.3.0"
emitter-listener@^1.0.1, emitter-listener@^1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/emitter-listener/-/emitter-listener-1.1.2.tgz#56b140e8f6992375b3d7cb2cab1cc7432d9632e8"
integrity sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==
dependencies:
shimmer "^1.2.0"
lru-cache@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
@ -100,20 +39,10 @@ minimatch@^3.0.4:
dependencies:
brace-expansion "^1.1.7"
request-light@^0.5.3:
version "0.5.3"
resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.5.3.tgz#bc5b103b939cde7c0653fff8ab4f43440779a5fb"
integrity sha512-wlHI5WbSZ2PcoLW2qE616PKDFCFJWaJjgRg2VaNXF9pa8MJ7+dKveJzw2HhJF8Et5uOmh9nAUJUX4iFI3Mvm/g==
semver@^5.3.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
integrity sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==
semver@^5.4.1:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
request-light@^0.5.4:
version "0.5.4"
resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.5.4.tgz#497a98c6d8ae49536417a5e2d7f383b934f3e38c"
integrity sha512-t3566CMweOFlUk7Y1DJMu5OrtpoZEb6aSTsLQVT3wtrIEJ5NhcY9G/Oqxvjllzl4a15zXfFlcr9q40LbLVQJqw==
semver@^7.3.4:
version "7.3.4"
@ -122,22 +51,10 @@ semver@^7.3.4:
dependencies:
lru-cache "^6.0.0"
shimmer@^1.1.0, shimmer@^1.2.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337"
integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==
stack-chain@^1.3.7:
version "1.3.7"
resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285"
integrity sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=
vscode-extension-telemetry@0.1.7:
version "0.1.7"
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.7.tgz#18389bc24127c89dade29cd2b71ba69a6ee6ad26"
integrity sha512-pZuZTHO9OpsrwlerOKotWBRLRYJ53DobYb7aWiRAXjlqkuqE+YJJaP+2WEy8GrLIF1EnitXTDMaTAKsmLQ5ORQ==
dependencies:
applicationinsights "1.7.4"
vscode-extension-telemetry@0.2.8:
version "0.2.8"
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.2.8.tgz#670c625c44791237c040cee2cb9f567ca34784ac"
integrity sha512-Vf52im5qzORRD2K5Ryp8PXo31YXVcJAYRSDDZGegWlt0OATOd83DYabS1U/WIq9nR5g80UQKH3+BsenhpQHUaA==
vscode-jsonrpc@6.0.0:
version "6.0.0"

View file

@ -6,7 +6,7 @@
"git": {
"name": "JuliaEditorSupport/atom-language-julia",
"repositoryUrl": "https://github.com/JuliaEditorSupport/atom-language-julia",
"commitHash": "63325eb9959b57282e2804e5d7215d240a9a6fd6"
"commitHash": "6c80921298caa9e6c382f1fecec0bf3a83c3d9ec"
}
},
"license": "MIT",

View file

@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/JuliaEditorSupport/atom-language-julia/commit/63325eb9959b57282e2804e5d7215d240a9a6fd6",
"version": "https://github.com/JuliaEditorSupport/atom-language-julia/commit/6c80921298caa9e6c382f1fecec0bf3a83c3d9ec",
"name": "Julia",
"scopeName": "source.julia",
"comment": "This grammar is used by Atom (Oniguruma), GitHub (PCRE), and VSCode (Oniguruma),\nso all regexps must be compatible with both engines.\n\nSpecs:\n- https://github.com/kkos/oniguruma/blob/master/doc/RE\n- https://www.pcre.org/current/doc/html/",
@ -176,7 +176,7 @@
"name": "support.type.julia"
}
},
"match": "((?:[[:alpha:]_\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}\\p{Nl}\\p{Sc}⅀-⅄∿⊾⊿⊤⊥∂∅-∇∎∏∐∑∞∟∫-∳⋀-⋃◸-◿♯⟘⟙⟀⟁⦰-⦴⨀-⨆⨉-⨖⨛⨜𝛁𝛛𝛻𝜕𝜵𝝏𝝯𝞉𝞩𝟃ⁱ-⁾₁-₎∠-∢⦛-⦯℘℮゛-゜𝟎-𝟡]|[^\\P{So}←-⇿])(?:[[:word:]_!\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}\\p{Nl}\\p{Sc}⅀-⅄∿⊾⊿⊤⊥∂∅-∇∎∏∐∑∞∟∫-∳⋀-⋃◸-◿♯⟘⟙⟀⟁⦰-⦴⨀-⨆⨉-⨖⨛⨜𝛁𝛛𝛻𝜕𝜵𝝏𝝯𝞉𝞩𝟃ⁱ-⁾₁-₎∠-∢⦛-⦯℘℮゛-゜𝟎-𝟡]|[^\\P{Mn}\u0001-¡]|[^\\P{Mc}\u0001-¡]|[^\\P{Nd}\u0001-¡]|[^\\P{Pc}\u0001-¡]|[^\\P{Sk}\u0001-¡]|[^\\P{Me}\u0001-¡]|[^\\P{No}\u0001-¡]|[-‷⁗]|[^\\P{So}←-⇿])*)({(?:[^{}]|{(?:[^{}]|{[^{}]*})*})*})?(?=\\(.*\\)(::[^\\s]+)?(\\s*\\bwhere\\b\\s+.+?)?\\s*?=(?![=>]))",
"match": "((?:[[:alpha:]_\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}\\p{Nl}\\p{Sc}⅀-⅄∿⊾⊿⊤⊥∂∅-∇∎∏∐∑∞∟∫-∳⋀-⋃◸-◿♯⟘⟙⟀⟁⦰-⦴⨀-⨆⨉-⨖⨛⨜𝛁𝛛𝛻𝜕𝜵𝝏𝝯𝞉𝞩𝟃ⁱ-⁾₁-₎∠-∢⦛-⦯℘℮゛-゜𝟎-𝟡]|[^\\P{So}←-⇿])(?:[[:word:]_!\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}\\p{Nl}\\p{Sc}⅀-⅄∿⊾⊿⊤⊥∂∅-∇∎∏∐∑∞∟∫-∳⋀-⋃◸-◿♯⟘⟙⟀⟁⦰-⦴⨀-⨆⨉-⨖⨛⨜𝛁𝛛𝛻𝜕𝜵𝝏𝝯𝞉𝞩𝟃ⁱ-⁾₁-₎∠-∢⦛-⦯℘℮゛-゜𝟎-𝟡]|[^\\P{Mn}\u0001-¡]|[^\\P{Mc}\u0001-¡]|[^\\P{Nd}\u0001-¡]|[^\\P{Pc}\u0001-¡]|[^\\P{Sk}\u0001-¡]|[^\\P{Me}\u0001-¡]|[^\\P{No}\u0001-¡]|[-‷⁗]|[^\\P{So}←-⇿])*)({(?:[^{}]|{(?:[^{}]|{[^{}]*})*})*})?(?=\\([^#]*\\)(::[^\\s]+)?(\\s*\\bwhere\\b\\s+.+?)?\\s*?=(?![=>]))",
"comment": "first group is function name\nSecond group is type parameters (e.g. {T<:Number, S})\nThen open parens\nThen a lookahead ensures that we are followed by:\n - anything (function argumnets)\n - 0 or more spaces\n - Finally an equal sign\nNegative lookahead ensures we don't have another equal sign (not `==`)"
},
{
@ -308,7 +308,7 @@
"name": "keyword.operator.ternary.julia"
},
{
"match": "(?:\\|\\||&&|(?<![[:word:]])!)",
"match": "(?:\\|\\||&&|(?<!(?:[[:word:]_!\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}\\p{Nl}\\p{Sc}⅀-⅄∿⊾⊿⊤⊥∂∅-∇∎∏∐∑∞∟∫-∳⋀-⋃◸-◿♯⟘⟙⟀⟁⦰-⦴⨀-⨆⨉-⨖⨛⨜𝛁𝛛𝛻𝜕𝜵𝝏𝝯𝞉𝞩𝟃ⁱ-⁾₁-₎∠-∢⦛-⦯℘℮゛-゜𝟎-𝟡]|[^\\P{Mn}\u0001-¡]|[^\\P{Mc}\u0001-¡]|[^\\P{Nd}\u0001-¡]|[^\\P{Pc}\u0001-¡]|[^\\P{Sk}\u0001-¡]|[^\\P{Me}\u0001-¡]|[^\\P{No}\u0001-¡]|[-‷⁗]|[^\\P{So}←-⇿]))!)",
"name": "keyword.operator.boolean.julia"
},
{
@ -945,7 +945,7 @@
"name": "punctuation.definition.string.end.julia"
},
"2": {
"name": "punctuation.definition.string.end.julia"
"name": "support.function.macro.julia"
}
},
"name": "string.quoted.other.julia",
@ -971,7 +971,7 @@
"name": "punctuation.definition.string.end.julia"
},
"2": {
"name": "punctuation.definition.string.end.julia"
"name": "support.function.macro.julia"
}
},
"name": "string.quoted.other.julia",
@ -997,7 +997,7 @@
"name": "punctuation.definition.string.end.julia"
},
"2": {
"name": "punctuation.definition.string.end.julia"
"name": "support.function.macro.julia"
}
},
"name": "string.interpolated.backtick.julia",
@ -1023,7 +1023,7 @@
"name": "punctuation.definition.string.end.julia"
},
"2": {
"name": "punctuation.definition.string.end.julia"
"name": "support.function.macro.julia"
}
},
"name": "string.interpolated.backtick.julia",

View file

@ -1,7 +1,9 @@
test/**
test-workspace/**
src/**
notebook/**
tsconfig.json
tsconfig.*.json
out/test/**
out/**
extension.webpack.config.js
@ -10,3 +12,4 @@ cgmanifest.json
yarn.lock
preview-src/**
webpack.config.js
esbuild.js

View file

@ -14,4 +14,6 @@ module.exports = withBrowserDefaults({
entry: {
extension: './src/extension.ts'
}
}, {
configFile: 'tsconfig.browser.json'
});

View file

@ -355,14 +355,13 @@
"highlight.js": "^10.4.1",
"markdown-it": "^12.0.3",
"markdown-it-front-matter": "^0.2.1",
"vscode-extension-telemetry": "0.1.7",
"vscode-extension-telemetry": "0.2.8",
"vscode-nls": "^5.0.0"
},
"devDependencies": {
"@types/highlight.js": "10.1.0",
"@types/lodash.throttle": "^4.1.3",
"@types/markdown-it": "0.0.2",
"@types/node": "14.x",
"@types/vscode-webview": "^1.57.0",
"lodash.throttle": "^4.1.1"
},

View file

@ -15,7 +15,7 @@
"markdown.previewSide.title": "Open Preview to the Side",
"markdown.showLockedPreviewToSide.title": "Open Locked Preview to the Side",
"markdown.showSource.title": "Show Source",
"markdown.styles.dec": "A list of URLs or local paths to CSS style sheets to use from the Markdown preview. Relative paths are interpreted relative to the folder open in the explorer. If there is no open folder, they are interpreted relative to the location of the Markdown file. All '\\' need to be written as '\\\\'.",
"markdown.styles.dec": "A list of URLs or local paths to CSS style sheets to use from the Markdown preview. Relative paths are interpreted relative to the folder open in the Explorer. If there is no open folder, they are interpreted relative to the location of the Markdown file. All '\\' need to be written as '\\\\'.",
"markdown.showPreviewSecuritySelector.title": "Change Preview Security Settings",
"markdown.trace.desc": "Enable debug logging for the Markdown extension.",
"markdown.preview.refresh.title": "Refresh Preview",

View file

@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { Command } from '../commandManager';
export class MoveCursorToPositionCommand implements Command {

View file

@ -4,12 +4,11 @@
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { extname } from 'path';
import { Command } from '../commandManager';
import { MarkdownEngine } from '../markdownEngine';
import { TableOfContentsProvider } from '../tableOfContentsProvider';
import { isMarkdownFile } from '../util/file';
import { extname } from '../util/path';
type UriComponents = {

View file

@ -4,11 +4,11 @@
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { Command } from '../commandManager';
import { MarkdownPreviewManager, DynamicPreviewSettings } from '../features/previewManager';
import { DynamicPreviewSettings, MarkdownPreviewManager } from '../features/previewManager';
import { TelemetryReporter } from '../telemetryReporter';
interface ShowPreviewSettings {
readonly sideBySide?: boolean;
readonly locked?: boolean;

View file

@ -5,9 +5,9 @@
import * as vscode from 'vscode';
import { Command } from '../commandManager';
import { MarkdownPreviewManager } from '../features/previewManager';
import { PreviewSecuritySelector } from '../security';
import { isMarkdownFile } from '../util/file';
import { MarkdownPreviewManager } from '../features/previewManager';
export class ShowPreviewSecuritySelectorCommand implements Command {
public readonly id = 'markdown.showPreviewSecuritySelector';

View file

@ -9,9 +9,9 @@ import * as commands from './commands/index';
import LinkProvider from './features/documentLinkProvider';
import MDDocumentSymbolProvider from './features/documentSymbolProvider';
import MarkdownFoldingProvider from './features/foldingProvider';
import MarkdownSmartSelect from './features/smartSelect';
import { MarkdownContentProvider } from './features/previewContentProvider';
import { MarkdownPreviewManager } from './features/previewManager';
import MarkdownSmartSelect from './features/smartSelect';
import MarkdownWorkspaceSymbolProvider from './features/workspaceSymbolProvider';
import { Logger } from './logger';
import { MarkdownEngine } from './markdownEngine';

View file

@ -3,11 +3,11 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as path from 'path';
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { OpenDocumentLinkCommand } from '../commands/openDocumentLink';
import { getUriForLinkWithKnownExternalScheme, isOfScheme, Schemes } from '../util/links';
import { dirname } from '../util/path';
const localize = nls.loadMessageBundle();
@ -43,7 +43,7 @@ function parseLink(
resourceUri = vscode.Uri.joinPath(root, tempUri.path);
}
} else {
const base = document.uri.with({ path: path.dirname(document.uri.fsPath) });
const base = document.uri.with({ path: dirname(document.uri.fsPath) });
resourceUri = vscode.Uri.joinPath(base, tempUri.path);
}
}

View file

@ -5,7 +5,7 @@
import * as vscode from 'vscode';
import { MarkdownEngine } from '../markdownEngine';
import { TableOfContentsProvider, SkinnyTextDocument, TocEntry } from '../tableOfContentsProvider';
import { SkinnyTextDocument, TableOfContentsProvider, TocEntry } from '../tableOfContentsProvider';
interface MarkdownSymbol {
readonly level: number;

View file

@ -3,20 +3,20 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as path from 'path';
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { OpenDocumentLinkCommand, resolveLinkToMarkdownFile } from '../commands/openDocumentLink';
import { Logger } from '../logger';
import { MarkdownEngine } from '../markdownEngine';
import { MarkdownContributionProvider } from '../markdownExtensions';
import { Disposable } from '../util/dispose';
import { isMarkdownFile } from '../util/file';
import * as path from '../util/path';
import { WebviewResourceProvider } from '../util/resources';
import { getVisibleLine, LastScrollLocation, TopmostLineMonitor } from '../util/topmostLineMonitor';
import { urlToUri } from '../util/url';
import { MarkdownPreviewConfigurationManager } from './previewConfig';
import { MarkdownContentProvider, MarkdownContentProviderOutput } from './previewContentProvider';
import { MarkdownEngine } from '../markdownEngine';
import { urlToUri } from '../util/url';
const localize = nls.loadMessageBundle();

View file

@ -3,13 +3,13 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as path from 'path';
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { Logger } from '../logger';
import { MarkdownEngine } from '../markdownEngine';
import { MarkdownContributionProvider } from '../markdownExtensions';
import { ContentSecurityPolicyArbiter, MarkdownPreviewSecurityLevel } from '../security';
import { basename, dirname, isAbsolute, join } from '../util/path';
import { WebviewResourceProvider } from '../util/resources';
import { MarkdownPreviewConfiguration, MarkdownPreviewConfigurationManager } from './previewConfig';
@ -110,7 +110,7 @@ export class MarkdownContentProvider {
public provideFileNotFoundContent(
resource: vscode.Uri,
): string {
const resourcePath = path.basename(resource.fsPath);
const resourcePath = basename(resource.fsPath);
const body = localize('preview.notFound', '{0} cannot be found', resourcePath);
return `<!DOCTYPE html>
<html>
@ -136,7 +136,7 @@ export class MarkdownContentProvider {
}
// Assume it must be a local file
if (path.isAbsolute(href)) {
if (isAbsolute(href)) {
return resourceProvider.asWebviewUri(vscode.Uri.file(href)).toString();
}
@ -147,7 +147,7 @@ export class MarkdownContentProvider {
}
// Otherwise look relative to the markdown file
return resourceProvider.asWebviewUri(vscode.Uri.file(path.join(path.dirname(resource.fsPath), href))).toString();
return resourceProvider.asWebviewUri(vscode.Uri.file(join(dirname(resource.fsPath), href))).toString();
}
private computeCustomStyleSheetIncludes(resourceProvider: WebviewResourceProvider, resource: vscode.Uri, config: MarkdownPreviewConfiguration): string {

View file

@ -8,11 +8,11 @@ import { Logger } from '../logger';
import { MarkdownEngine } from '../markdownEngine';
import { MarkdownContributionProvider } from '../markdownExtensions';
import { Disposable, disposeAll } from '../util/dispose';
import { isMarkdownFile } from '../util/file';
import { TopmostLineMonitor } from '../util/topmostLineMonitor';
import { DynamicMarkdownPreview, ManagedMarkdownPreview, StartingScrollFragment, StaticMarkdownPreview, scrollEditorToLine } from './preview';
import { DynamicMarkdownPreview, ManagedMarkdownPreview, scrollEditorToLine, StartingScrollFragment, StaticMarkdownPreview } from './preview';
import { MarkdownPreviewConfigurationManager } from './previewConfig';
import { MarkdownContentProvider } from './previewContentProvider';
import { isMarkdownFile } from '../util/file';
export interface DynamicPreviewSettings {
readonly resourceColumn: vscode.ViewColumn;

View file

@ -4,11 +4,11 @@
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { SkinnyTextDocument, SkinnyTextLine } from '../tableOfContentsProvider';
import { Disposable } from '../util/dispose';
import { isMarkdownFile } from '../util/file';
import { Lazy, lazy } from '../util/lazy';
import MDDocumentSymbolProvider from './documentSymbolProvider';
import { SkinnyTextDocument, SkinnyTextLine } from '../tableOfContentsProvider';
export interface WorkspaceMarkdownDocumentProvider {
getAllMarkdownDocuments(): Thenable<Iterable<SkinnyTextDocument>>;
@ -26,10 +26,25 @@ class VSCodeWorkspaceMarkdownDocumentProvider extends Disposable implements Work
private _watcher: vscode.FileSystemWatcher | undefined;
async getAllMarkdownDocuments() {
private readonly utf8Decoder = new TextDecoder('utf-8');
/**
* Reads and parses all .md documents in the workspace.
* Files are processed in batches, to keep the number of open files small.
*
* @returns Array of processed .md files.
*/
async getAllMarkdownDocuments(): Promise<SkinnyTextDocument[]> {
const maxConcurrent = 20;
const docList: SkinnyTextDocument[] = [];
const resources = await vscode.workspace.findFiles('**/*.md', '**/node_modules/**');
const docs = await Promise.all(resources.map(doc => this.getMarkdownDocument(doc)));
return docs.filter(doc => !!doc) as SkinnyTextDocument[];
for (let i = 0; i < resources.length; i += maxConcurrent) {
const resourceBatch = resources.slice(i, i + maxConcurrent);
const documentBatch = (await Promise.all(resourceBatch.map(this.getMarkdownDocument))).filter((doc) => !!doc) as SkinnyTextDocument[];
docList.push(...documentBatch);
}
return docList;
}
public get onDidChangeMarkdownDocument() {
@ -88,7 +103,7 @@ class VSCodeWorkspaceMarkdownDocumentProvider extends Disposable implements Work
const bytes = await vscode.workspace.fs.readFile(resource);
// We assume that markdown is in UTF-8
const text = Buffer.from(bytes).toString('utf-8');
const text = this.utf8Decoder.decode(bytes);
const lines: SkinnyTextLine[] = [];
const parts = text.split(/(\r?\n)/);

View file

@ -96,7 +96,7 @@ export class MarkdownEngine {
}
}
const frontMatterPlugin = require('markdown-it-front-matter');
const frontMatterPlugin = await import('markdown-it-front-matter');
// Extract rules from front matter plugin and apply at a lower precedence
let fontMatterRule: any;
frontMatterPlugin({

View file

@ -4,10 +4,10 @@
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { MarkdownPreviewManager } from './features/previewManager';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();

Some files were not shown because too many files have changed in this diff Show more