This commit is contained in:
ADS Merger 2020-06-18 04:32:54 +00:00 коммит произвёл AzureDataStudio
Родитель a971aee5bd
Коммит 5e7071e466
1002 изменённых файлов: 24201 добавлений и 13193 удалений

Просмотреть файл

@ -42,7 +42,15 @@
"jsdoc/no-types": "warn",
"semi": "off",
"@typescript-eslint/semi": "warn",
"@typescript-eslint/class-name-casing": "warn",
"@typescript-eslint/naming-convention": [
"warn",
{
"selector": "class",
"format": [
"PascalCase"
]
}
],
"code-no-unused-expressions": [
"warn",
{

23
.github/workflows/deep-classifier-monitor.yml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,23 @@
name: "Deep Classifier: Monitor"
on:
issues:
types: [unassigned]
jobs:
main:
runs-on: ubuntu-latest
steps:
- name: Checkout Actions
uses: actions/checkout@v2
with:
repository: 'microsoft/vscode-github-triage-actions'
ref: master
path: ./actions
- name: Install Actions
run: npm install --production --prefix ./actions
- name: "Run Classifier: Scraper"
uses: ./actions/classifier-deep/monitor
with:
botName: vscode-triage-bot
token: ${{secrets.VSCODE_ISSUE_TRIAGE_BOT_PAT}}
appInsightsKey: ${{secrets.TRIAGE_ACTIONS_APP_INSIGHTS}}

49
.github/workflows/deep-classifier-runner.yml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,49 @@
name: "Deep Classifier: Runner"
on:
schedule:
- cron: 0/30 * * * *
repository_dispatch:
types: [trigger-deep-classifier-runner]
jobs:
main:
runs-on: ubuntu-latest
steps:
- name: Checkout Actions
uses: actions/checkout@v2
with:
repository: 'microsoft/vscode-github-triage-actions'
ref: v30
path: ./actions
- name: Install Actions
run: npm install --production --prefix ./actions
- name: Install Additional Dependencies
# Pulls in a bunch of other packages that arent needed for the rest of the actions
run: npm install @azure/storage-blob@12
- name: "Run Classifier: Scraper"
uses: ./actions/classifier-deep/apply/fetch-sources
with:
# slightly overlapping to protect against issues slipping through the cracks if a run is delayed
from: 40
until: 5
configPath: classifier
blobContainerName: vscode-issue-classifier
blobStorageKey: ${{secrets.AZURE_BLOB_STORAGE_CONNECTION_STRING}}
token: ${{secrets.VSCODE_ISSUE_TRIAGE_BOT_PAT}}
appInsightsKey: ${{secrets.TRIAGE_ACTIONS_APP_INSIGHTS}}
- name: Set up Python 3.7
uses: actions/setup-python@v1
with:
python-version: 3.7
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install --upgrade numpy scipy scikit-learn joblib nltk simpletransformers torch torchvision
- name: "Run Classifier: Generator"
run: python ./actions/classifier-deep/apply/generate-labels/main.py
- name: "Run Classifier: Labeler"
uses: ./actions/classifier-deep/apply/apply-labels
with:
configPath: classifier
appInsightsKey: ${{secrets.TRIAGE_ACTIONS_APP_INSIGHTS}}
token: ${{secrets.VSCODE_ISSUE_TRIAGE_BOT_PAT}}

27
.github/workflows/deep-classifier-scraper.yml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,27 @@
name: "Deep Classifier: Scraper"
on:
repository_dispatch:
types: [trigger-deep-classifier-scraper]
jobs:
main:
runs-on: ubuntu-latest
steps:
- name: Checkout Actions
uses: actions/checkout@v2
with:
repository: 'microsoft/vscode-github-triage-actions'
ref: master
path: ./actions
- name: Install Actions
run: npm install --production --prefix ./actions
- name: Install Additional Dependencies
# Pulls in a bunch of other packages that arent needed for the rest of the actions
run: npm install @azure/storage-blob@12
- name: "Run Classifier: Scraper"
uses: ./actions/classifier-deep/train/fetch-issues
with:
blobContainerName: vscode-issue-classifier
blobStorageKey: ${{secrets.AZURE_BLOB_STORAGE_CONNECTION_STRING}}
token: ${{secrets.ISSUE_SCRAPER_TOKEN}}
appInsightsKey: ${{secrets.TRIAGE_ACTIONS_APP_INSIGHTS}}

25
.github/workflows/latest-release-monitor.yml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,25 @@
name: Latest Release Monitor
on:
schedule:
- cron: 0/5 * * * *
jobs:
main:
runs-on: ubuntu-latest
steps:
- name: Checkout Actions
uses: actions/checkout@v2
with:
repository: 'microsoft/vscode-github-triage-actions'
path: ./actions
ref: v30
- name: Install Actions
run: npm install --production --prefix ./actions
- name: Install Storage Module
run: npm install @azure/storage-blob
- name: Run Latest Release Monitor
uses: ./actions/latest-release-monitor
with:
storageKey: ${{secrets.AZURE_BLOB_STORAGE_CONNECTION_STRING}}
appInsightsKey: ${{secrets.TRIAGE_ACTIONS_APP_INSIGHTS}}
token: ${{secrets.VSCODE_ISSUE_TRIAGE_BOT_PAT}}

32
.github/workflows/release-pipeline-labeler.yml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,32 @@
name: "Release Pipeline Labeler"
on:
issues:
types: [closed, reopened]
repository_dispatch:
types: [released-insider]
jobs:
main:
runs-on: ubuntu-latest
steps:
- name: Checkout Actions
uses: actions/checkout@v2
with:
repository: 'microsoft/vscode-github-triage-actions'
ref: v30
path: ./actions
- name: Checkout Repo
if: github.event_name != 'issues'
uses: actions/checkout@v2
with:
path: ./repo
fetch-depth: 0
- name: Install Actions
run: npm install --production --prefix ./actions
- name: "Run Release Pipeline Labeler"
uses: ./actions/release-pipeline
with:
token: ${{secrets.VSCODE_ISSUE_TRIAGE_BOT_PAT}}
appInsightsKey: ${{secrets.TRIAGE_ACTIONS_APP_INSIGHTS}}
notYetReleasedLabel: unreleased
insidersReleasedLabel: insiders-released

19
.github/workflows/rich-navigation.yml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,19 @@
name: "Rich Navigation Indexing"
on:
pull_request:
push:
branches:
- master
jobs:
richnav:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- name: Use Node.js
uses: actions/setup-node@v1
- name: Install dependencies
run: yarn install
- uses: microsoft/RichCodeNavIndexer@master
with:
languages: typescript

3
.vscode/extensions.json поставляемый
Просмотреть файл

@ -4,6 +4,7 @@
"recommendations": [
"dbaeumer.vscode-eslint",
"EditorConfig.EditorConfig",
"msjsdiag.debugger-for-chrome"
"msjsdiag.debugger-for-chrome",
"ms-vscode.vscode-github-issue-notebooks"
]
}

15
.vscode/launch.json поставляемый
Просмотреть файл

@ -109,7 +109,7 @@
"type": "chrome",
"request": "launch",
"name": "Launch ADS (Web) (TBD)",
"program": "${workspaceFolder}/scripts/code-web.js",
"program": "${workspaceFolder}/resources/serverless/code-web.js",
"presentation": {
"group": "0_vscode",
"order": 2
@ -145,6 +145,18 @@
"order": 3
}
},
{
"type": "pwa-msedge",
"request": "launch",
"name": "VS Code (Web, Edge)",
"url": "http://localhost:8080",
"pauseForSourceMap": false,
"preLaunchTask": "Run web",
"presentation": {
"group": "0_vscode",
"order": 3
}
},
{
"type": "node",
"request": "launch",
@ -251,6 +263,7 @@
},
{
"name": "Azure Data Studio",
"stopAll": true,
"configurations": [
"Launch azuredatastudio",
"Attach to Main Process",

36
.vscode/notebooks/inbox.github-issues поставляемый Normal file
Просмотреть файл

@ -0,0 +1,36 @@
[
{
"kind": 1,
"language": "markdown",
"value": "##### `Config`: defines the inbox query"
},
{
"kind": 2,
"language": "github-issues",
"value": "$inbox=repo:microsoft/vscode is:open no:assignee -label:feature-request -label:testplan-item -label:plan-item "
},
{
"kind": 1,
"language": "markdown",
"value": "## Triage Inbox\n\nAll inbox issues but not those that need more information. These issues need to be triaged, e.g assigned to a user or ask for more information",
"editable": true
},
{
"kind": 2,
"language": "github-issues",
"value": "$inbox -label:\"needs more info\"",
"editable": true
},
{
"kind": 1,
"language": "markdown",
"value": "## Inbox\n\nAll issues that have no assignee and that have neither **feature requests** nor **test plan items** nor **plan items**.",
"editable": true
},
{
"kind": 2,
"language": "github-issues",
"value": "$inbox",
"editable": true
}
]

98
.vscode/notebooks/my-work.github-issues поставляемый Normal file
Просмотреть файл

@ -0,0 +1,98 @@
[
{
"kind": 1,
"language": "markdown",
"value": "##### `Config`: This should be changed every month/milestone",
"editable": true
},
{
"kind": 2,
"language": "github-issues",
"value": "// list of repos we work in\n$repos=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks\n\n// current milestone name\n$milestone=milestone:\"June 2020\"",
"editable": true
},
{
"kind": 1,
"language": "github-issues",
"value": "## Milestone Work",
"editable": true
},
{
"kind": 2,
"language": "github-issues",
"value": "$repos $milestone assignee:@me is:open\n",
"editable": false
},
{
"kind": 1,
"language": "github-issues",
"value": "## Bugs, Debt, Features...",
"editable": true
},
{
"kind": 1,
"language": "markdown",
"value": "#### My Bugs",
"editable": true
},
{
"kind": 2,
"language": "github-issues",
"value": "$repos assignee:@me is:open label:bug",
"editable": true
},
{
"kind": 1,
"language": "markdown",
"value": "#### Debt & Engineering",
"editable": true
},
{
"kind": 2,
"language": "github-issues",
"value": "$repos assignee:@me is:open label:debt OR $repos assignee:@me is:open label:engineering",
"editable": true
},
{
"kind": 1,
"language": "markdown",
"value": "#### Performance 🐌 🔜 🏎",
"editable": true
},
{
"kind": 2,
"language": "github-issues",
"value": "$repos assignee:@me is:open label:perf OR $repos assignee:@me is:open label:perf-startup OR $repos assignee:@me is:open label:perf-bloat OR $repos assignee:@me is:open label:freeze-slow-crash-leak",
"editable": true
},
{
"kind": 1,
"language": "markdown",
"value": "#### Feature Requests",
"editable": true
},
{
"kind": 2,
"language": "github-issues",
"value": "$repos assignee:@me is:open label:feature-request milestone:Backlog sort:reactions-+1-desc",
"editable": true
},
{
"kind": 2,
"language": "github-issues",
"value": "$repos assignee:@me is:open milestone:\"Backlog Candidates\"",
"editable": false
},
{
"kind": 1,
"language": "markdown",
"value": "#### Not Actionable",
"editable": true
},
{
"kind": 2,
"language": "github-issues",
"value": "$repos assignee:@me is:open label:\"needs more info\"",
"editable": false
}
]

10
.vscode/searches/es6.code-search поставляемый
Просмотреть файл

@ -79,8 +79,8 @@ src/vs/base/common/strings.ts:
170 */
171 export function endsWith(haystack: string, needle: string): boolean {
853
854 /**
855: * @deprecated ES6
856 */
857 export function repeat(s: string, count: number): string {
861
862 /**
863: * @deprecated ES6
864 */
865 export function repeat(s: string, count: number): string {

2
.vscode/settings.json поставляемый
Просмотреть файл

@ -72,7 +72,7 @@
},
"gulp.autoDetect": "off",
"files.insertFinalNewline": true,
"[typescript]": {
"[typescript]": {
"editor.defaultFormatter": "vscode.typescript-language-features"
},
"typescript.tsc.autoDetect": "off"

2
.vscode/tasks.json поставляемый
Просмотреть файл

@ -89,7 +89,7 @@
},
{
"type": "shell",
"command": "yarn web -- --no-launch",
"command": "yarn web --no-launch",
"label": "Run web",
"isBackground": true,
"problemMatcher": {

Просмотреть файл

@ -1,3 +1,3 @@
disturl "https://atom.io/download/electron"
target "7.3.0"
target "7.3.1"
runtime "electron"

Просмотреть файл

@ -29,15 +29,7 @@ steps:
yarn electron x64
displayName: Download Electron
- script: |
yarn gulp hygiene
displayName: Run Hygiene Checks
- script: | # {{SQL CARBON EDIT}} add step
yarn strict-vscode
displayName: Run Strict Null Check.
# - script: | {{SQL CARBON EDIT}} remove step
# - script: | {{SQL CARBON EDIT}} remove editor checks
# yarn monaco-compile-check
# displayName: Run Monaco Editor Checks

Просмотреть файл

@ -36,15 +36,7 @@ steps:
yarn electron
displayName: Download Electron
- script: |
yarn gulp hygiene
displayName: Run Hygiene Checks
- script: | # {{SQL CARBON EDIT}} add step
yarn strict-vscode
displayName: Run Strict Null Check
# - powershell: | {{SQL CARBON EDIT}} remove step
# - powershell: | {{SQL CARBON EDIT}} remove editor check
# yarn monaco-compile-check
# displayName: Run Monaco Editor Checks

Просмотреть файл

@ -10,7 +10,7 @@ const path = require('path');
let window = null;
app.once('ready', () => {
window = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, webviewTag: true, enableWebSQL: false } });
window = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, webviewTag: true, enableWebSQL: false, nativeWindowOpen: true } });
window.setMenuBarVisibility(false);
window.loadURL(url.format({ pathname: path.join(__dirname, 'index.html'), protocol: 'file:', slashes: true }));
// window.webContents.openDevTools();

Просмотреть файл

@ -144,6 +144,7 @@ const copyrightFilter = [
'!extensions/*/server/bin/*',
'!src/vs/editor/test/node/classification/typescript-test.ts',
'!scripts/code-web.js',
'!resources/serverless/code-web.js',
// {{SQL CARBON EDIT}}
'!extensions/notebook/src/intellisense/text.ts',
'!extensions/mssql/src/hdfs/webhdfs.ts',

Просмотреть файл

@ -4,7 +4,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.packageRebuildExtensionsStream = exports.cleanRebuildExtensions = exports.packageExternalExtensionsStream = exports.packageMarketplaceExtensionsStream = exports.packageLocalExtensionsStream = exports.fromMarketplace = void 0;
exports.packageRebuildExtensionsStream = exports.cleanRebuildExtensions = exports.packageExternalExtensionsStream = exports.packageMarketplaceWebExtensionsStream = exports.packageMarketplaceExtensionsStream = exports.packageLocalWebExtensionsStream = exports.packageLocalExtensionsStream = exports.fromMarketplace = void 0;
const es = require("event-stream");
const fs = require("fs");
const glob = require("glob");
@ -28,11 +28,7 @@ const util = require('./util');
const root = path.dirname(path.dirname(__dirname));
const commit = util.getVersion(root);
const sourceMappingURLBase = `https://sqlopsbuilds.blob.core.windows.net/sourcemaps/${commit}`;
function fromLocal(extensionPath) {
const webpackFilename = path.join(extensionPath, 'extension.webpack.config.js');
const input = fs.existsSync(webpackFilename)
? fromLocalWebpack(extensionPath)
: fromLocalNormal(extensionPath);
function minimizeLanguageJSON(input) {
const tmLanguageJsonFilter = filter('**/*.tmLanguage.json', { restore: true });
return input
.pipe(tmLanguageJsonFilter)
@ -43,12 +39,49 @@ function fromLocal(extensionPath) {
}))
.pipe(tmLanguageJsonFilter.restore);
}
function fromLocalWebpack(extensionPath) {
function updateExtensionPackageJSON(input, update) {
const packageJsonFilter = filter('extensions/*/package.json', { restore: true });
return input
.pipe(packageJsonFilter)
.pipe(buffer())
.pipe(es.mapSync((f) => {
const data = JSON.parse(f.contents.toString('utf8'));
f.contents = Buffer.from(JSON.stringify(update(data)));
return f;
}))
.pipe(packageJsonFilter.restore);
}
function fromLocal(extensionPath, forWeb) {
const webpackConfigFileName = forWeb ? 'extension-browser.webpack.config.js' : 'extension.webpack.config.js';
const isWebPacked = fs.existsSync(path.join(extensionPath, webpackConfigFileName));
let input = isWebPacked
? fromLocalWebpack(extensionPath, webpackConfigFileName)
: fromLocalNormal(extensionPath);
if (forWeb) {
input = updateExtensionPackageJSON(input, (data) => {
if (data.browser) {
data.main = data.browser;
}
data.extensionKind = ['web'];
return data;
});
}
else if (isWebPacked) {
input = updateExtensionPackageJSON(input, (data) => {
if (data.main) {
data.main = data.main.replace('/out/', /dist/);
}
return data;
});
}
return minimizeLanguageJSON(input);
}
function fromLocalWebpack(extensionPath, webpackConfigFileName) {
const result = es.through();
const packagedDependencies = [];
const packageJsonConfig = require(path.join(extensionPath, 'package.json'));
if (packageJsonConfig.dependencies) {
const webpackRootConfig = require(path.join(extensionPath, 'extension.webpack.config.js'));
const webpackRootConfig = require(path.join(extensionPath, webpackConfigFileName));
for (const key in webpackRootConfig.externals) {
if (key in packageJsonConfig.dependencies) {
packagedDependencies.push(key);
@ -64,30 +97,9 @@ function fromLocalWebpack(extensionPath) {
base: extensionPath,
contents: fs.createReadStream(filePath)
}));
const filesStream = es.readArray(files);
// check for a webpack configuration files, then invoke webpack
// and merge its output with the files stream. also rewrite the package.json
// file to a new entry point
const webpackConfigLocations = glob.sync(path.join(extensionPath, '/**/extension.webpack.config.js'), { ignore: ['**/node_modules'] });
const packageJsonFilter = filter(f => {
if (path.basename(f.path) === 'package.json') {
// only modify package.json's next to the webpack file.
// to be safe, use existsSync instead of path comparison.
return fs.existsSync(path.join(path.dirname(f.path), 'extension.webpack.config.js'));
}
return false;
}, { restore: true });
const patchFilesStream = filesStream
.pipe(packageJsonFilter)
.pipe(buffer())
.pipe(json((data) => {
if (data.main) {
// hardcoded entry point directory!
data.main = data.main.replace('/out/', /dist/);
}
return data;
}))
.pipe(packageJsonFilter.restore);
// and merge its output with the files stream.
const webpackConfigLocations = glob.sync(path.join(extensionPath, '**', webpackConfigFileName), { ignore: ['**/node_modules'] });
const webpackStreams = webpackConfigLocations.map(webpackConfigPath => {
const webpackDone = (err, stats) => {
fancyLog(`Bundled extension: ${ansiColors.yellow(path.join(path.basename(extensionPath), path.relative(extensionPath, webpackConfigPath)))}...`);
@ -121,7 +133,7 @@ function fromLocalWebpack(extensionPath) {
this.emit('data', data);
}));
});
es.merge(...webpackStreams, patchFilesStream)
es.merge(...webpackStreams, es.readArray(files))
// .pipe(es.through(function (data) {
// // debug
// console.log('out', data.path, data.contents.length);
@ -228,15 +240,32 @@ function packageLocalExtensionsStream() {
.filter(({ name }) => excludedExtensions.indexOf(name) === -1)
.filter(({ name }) => builtInExtensions.every(b => b.name !== name))
.filter(({ name }) => externalExtensions.indexOf(name) === -1); // {{SQL CARBON EDIT}} Remove external Extensions with separate package
const nodeModules = gulp.src('extensions/node_modules/**', { base: '.' });
const localExtensions = localExtensionDescriptions.map(extension => {
return fromLocal(extension.path)
return fromLocal(extension.path, false)
.pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`));
});
const nodeModules = gulp.src('extensions/node_modules/**', { base: '.' });
return es.merge(nodeModules, ...localExtensions)
.pipe(util2.setExecutableBit(['**/*.sh']));
}
exports.packageLocalExtensionsStream = packageLocalExtensionsStream;
function packageLocalWebExtensionsStream() {
const localExtensionDescriptions = glob.sync('extensions/*/package.json')
.filter(manifestPath => {
const packageJsonConfig = require(path.join(root, manifestPath));
return !packageJsonConfig.main || packageJsonConfig.browser;
})
.map(manifestPath => {
const extensionPath = path.dirname(path.join(root, manifestPath));
const extensionName = path.basename(extensionPath);
return { name: extensionName, path: extensionPath };
});
return es.merge(...localExtensionDescriptions.map(extension => {
return fromLocal(extension.path, true)
.pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`));
}));
}
exports.packageLocalWebExtensionsStream = packageLocalWebExtensionsStream;
function packageMarketplaceExtensionsStream() {
const extensions = builtInExtensions.map(extension => {
return fromMarketplace(extension.name, extension.version, extension.metadata)
@ -246,6 +275,22 @@ function packageMarketplaceExtensionsStream() {
.pipe(util2.setExecutableBit(['**/*.sh']));
}
exports.packageMarketplaceExtensionsStream = packageMarketplaceExtensionsStream;
function packageMarketplaceWebExtensionsStream(builtInExtensions) {
const extensions = builtInExtensions
.map(extension => {
const input = fromMarketplace(extension.name, extension.version, extension.metadata)
.pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`));
return updateExtensionPackageJSON(input, (data) => {
if (data.main) {
data.browser = data.main;
}
data.extensionKind = ['web'];
return data;
});
});
return es.merge(extensions);
}
exports.packageMarketplaceWebExtensionsStream = packageMarketplaceWebExtensionsStream;
function packageExternalExtensionsStream() {
const extenalExtensionDescriptions = glob.sync('extensions/*/package.json')
.map(manifestPath => {
@ -255,13 +300,12 @@ function packageExternalExtensionsStream() {
})
.filter(({ name }) => externalExtensions.indexOf(name) >= 0);
const builtExtensions = extenalExtensionDescriptions.map(extension => {
return fromLocal(extension.path)
return fromLocal(extension.path, false)
.pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`));
});
return es.merge(builtExtensions);
}
exports.packageExternalExtensionsStream = packageExternalExtensionsStream;
// {{SQL CARBON EDIT}} - End
function cleanRebuildExtensions(root) {
return Promise.all(rebuildExtensions.map(async (e) => {
await util2.rimraf(path.join(root, e))();
@ -277,7 +321,7 @@ function packageRebuildExtensionsStream() {
})
.filter(({ name }) => rebuildExtensions.indexOf(name) >= 0);
const builtExtensions = extenalExtensionDescriptions.map(extension => {
return fromLocal(extension.path)
return fromLocal(extension.path, false)
.pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`));
});
return es.merge(builtExtensions);

Просмотреть файл

@ -28,14 +28,8 @@ const root = path.dirname(path.dirname(__dirname));
const commit = util.getVersion(root);
const sourceMappingURLBase = `https://sqlopsbuilds.blob.core.windows.net/sourcemaps/${commit}`;
function fromLocal(extensionPath: string): Stream {
const webpackFilename = path.join(extensionPath, 'extension.webpack.config.js');
const input = fs.existsSync(webpackFilename)
? fromLocalWebpack(extensionPath)
: fromLocalNormal(extensionPath);
function minimizeLanguageJSON(input: Stream): Stream {
const tmLanguageJsonFilter = filter('**/*.tmLanguage.json', { restore: true });
return input
.pipe(tmLanguageJsonFilter)
.pipe(buffer())
@ -46,13 +40,55 @@ function fromLocal(extensionPath: string): Stream {
.pipe(tmLanguageJsonFilter.restore);
}
function fromLocalWebpack(extensionPath: string): Stream {
function updateExtensionPackageJSON(input: Stream, update: (data: any) => any): Stream {
const packageJsonFilter = filter('extensions/*/package.json', { restore: true });
return input
.pipe(packageJsonFilter)
.pipe(buffer())
.pipe(es.mapSync((f: File) => {
const data = JSON.parse(f.contents.toString('utf8'));
f.contents = Buffer.from(JSON.stringify(update(data)));
return f;
}))
.pipe(packageJsonFilter.restore);
}
function fromLocal(extensionPath: string, forWeb: boolean): Stream {
const webpackConfigFileName = forWeb ? 'extension-browser.webpack.config.js' : 'extension.webpack.config.js';
const isWebPacked = fs.existsSync(path.join(extensionPath, webpackConfigFileName));
let input = isWebPacked
? fromLocalWebpack(extensionPath, webpackConfigFileName)
: fromLocalNormal(extensionPath);
if (forWeb) {
input = updateExtensionPackageJSON(input, (data: any) => {
if (data.browser) {
data.main = data.browser;
}
data.extensionKind = ['web'];
return data;
});
} else if (isWebPacked) {
input = updateExtensionPackageJSON(input, (data: any) => {
if (data.main) {
data.main = data.main.replace('/out/', /dist/);
}
return data;
});
}
return minimizeLanguageJSON(input);
}
function fromLocalWebpack(extensionPath: string, webpackConfigFileName: string): Stream {
const result = es.through();
const packagedDependencies: string[] = [];
const packageJsonConfig = require(path.join(extensionPath, 'package.json'));
if (packageJsonConfig.dependencies) {
const webpackRootConfig = require(path.join(extensionPath, 'extension.webpack.config.js'));
const webpackRootConfig = require(path.join(extensionPath, webpackConfigFileName));
for (const key in webpackRootConfig.externals) {
if (key in packageJsonConfig.dependencies) {
packagedDependencies.push(key);
@ -70,38 +106,13 @@ function fromLocalWebpack(extensionPath: string): Stream {
contents: fs.createReadStream(filePath) as any
}));
const filesStream = es.readArray(files);
// check for a webpack configuration files, then invoke webpack
// and merge its output with the files stream. also rewrite the package.json
// file to a new entry point
// and merge its output with the files stream.
const webpackConfigLocations = (<string[]>glob.sync(
path.join(extensionPath, '/**/extension.webpack.config.js'),
path.join(extensionPath, '**', webpackConfigFileName),
{ ignore: ['**/node_modules'] }
));
const packageJsonFilter = filter(f => {
if (path.basename(f.path) === 'package.json') {
// only modify package.json's next to the webpack file.
// to be safe, use existsSync instead of path comparison.
return fs.existsSync(path.join(path.dirname(f.path), 'extension.webpack.config.js'));
}
return false;
}, { restore: true });
const patchFilesStream = filesStream
.pipe(packageJsonFilter)
.pipe(buffer())
.pipe(json((data: any) => {
if (data.main) {
// hardcoded entry point directory!
data.main = data.main.replace('/out/', /dist/);
}
return data;
}))
.pipe(packageJsonFilter.restore);
const webpackStreams = webpackConfigLocations.map(webpackConfigPath => {
const webpackDone = (err: any, stats: any) => {
@ -143,7 +154,7 @@ function fromLocalWebpack(extensionPath: string): Stream {
}));
});
es.merge(...webpackStreams, patchFilesStream)
es.merge(...webpackStreams, es.readArray(files))
// .pipe(es.through(function (data) {
// // debug
// console.log('out', data.path, data.contents.length);
@ -274,16 +285,35 @@ export function packageLocalExtensionsStream(): NodeJS.ReadWriteStream {
.filter(({ name }) => builtInExtensions.every(b => b.name !== name))
.filter(({ name }) => externalExtensions.indexOf(name) === -1); // {{SQL CARBON EDIT}} Remove external Extensions with separate package
const nodeModules = gulp.src('extensions/node_modules/**', { base: '.' });
const localExtensions = localExtensionDescriptions.map(extension => {
return fromLocal(extension.path)
return fromLocal(extension.path, false)
.pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`));
});
const nodeModules = gulp.src('extensions/node_modules/**', { base: '.' });
return es.merge(nodeModules, ...localExtensions)
.pipe(util2.setExecutableBit(['**/*.sh']));
}
export function packageLocalWebExtensionsStream(): NodeJS.ReadWriteStream {
const localExtensionDescriptions = (<string[]>glob.sync('extensions/*/package.json'))
.filter(manifestPath => {
const packageJsonConfig = require(path.join(root, manifestPath));
return !packageJsonConfig.main || packageJsonConfig.browser;
})
.map(manifestPath => {
const extensionPath = path.dirname(path.join(root, manifestPath));
const extensionName = path.basename(extensionPath);
return { name: extensionName, path: extensionPath };
});
return es.merge(...localExtensionDescriptions.map(extension => {
return fromLocal(extension.path, true)
.pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`));
}));
}
export function packageMarketplaceExtensionsStream(): NodeJS.ReadWriteStream {
const extensions = builtInExtensions.map(extension => {
return fromMarketplace(extension.name, extension.version, extension.metadata)
@ -294,6 +324,22 @@ export function packageMarketplaceExtensionsStream(): NodeJS.ReadWriteStream {
.pipe(util2.setExecutableBit(['**/*.sh']));
}
export function packageMarketplaceWebExtensionsStream(builtInExtensions: IBuiltInExtension[]): NodeJS.ReadWriteStream {
const extensions = builtInExtensions
.map(extension => {
const input = fromMarketplace(extension.name, extension.version, extension.metadata)
.pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`));
return updateExtensionPackageJSON(input, (data: any) => {
if (data.main) {
data.browser = data.main;
}
data.extensionKind = ['web'];
return data;
});
});
return es.merge(extensions);
}
export function packageExternalExtensionsStream(): NodeJS.ReadWriteStream {
const extenalExtensionDescriptions = (<string[]>glob.sync('extensions/*/package.json'))
.map(manifestPath => {
@ -304,13 +350,12 @@ export function packageExternalExtensionsStream(): NodeJS.ReadWriteStream {
.filter(({ name }) => externalExtensions.indexOf(name) >= 0);
const builtExtensions = extenalExtensionDescriptions.map(extension => {
return fromLocal(extension.path)
return fromLocal(extension.path, false)
.pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`));
});
return es.merge(builtExtensions);
}
// {{SQL CARBON EDIT}} - End
export function cleanRebuildExtensions(root: string): Promise<void> {
return Promise.all(rebuildExtensions.map(async e => {
@ -328,7 +373,7 @@ export function packageRebuildExtensionsStream(): NodeJS.ReadWriteStream {
.filter(({ name }) => rebuildExtensions.indexOf(name) >= 0);
const builtExtensions = extenalExtensionDescriptions.map(extension => {
return fromLocal(extension.path)
return fromLocal(extension.path, false)
.pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`));
});

Просмотреть файл

@ -101,161 +101,158 @@ class TextModel {
return this._lines;
}
}
let XLF = /** @class */ (() => {
class XLF {
constructor(project) {
this.project = project;
this.buffer = [];
this.files = Object.create(null);
this.numberOfMessages = 0;
class XLF {
constructor(project) {
this.project = project;
this.buffer = [];
this.files = Object.create(null);
this.numberOfMessages = 0;
}
toString() {
this.appendHeader();
for (let file in this.files) {
this.appendNewLine(`<file original="${file}" source-language="en" datatype="plaintext"><body>`, 2);
for (let item of this.files[file]) {
this.addStringItem(file, item);
}
this.appendNewLine('</body></file>', 2);
}
toString() {
this.appendHeader();
for (let file in this.files) {
this.appendNewLine(`<file original="${file}" source-language="en" datatype="plaintext"><body>`, 2);
for (let item of this.files[file]) {
this.addStringItem(file, item);
this.appendFooter();
return this.buffer.join('\r\n');
}
addFile(original, keys, messages) {
if (keys.length === 0) {
console.log('No keys in ' + original);
return;
}
if (keys.length !== messages.length) {
throw new Error(`Unmatching keys(${keys.length}) and messages(${messages.length}).`);
}
this.numberOfMessages += keys.length;
this.files[original] = [];
let existingKeys = new Set();
for (let i = 0; i < keys.length; i++) {
let key = keys[i];
let realKey;
let comment;
if (Is.string(key)) {
realKey = key;
comment = undefined;
}
else if (LocalizeInfo.is(key)) {
realKey = key.key;
if (key.comment && key.comment.length > 0) {
comment = key.comment.map(comment => encodeEntities(comment)).join('\r\n');
}
this.appendNewLine('</body></file>', 2);
}
this.appendFooter();
return this.buffer.join('\r\n');
}
addFile(original, keys, messages) {
if (keys.length === 0) {
console.log('No keys in ' + original);
return;
if (!realKey || existingKeys.has(realKey)) {
continue;
}
if (keys.length !== messages.length) {
throw new Error(`Unmatching keys(${keys.length}) and messages(${messages.length}).`);
}
this.numberOfMessages += keys.length;
this.files[original] = [];
let existingKeys = new Set();
for (let i = 0; i < keys.length; i++) {
let key = keys[i];
let realKey;
let comment;
if (Is.string(key)) {
realKey = key;
comment = undefined;
}
else if (LocalizeInfo.is(key)) {
realKey = key.key;
if (key.comment && key.comment.length > 0) {
comment = key.comment.map(comment => encodeEntities(comment)).join('\r\n');
}
}
if (!realKey || existingKeys.has(realKey)) {
continue;
}
existingKeys.add(realKey);
let message = encodeEntities(messages[i]);
this.files[original].push({ id: realKey, message: message, comment: comment });
}
}
addStringItem(file, item) {
if (!item.id || item.message === undefined || item.message === null) {
throw new Error(`No item ID or value specified: ${JSON.stringify(item)}. File: ${file}`);
}
if (item.message.length === 0) {
log(`Item with id ${item.id} in file ${file} has an empty message.`);
}
this.appendNewLine(`<trans-unit id="${item.id}">`, 4);
this.appendNewLine(`<source xml:lang="en">${item.message}</source>`, 6);
if (item.comment) {
this.appendNewLine(`<note>${item.comment}</note>`, 6);
}
this.appendNewLine('</trans-unit>', 4);
}
appendHeader() {
this.appendNewLine('<?xml version="1.0" encoding="utf-8"?>', 0);
this.appendNewLine('<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">', 0);
}
appendFooter() {
this.appendNewLine('</xliff>', 0);
}
appendNewLine(content, indent) {
let line = new Line(indent);
line.append(content);
this.buffer.push(line.toString());
existingKeys.add(realKey);
let message = encodeEntities(messages[i]);
this.files[original].push({ id: realKey, message: message, comment: comment });
}
}
XLF.parsePseudo = function (xlfString) {
return new Promise((resolve) => {
let parser = new xml2js.Parser();
let files = [];
parser.parseString(xlfString, function (_err, result) {
const fileNodes = result['xliff']['file'];
fileNodes.forEach(file => {
const originalFilePath = file.$.original;
const messages = {};
const transUnits = file.body[0]['trans-unit'];
if (transUnits) {
transUnits.forEach((unit) => {
const key = unit.$.id;
const val = pseudify(unit.source[0]['_'].toString());
if (key && val) {
messages[key] = decodeEntities(val);
}
});
files.push({ messages: messages, originalFilePath: originalFilePath, language: 'ps' });
}
});
resolve(files);
});
});
};
XLF.parse = function (xlfString) {
return new Promise((resolve, reject) => {
let parser = new xml2js.Parser();
let files = [];
parser.parseString(xlfString, function (err, result) {
if (err) {
reject(new Error(`XLF parsing error: Failed to parse XLIFF string. ${err}`));
}
const fileNodes = result['xliff']['file'];
if (!fileNodes) {
reject(new Error(`XLF parsing error: XLIFF file does not contain "xliff" or "file" node(s) required for parsing.`));
}
fileNodes.forEach((file) => {
const originalFilePath = file.$.original;
if (!originalFilePath) {
reject(new Error(`XLF parsing error: XLIFF file node does not contain original attribute to determine the original location of the resource file.`));
}
let language = file.$['target-language'];
if (!language) {
reject(new Error(`XLF parsing error: XLIFF file node does not contain target-language attribute to determine translated language.`));
}
const messages = {};
const transUnits = file.body[0]['trans-unit'];
if (transUnits) {
transUnits.forEach((unit) => {
const key = unit.$.id;
if (!unit.target) {
return; // No translation available
}
let val = unit.target[0];
if (typeof val !== 'string') {
val = val._;
}
if (key && val) {
messages[key] = decodeEntities(val);
}
else {
reject(new Error(`XLF parsing error: XLIFF file ${originalFilePath} does not contain full localization data. ID or target translation for one of the trans-unit nodes is not present.`));
}
});
files.push({ messages: messages, originalFilePath: originalFilePath, language: language.toLowerCase() });
}
});
resolve(files);
});
});
};
return XLF;
})();
addStringItem(file, item) {
if (!item.id || item.message === undefined || item.message === null) {
throw new Error(`No item ID or value specified: ${JSON.stringify(item)}. File: ${file}`);
}
if (item.message.length === 0) {
log(`Item with id ${item.id} in file ${file} has an empty message.`);
}
this.appendNewLine(`<trans-unit id="${item.id}">`, 4);
this.appendNewLine(`<source xml:lang="en">${item.message}</source>`, 6);
if (item.comment) {
this.appendNewLine(`<note>${item.comment}</note>`, 6);
}
this.appendNewLine('</trans-unit>', 4);
}
appendHeader() {
this.appendNewLine('<?xml version="1.0" encoding="utf-8"?>', 0);
this.appendNewLine('<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">', 0);
}
appendFooter() {
this.appendNewLine('</xliff>', 0);
}
appendNewLine(content, indent) {
let line = new Line(indent);
line.append(content);
this.buffer.push(line.toString());
}
}
exports.XLF = XLF;
XLF.parsePseudo = function (xlfString) {
return new Promise((resolve) => {
let parser = new xml2js.Parser();
let files = [];
parser.parseString(xlfString, function (_err, result) {
const fileNodes = result['xliff']['file'];
fileNodes.forEach(file => {
const originalFilePath = file.$.original;
const messages = {};
const transUnits = file.body[0]['trans-unit'];
if (transUnits) {
transUnits.forEach((unit) => {
const key = unit.$.id;
const val = pseudify(unit.source[0]['_'].toString());
if (key && val) {
messages[key] = decodeEntities(val);
}
});
files.push({ messages: messages, originalFilePath: originalFilePath, language: 'ps' });
}
});
resolve(files);
});
});
};
XLF.parse = function (xlfString) {
return new Promise((resolve, reject) => {
let parser = new xml2js.Parser();
let files = [];
parser.parseString(xlfString, function (err, result) {
if (err) {
reject(new Error(`XLF parsing error: Failed to parse XLIFF string. ${err}`));
}
const fileNodes = result['xliff']['file'];
if (!fileNodes) {
reject(new Error(`XLF parsing error: XLIFF file does not contain "xliff" or "file" node(s) required for parsing.`));
}
fileNodes.forEach((file) => {
const originalFilePath = file.$.original;
if (!originalFilePath) {
reject(new Error(`XLF parsing error: XLIFF file node does not contain original attribute to determine the original location of the resource file.`));
}
let language = file.$['target-language'];
if (!language) {
reject(new Error(`XLF parsing error: XLIFF file node does not contain target-language attribute to determine translated language.`));
}
const messages = {};
const transUnits = file.body[0]['trans-unit'];
if (transUnits) {
transUnits.forEach((unit) => {
const key = unit.$.id;
if (!unit.target) {
return; // No translation available
}
let val = unit.target[0];
if (typeof val !== 'string') {
val = val._;
}
if (key && val) {
messages[key] = decodeEntities(val);
}
else {
reject(new Error(`XLF parsing error: XLIFF file ${originalFilePath} does not contain full localization data. ID or target translation for one of the trans-unit nodes is not present.`));
}
});
files.push({ messages: messages, originalFilePath: originalFilePath, language: language.toLowerCase() });
}
});
resolve(files);
});
});
};
class Limiter {
constructor(maxDegreeOfParalellism) {
this.maxDegreeOfParalellism = maxDegreeOfParalellism;

Просмотреть файл

@ -138,7 +138,7 @@ function loadSourcemaps() {
version: '3',
names: [],
mappings: '',
sources: [f.relative.replace(/\//g, '/')],
sources: [f.relative],
sourcesContent: [contents]
};
cb(undefined, f);

Просмотреть файл

@ -186,7 +186,7 @@ export function loadSourcemaps(): NodeJS.ReadWriteStream {
version: '3',
names: [],
mappings: '',
sources: [f.relative.replace(/\//g, '/')],
sources: [f.relative],
sourcesContent: [contents]
};

Просмотреть файл

@ -40,7 +40,7 @@
"gulp-bom": "^1.0.0",
"gulp-sourcemaps": "^1.11.0",
"gulp-uglify": "^3.0.0",
"iconv-lite": "0.4.23",
"iconv-lite": "0.6.0",
"mime": "^1.3.4",
"minimatch": "3.0.4",
"minimist": "^1.2.3",
@ -49,7 +49,7 @@
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-node-resolve": "^5.2.0",
"terser": "4.3.8",
"typescript": "^3.9.3",
"typescript": "^4.0.0-dev.20200615",
"vsce": "1.48.0",
"vscode-telemetry-extractor": "^1.5.4",
"xml2js": "^0.4.17"

Просмотреть файл

@ -0,0 +1,26 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. 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;

Просмотреть файл

@ -0,0 +1,79 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
function format(message, args) {
let result;
// if (isPseudo) {
// // FF3B and FF3D is the Unicode zenkaku representation for [ and ]
// message = '\uFF3B' + message.replace(/[aouei]/g, '$&$&') + '\uFF3D';
// }
if (args.length === 0) {
result = message;
}
else {
result = message.replace(/\{(\d+)\}/g, function (match, rest) {
let index = rest[0];
let arg = args[index];
let replacement = match;
if (typeof arg === 'string') {
replacement = arg;
}
else if (typeof arg === 'number' || typeof arg === 'boolean' || arg === void 0 || arg === null) {
replacement = String(arg);
}
return replacement;
});
}
return result;
}
function localize(key, message) {
let args = [];
for (let _i = 2; _i < arguments.length; _i++) {
args[_i - 2] = arguments[_i];
}
return format(message, args);
}
function loadMessageBundle(file) {
return localize;
}
let MessageFormat;
(function (MessageFormat) {
MessageFormat["file"] = "file";
MessageFormat["bundle"] = "bundle";
MessageFormat["both"] = "both";
})(MessageFormat = exports.MessageFormat || (exports.MessageFormat = {}));
let BundleFormat;
(function (BundleFormat) {
// the nls.bundle format
BundleFormat["standalone"] = "standalone";
BundleFormat["languagePack"] = "languagePack";
})(BundleFormat = exports.BundleFormat || (exports.BundleFormat = {}));
exports.loadMessageBundle = loadMessageBundle;
function config(opts) {
if (opts) {
if (isString(opts.locale)) {
options.locale = opts.locale.toLowerCase();
options.language = options.locale;
resolvedLanguage = undefined;
resolvedBundles = Object.create(null);
}
if (opts.messageFormat !== undefined) {
options.messageFormat = opts.messageFormat;
}
if (opts.bundleFormat === BundleFormat.standalone && options.languagePackSupport === true) {
options.languagePackSupport = false;
}
}
isPseudo = options.locale === 'pseudo';
return loadMessageBundle;
}
exports.config = config;

Просмотреть файл

@ -1,7 +1,8 @@
#define RootLicenseFileName FileExists(RepoDir + '\LICENSE.rtf') ? 'LICENSE.rtf' : 'LICENSE.txt'
#define LocalizedLanguageFile(Language = "") \
DirExists(RepoDir + "\licenses") && Language != "" \
? ('; LicenseFile: "' + RepoDir + '\licenses\LICENSE-' + Language + '.txt"') \
: '; LicenseFile: "' + RepoDir + '\LICENSE.txt"'
: '; LicenseFile: "' + RepoDir + '\' + RootLicenseFileName + '"'
[Setup]
AppId={#AppId}
@ -56,6 +57,9 @@ Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl,{#RepoDir}\build\
Name: "korean"; MessagesFile: "{#RepoDir}\build\win32\i18n\Default.ko.isl,{#RepoDir}\build\win32\i18n\messages.ko.isl" {#LocalizedLanguageFile("kor")}
Name: "simplifiedChinese"; MessagesFile: "{#RepoDir}\build\win32\i18n\Default.zh-cn.isl,{#RepoDir}\build\win32\i18n\messages.zh-cn.isl" {#LocalizedLanguageFile("chs")}
Name: "traditionalChinese"; MessagesFile: "{#RepoDir}\build\win32\i18n\Default.zh-tw.isl,{#RepoDir}\build\win32\i18n\messages.zh-tw.isl" {#LocalizedLanguageFile("cht")}
Name: "brazilianPortuguese"; MessagesFile: "compiler:Languages\BrazilianPortuguese.isl,{#RepoDir}\build\win32\i18n\messages.pt-br.isl" {#LocalizedLanguageFile("ptb")}
Name: "hungarian"; MessagesFile: "compiler:Languages\Hungarian.isl,{#RepoDir}\build\win32\i18n\messages.hu.isl" {#LocalizedLanguageFile("hun")}
Name: "turkish"; MessagesFile: "compiler:Languages\Turkish.isl,{#RepoDir}\build\win32\i18n\messages.tr.isl" {#LocalizedLanguageFile("trk")}
[InstallDelete]
Type: filesandordirs; Name: "{app}\resources\app\out"; Check: IsNotUpdate

Просмотреть файл

@ -1804,10 +1804,10 @@ http-signature@~1.2.0:
jsprim "^1.2.2"
sshpk "^1.7.0"
iconv-lite@0.4.23:
version "0.4.23"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63"
integrity sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==
iconv-lite@0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.0.tgz#66a93b80df0bd05d2a43a7426296b7f91073f125"
integrity sha512-43ZpGYZ9QtuutX5l6WC1DSO8ane9N+Ct5qPLF2OV7vM9abM69gnAbVkh66ibaZd3aOGkoP1ZmringlKhLBkw2Q==
dependencies:
safer-buffer ">= 2.1.2 < 3"
@ -3523,10 +3523,10 @@ typescript@^3.0.1:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.3.tgz#c830f657f93f1ea846819e929092f5fe5983e977"
integrity sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==
typescript@^3.9.3:
version "3.9.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.3.tgz#d3ac8883a97c26139e42df5e93eeece33d610b8a"
integrity sha512-D/wqnB2xzNFIcoBG9FG8cXRDjiqSTbG2wd8DMZeQyJlP1vfTkIxH4GKveWaEBYySKIg+USu+E+EDIR47SqnaMQ==
typescript@^4.0.0-dev.20200615:
version "4.0.0-dev.20200615"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.0-dev.20200615.tgz#5c06a0d5f25a29a018767970c6531fbbed7240e3"
integrity sha512-OD7KRTLimUwW5E1xHsAqXNjw0O0Krk9CgRVFYkqANv4fZisaN1LJI06u30D5QiNnHBzm2nBSzZIAhjj4MUqaRA==
typical@^4.0.0:
version "4.0.0"

Просмотреть файл

@ -60,12 +60,12 @@
"git": {
"name": "electron",
"repositoryUrl": "https://github.com/electron/electron",
"commitHash": "8f502de1dc5b6df4218a900d0857de7a40301d98"
"commitHash": "bc8fc0d406d32e4c02f3ec9f161deaacbe4f5989"
}
},
"isOnlyProductionDependency": true,
"license": "MIT",
"version": "7.3.0"
"version": "7.3.1"
},
{
"component": {

Просмотреть файл

@ -3,4 +3,5 @@ src/**
tsconfig.json
out/**
extension.webpack.config.js
extension-browser.webpack.config.js
yarn.lock

Просмотреть файл

@ -0,0 +1,33 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
//@ts-check
'use strict';
const withDefaults = require('../shared.webpack.config');
const path = require('path');
const clientConfig = withDefaults({
target: 'webworker',
context: __dirname,
entry: {
extension: './src/configurationEditingMain.ts'
},
output: {
filename: 'configurationEditingMain.js'
},
performance: {
hints: false
},
resolve: {
alias: {
'vscode-nls': path.resolve(__dirname, '../../build/polyfills/vscode-nls.js')
}
}
});
clientConfig.module.rules[0].use.shift(); // remove nls loader
module.exports = clientConfig;

Просмотреть файл

@ -12,7 +12,10 @@ const withDefaults = require('../shared.webpack.config');
module.exports = withDefaults({
context: __dirname,
entry: {
extension: './src/extension.ts',
extension: './src/configurationEditingMain.ts',
},
output: {
filename: 'configurationEditingMain.js'
},
resolve: {
mainFields: ['module', 'main']

Просмотреть файл

@ -12,7 +12,8 @@
"onLanguage:json",
"onLanguage:jsonc"
],
"main": "./out/extension",
"main": "./out/configurationEditingMain",
"browser": "./dist/configurationEditingMain",
"scripts": {
"compile": "gulp compile-extension:configuration-editing",
"watch": "gulp watch-extension:configuration-editing"

Просмотреть файл

@ -45,6 +45,16 @@
"pattern": "^([a-z0-9A-Z][a-z0-9\\-A-Z]*)\\.([a-z0-9A-Z][a-z0-9\\-A-Z]*)$",
"errorMessage": "Expected format '${publisher}.${name}'. Example: 'vscode.csharp'."
}
},
"postAttachCommand": {
"type": [
"string",
"array"
],
"description": "A command to run after attaching to the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
}
}
}

Просмотреть файл

@ -68,9 +68,33 @@
"type": "string"
}
},
"postStartCommand": {
"type": [
"string",
"array"
],
"description": "A command to run after starting the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
},
"postAttachCommand": {
"type": [
"string",
"array"
],
"description": "A command to run after attaching to the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
},
"devPort": {
"type": "integer",
"description": "The port VS Code can use to connect to its backend."
},
"codespaces": {
"type": "object",
"description": "Codespaces-specific configuration."
}
}
},

Просмотреть файл

@ -30,7 +30,8 @@ export function createContext(): TestContext {
globalStoragePath: '',
logPath: '',
extensionUri: vscode.Uri.parse(''),
environmentVariableCollection: undefined as any
environmentVariableCollection: undefined as any,
extensionMode: undefined as any
}
};
}

Просмотреть файл

@ -16,6 +16,11 @@ import { languages, workspace, Disposable, TextDocument, Uri, Diagnostic, Range,
const product = JSON.parse(fs.readFileSync(path.join(env.appRoot, 'product.json'), { encoding: 'utf-8' }));
const allowedBadgeProviders: string[] = (product.extensionAllowedBadgeProviders || []).map((s: string) => s.toLowerCase());
const allowedBadgeProvidersRegex: RegExp[] = (product.extensionAllowedBadgeProvidersRegex || []).map((r: string) => new RegExp(r));
function isTrustedSVGSource(uri: Uri): boolean {
return allowedBadgeProviders.includes(uri.authority.toLowerCase()) || allowedBadgeProvidersRegex.some(r => r.test(uri.toString()));
}
const httpsRequired = localize('httpsRequired', "Images must use the HTTPS protocol.");
const svgsNotValid = localize('svgsNotValid', "SVGs are not a valid image source.");
@ -321,7 +326,7 @@ export class ExtensionLinter {
diagnostics.push(new Diagnostic(range, message, DiagnosticSeverity.Warning));
}
if (endsWith(uri.path.toLowerCase(), '.svg') && allowedBadgeProviders.indexOf(uri.authority.toLowerCase()) === -1) {
if (endsWith(uri.path.toLowerCase(), '.svg') && !isTrustedSVGSource(uri)) {
const range = new Range(document.positionAt(begin), document.positionAt(end));
diagnostics.push(new Diagnostic(range, svgsNotValid, DiagnosticSeverity.Warning));
}

Просмотреть файл

@ -14,7 +14,8 @@
"Other"
],
"activationEvents": [
"*"
"*",
"onFileSystem:git"
],
"main": "./out/main",
"icon": "resources/icons/git.png",
@ -1870,14 +1871,14 @@
{
"view": "explorer",
"contents": "%view.workbench.cloneRepository%",
"when": "config.git.enabled"
"when": "config.git.enabled && git.state == initialized"
}
]
},
"dependencies": {
"byline": "^5.0.0",
"file-type": "^7.2.0",
"iconv-lite": "^0.4.24",
"iconv-lite": "0.6.0",
"jschardet": "2.1.1",
"vscode-extension-telemetry": "0.1.1",
"vscode-nls": "^4.0.0",

2
extensions/git/src/api/git.d.ts поставляемый
Просмотреть файл

@ -134,6 +134,8 @@ export interface CommitOptions {
export interface BranchQuery {
readonly remote?: boolean;
readonly pattern?: string;
readonly count?: number;
readonly contains?: string;
}

Просмотреть файл

@ -133,6 +133,8 @@ export class GitFileSystemProvider implements FileSystemProvider {
}
async stat(uri: Uri): Promise<FileStat> {
await this.model.isInitialized;
const { submoduleOf, path, ref } = fromGitUri(uri);
const repository = submoduleOf ? this.model.getRepository(submoduleOf) : this.model.getRepository(uri);
if (!repository) {
@ -158,6 +160,8 @@ export class GitFileSystemProvider implements FileSystemProvider {
}
async readFile(uri: Uri): Promise<Uint8Array> {
await this.model.isInitialized;
const { path, ref, submoduleOf } = fromGitUri(uri);
if (submoduleOf) {

Просмотреть файл

@ -422,7 +422,7 @@ export class Git {
const result = await this.exec(repositoryPath, ['rev-parse', '--show-toplevel']);
// Keep trailing spaces which are part of the directory name
const repoPath = path.normalize(result.stdout.trimLeft().replace(/(\r\n|\r|\n)+$/, ''));
const repoPath = path.normalize(result.stdout.trimLeft().replace(/[\r\n]+$/, ''));
if (isWindows) {
// On Git 2.25+ if you call `rev-parse --show-toplevel` on a mapped drive, instead of getting the mapped drive path back, you get the UNC path for the mapped drive.
@ -905,7 +905,7 @@ export class Repository {
}
async buffer(object: string): Promise<Buffer> {
const child = this.stream(['show', object]);
const child = this.stream(['show', '--textconv', object]);
if (!child.stdout) {
return Promise.reject<Buffer>('Can\'t open file from git');
@ -978,7 +978,7 @@ export class Repository {
}
async detectObjectType(object: string): Promise<{ mimetype: string, encoding?: string }> {
const child = await this.stream(['show', object]);
const child = await this.stream(['show', '--textconv', object]);
const buffer = await readBytes(child.stdout!, 4100);
try {
@ -1791,13 +1791,23 @@ export class Repository {
.map(([ref]) => ({ name: ref, type: RefType.Head } as Branch));
}
async getRefs(opts?: { sort?: 'alphabetically' | 'committerdate', contains?: string }): Promise<Ref[]> {
const args = ['for-each-ref', '--format', '%(refname) %(objectname)'];
async getRefs(opts?: { sort?: 'alphabetically' | 'committerdate', contains?: string, pattern?: string, count?: number }): Promise<Ref[]> {
const args = ['for-each-ref'];
if (opts?.count) {
args.push(`--count=${opts.count}`);
}
if (opts && opts.sort && opts.sort !== 'alphabetically') {
args.push('--sort', `-${opts.sort}`);
}
args.push('--format', '%(refname) %(objectname)');
if (opts?.pattern) {
args.push(opts.pattern);
}
if (opts?.contains) {
args.push('--contains', opts.contains);
}
@ -1920,7 +1930,7 @@ export class Repository {
}
async getBranches(query: BranchQuery): Promise<Ref[]> {
const refs = await this.getRefs({ contains: query.contains });
const refs = await this.getRefs({ contains: query.contains, pattern: query.pattern ? `refs/${query.pattern}` : undefined, count: query.count });
return refs.filter(value => (value.type !== RefType.Tag) && (query.remote || !value.remote));
}

Просмотреть файл

@ -6,7 +6,7 @@
import { workspace, WorkspaceFoldersChangeEvent, Uri, window, Event, EventEmitter, QuickPickItem, Disposable, SourceControl, SourceControlResourceGroup, TextEditor, Memento, OutputChannel, commands } from 'vscode';
import { Repository, RepositoryState } from './repository';
import { memoize, sequentialize, debounce } from './decorators';
import { dispose, anyEvent, filterEvent, isDescendant, firstIndex, pathEquals, toDisposable } from './util';
import { dispose, anyEvent, filterEvent, isDescendant, firstIndex, pathEquals, toDisposable, eventToPromise } from './util';
import { Git } from './git';
import * as path from 'path';
import * as fs from 'fs';
@ -77,6 +77,15 @@ export class Model implements IRemoteSourceProviderRegistry {
commands.executeCommand('setContext', 'git.state', state);
}
@memoize
get isInitialized(): Promise<void> {
if (this._state === 'initialized') {
return Promise.resolve();
}
return eventToPromise(filterEvent(this.onDidChangeState, s => s === 'initialized')) as Promise<any>;
}
private remoteSourceProviders = new Set<RemoteSourceProvider>();
private _onDidAddRemoteSourceProvider = new EventEmitter<RemoteSourceProvider>();
@ -148,6 +157,13 @@ export class Model implements IRemoteSourceProviderRegistry {
}
private onPossibleGitRepositoryChange(uri: Uri): void {
const config = workspace.getConfiguration('git');
const autoRepositoryDetection = config.get<boolean | 'subFolders' | 'openEditors'>('autoRepositoryDetection');
if (autoRepositoryDetection === false) {
return;
}
this.eventuallyScanPossibleGitRepository(uri.fsPath.replace(/\.git.*$/, ''));
}

Просмотреть файл

@ -19,7 +19,7 @@ export function applyLineChanges(original: TextDocument, modified: TextDocument,
// if this is a deletion at the very end of the document,then we need to account
// for a newline at the end of the last line which may have been deleted
// https://github.com/Microsoft/vscode/issues/59670
if (isDeletion && diff.originalStartLineNumber === original.lineCount) {
if (isDeletion && diff.originalEndLineNumber === original.lineCount) {
endLine -= 1;
endCharacter = original.lineAt(endLine).range.end.character;
}

Просмотреть файл

@ -425,10 +425,10 @@ https-proxy-agent@^2.2.1:
agent-base "^4.3.0"
debug "^3.1.0"
iconv-lite@^0.4.24:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
iconv-lite@0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.0.tgz#66a93b80df0bd05d2a43a7426296b7f91073f125"
integrity sha512-43ZpGYZ9QtuutX5l6WC1DSO8ane9N+Ct5qPLF2OV7vM9abM69gnAbVkh66ibaZd3aOGkoP1ZmringlKhLBkw2Q==
dependencies:
safer-buffer ">= 2.1.2 < 3"

Просмотреть файл

@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
//@ts-check
'use strict';
const path = require('path');
const withDefaults = require('../shared.webpack.config');
module.exports = withDefaults({
context: __dirname,
target: 'webworker',
node: false,
entry: {
extension: './src/extension.ts',
},
externals: {
'keytar': 'commonjs keytar',
},
// TODO@eamodio Deal with nls properly for the browser
// Specify module here, so we can stop the vscode-nls-dev loader from overwriting nls calls
module: {
rules: [{
test: /\.ts$/,
exclude: /node_modules/,
use: [{
// configure TypeScript loader:
// * enable sources maps for end-to-end source maps
loader: 'ts-loader',
options: {
compilerOptions: {
'sourceMap': true,
}
}
}]
}]
},
resolve: {
alias: {
'node-fetch': path.resolve(__dirname, 'node_modules/node-fetch/browser.js'),
'vscode-extension-telemetry': path.resolve(__dirname, '../../build/polyfills/vscode-extension-telemetry.js'),
'vscode-nls': path.resolve(__dirname, '../../build/polyfills/vscode-nls.js'),
'uuid': path.resolve(__dirname, 'node_modules/uuid/dist/esm-browser/index.js')
},
}
});

Просмотреть файл

@ -32,20 +32,25 @@
},
"aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217",
"main": "./out/extension.js",
"browser": "./dist/extension.js",
"scripts": {
"vscode:prepublish": "npm run compile",
"compile": "gulp compile-extension:github-authentication",
"watch": "gulp watch-extension:github-authentication"
"compile-web": "npx webpack-cli --config extension-browser.webpack.config --mode none",
"watch": "gulp watch-extension:github-authentication",
"watch-web": "npx webpack-cli --config extension-browser.webpack.config --mode none --watch --info-verbosity verbose",
"vscode:prepublish": "npm run compile"
},
"dependencies": {
"uuid": "^3.3.3",
"node-fetch": "2.6.0",
"uuid": "8.1.0",
"vscode-extension-telemetry": "0.1.1",
"vscode-nls": "^4.1.2"
},
"devDependencies": {
"@types/keytar": "^4.4.2",
"@types/node": "^10.12.21",
"@types/uuid": "^3.4.6",
"@types/node-fetch": "2.5.7",
"@types/uuid": "8.0.0",
"typescript": "^3.7.5"
}
}

Просмотреть файл

@ -5,7 +5,7 @@
// keytar depends on a native module shipped in vscode, so this is
// how we load it
import * as keytarType from 'keytar';
import type * as keytarType from 'keytar';
import * as vscode from 'vscode';
import Logger from './logger';
import * as nls from 'vscode-nls';

Просмотреть файл

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import * as uuid from 'uuid';
import { v4 as uuid } from 'uuid';
import { keychain } from './common/keychain';
import { GitHubServer, NETWORK_ERROR } from './githubServer';
import Logger from './common/logger';

Просмотреть файл

@ -3,10 +3,10 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as https from 'https';
import * as nls from 'vscode-nls';
import * as vscode from 'vscode';
import * as uuid from 'uuid';
import fetch from 'node-fetch';
import { v4 as uuid } from 'uuid';
import { PromiseAdapter, promiseFromEvent } from './common/utils';
import Logger from './common/logger';
@ -23,6 +23,8 @@ class UriEventHandler extends vscode.EventEmitter<vscode.Uri> implements vscode.
export const uriHandler = new UriEventHandler;
const onDidManuallyProvideToken = new vscode.EventEmitter<string>();
const exchangeCodeForToken: (state: string) => PromiseAdapter<vscode.Uri, string> =
(state) => async (uri, resolve, reject) => {
Logger.info('Exchanging code for token...');
@ -34,33 +36,24 @@ const exchangeCodeForToken: (state: string) => PromiseAdapter<vscode.Uri, string
return;
}
const post = https.request({
host: AUTH_RELAY_SERVER,
path: `/token?code=${code}&state=${state}`,
method: 'POST',
headers: {
Accept: 'application/json'
}
}, result => {
const buffer: Buffer[] = [];
result.on('data', (chunk: Buffer) => {
buffer.push(chunk);
});
result.on('end', () => {
if (result.statusCode === 200) {
const json = JSON.parse(Buffer.concat(buffer).toString());
Logger.info('Token exchange success!');
resolve(json.access_token);
} else {
reject(new Error(result.statusMessage));
try {
const result = await fetch(`https://${AUTH_RELAY_SERVER}/token?code=${code}&state=${state}`, {
method: 'POST',
headers: {
Accept: 'application/json'
}
});
});
post.end();
post.on('error', err => {
reject(err);
});
if (result.ok) {
const json = await result.json();
Logger.info('Token exchange success!');
resolve(json.access_token);
} else {
reject(result.statusText);
}
} catch (ex) {
reject(ex);
}
};
function parseQuery(uri: vscode.Uri) {
@ -80,11 +73,14 @@ export class GitHubServer {
const state = uuid();
const callbackUri = await vscode.env.asExternalUri(vscode.Uri.parse(`${vscode.env.uriScheme}://vscode.github-authentication/did-authenticate`));
const uri = vscode.Uri.parse(`https://${AUTH_RELAY_SERVER}/authorize/?callbackUri=${encodeURIComponent(callbackUri.toString())}&scope=${scopes}&state=${state}&responseType=code`);
const uri = vscode.Uri.parse(`https://${AUTH_RELAY_SERVER}/authorize/?callbackUri=${encodeURIComponent(callbackUri.toString())}&scope=${scopes}&state=${state}&responseType=code&authServer=https://github.com`);
vscode.env.openExternal(uri);
await vscode.env.openExternal(uri);
return promiseFromEvent(uriHandler.event, exchangeCodeForToken(state)).finally(() => {
return Promise.race([
promiseFromEvent(uriHandler.event, exchangeCodeForToken(state)),
promiseFromEvent<string, string>(onDidManuallyProvideToken.event)
]).finally(() => {
this.updateStatusBarItem(false);
});
}
@ -111,44 +107,33 @@ export class GitHubServer {
if (!uri.scheme || uri.scheme === 'file') { throw new Error; }
uriHandler.handleUri(uri);
} catch (e) {
Logger.error(e);
vscode.window.showErrorMessage(localize('unexpectedInput', "The input did not matched the expected format"));
// If it doesn't look like a URI, treat it as a token.
Logger.info('Treating input as token');
onDidManuallyProvideToken.fire(uriOrToken);
}
}
public async getUserInfo(token: string): Promise<{ id: string, accountName: string }> {
return new Promise((resolve, reject) => {
Logger.info('Getting account info...');
const post = https.request({
host: 'api.github.com',
path: `/user`,
method: 'GET',
try {
Logger.info('Getting user info...');
const result = await fetch('https://api.github.com/user', {
headers: {
Authorization: `token ${token}`,
'User-Agent': 'Visual-Studio-Code'
}
}, result => {
const buffer: Buffer[] = [];
result.on('data', (chunk: Buffer) => {
buffer.push(chunk);
});
result.on('end', () => {
if (result.statusCode === 200) {
const json = JSON.parse(Buffer.concat(buffer).toString());
Logger.info('Got account info!');
resolve({ id: json.id, accountName: json.login });
} else {
Logger.error(`Getting account info failed: ${result.statusMessage}`);
reject(new Error(result.statusMessage));
}
});
});
post.end();
post.on('error', err => {
Logger.error(err.message);
reject(new Error(NETWORK_ERROR));
});
});
if (result.ok) {
const json = await result.json();
Logger.info('Got account info!');
return { id: json.id, accountName: json.login };
} else {
Logger.error(`Getting account info failed: ${result.statusText}`);
throw new Error(result.statusText);
}
} catch (ex) {
Logger.error(ex.message);
throw new Error(NETWORK_ERROR);
}
}
}

Просмотреть файл

@ -9,15 +9,28 @@
dependencies:
keytar "*"
"@types/node@^10.12.21":
version "10.17.14"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.14.tgz#b6c60ebf2fb5e4229fdd751ff9ddfae0f5f31541"
integrity sha512-G0UmX5uKEmW+ZAhmZ6PLTQ5eu/VPaT+d/tdLd5IFsKRPcbe6lPxocBtcYBFSaLaCW8O60AX90e91Nsp8lVHCNw==
"@types/node-fetch@2.5.7":
version "2.5.7"
resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.7.tgz#20a2afffa882ab04d44ca786449a276f9f6bbf3c"
integrity sha512-o2WVNf5UhWRkxlf6eq+jMZDu7kjgpgJfl4xVNlvryc95O/6F2ld8ztKX+qu+Rjyet93WAWm5LjeX9H5FGkODvw==
dependencies:
"@types/node" "*"
form-data "^3.0.0"
"@types/uuid@^3.4.6":
version "3.4.7"
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-3.4.7.tgz#51d42247473bc00e38cc8dfaf70d936842a36c03"
integrity sha512-C2j2FWgQkF1ru12SjZJyMaTPxs/f6n90+5G5qNakBxKXjTBc/YTSelHh4Pz1HUDwxFXD9WvpQhOGCDC+/Y4mIQ==
"@types/node@*":
version "14.0.5"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.5.tgz#3d03acd3b3414cf67faf999aed11682ed121f22b"
integrity sha512-90hiq6/VqtQgX8Sp0EzeIsv3r+ellbGj4URKj5j30tLlZvRUpnAe9YbYnjl3pJM93GyXU0tghHhvXHq+5rnCKA==
"@types/node@^10.12.21":
version "10.17.24"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.24.tgz#c57511e3a19c4b5e9692bb2995c40a3a52167944"
integrity sha512-5SCfvCxV74kzR3uWgTYiGxrd69TbT1I6+cMx1A5kEly/IVveJBimtAMlXiEyVFn5DvUFewQWxOOiJhlxeQwxgA==
"@types/uuid@8.0.0":
version "8.0.0"
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.0.0.tgz#165aae4819ad2174a17476dbe66feebd549556c0"
integrity sha512-xSQfNcvOiE5f9dyd4Kzxbof1aTrLobL278pGLKOZI6esGfZ7ts9Ka16CzIN6Y8hFHE1C7jIBZokULhK1bOgjRw==
ansi-regex@^2.0.0:
version "2.1.1"
@ -51,23 +64,50 @@ are-we-there-yet@~1.1.2:
delegates "^1.0.0"
readable-stream "^2.0.6"
bl@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/bl/-/bl-3.0.0.tgz#3611ec00579fd18561754360b21e9f784500ff88"
integrity sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A==
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
base64-js@^1.0.2:
version "1.3.1"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1"
integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==
bl@^4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/bl/-/bl-4.0.2.tgz#52b71e9088515d0606d9dd9cc7aa48dc1f98e73a"
integrity sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ==
dependencies:
readable-stream "^3.0.1"
buffer "^5.5.0"
inherits "^2.0.4"
readable-stream "^3.4.0"
buffer@^5.5.0:
version "5.6.0"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786"
integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==
dependencies:
base64-js "^1.0.2"
ieee754 "^1.1.4"
chownr@^1.1.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142"
integrity sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==
version "1.1.4"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
code-point-at@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
combined-stream@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
dependencies:
delayed-stream "~1.0.0"
console-control-strings@^1.0.0, console-control-strings@~1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
@ -90,6 +130,11 @@ deep-extend@^0.6.0:
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
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=
delegates@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
@ -124,6 +169,15 @@ expand-template@^2.0.3:
resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c"
integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==
form-data@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682"
integrity sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.8"
mime-types "^2.1.12"
fs-constants@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
@ -153,7 +207,12 @@ has-unicode@^2.0.0:
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=
inherits@^2.0.3, inherits@~2.0.3:
ieee754@^1.1.4:
version "1.1.13"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84"
integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==
inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@ -181,52 +240,69 @@ isarray@~1.0.0:
integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
keytar@*:
version "5.1.0"
resolved "https://registry.yarnpkg.com/keytar/-/keytar-5.1.0.tgz#d572ed9250ff2b4c8d729621397e00b17bfa5581"
integrity sha512-SptCrRDqLbTeOMB2Z9UmVOS+OKguIrMft+EUaCB8xJPiFMjy6Jnmjgv/LA0rg1ENgLelzwSsC5PSQXF0uoqNDQ==
version "6.0.1"
resolved "https://registry.yarnpkg.com/keytar/-/keytar-6.0.1.tgz#996961abdebf300b2d34bb2eab6e42a8096b1ed8"
integrity sha512-1Ihpf2tdM3sLwGMkYHXYhVC/hx5BDR7CWFL4IrBA3IDZo0xHhS2nM+tU9Y+u/U7okNfbVkwmKsieLkcWRMh93g==
dependencies:
nan "2.14.0"
prebuild-install "5.3.3"
node-addon-api "^3.0.0"
prebuild-install "5.3.4"
mime-db@1.44.0:
version "1.44.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92"
integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==
mime-types@^2.1.12:
version "2.1.27"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f"
integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==
dependencies:
mime-db "1.44.0"
mimic-response@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.0.0.tgz#996a51c60adf12cb8a87d7fb8ef24c2f3d5ebb46"
integrity sha512-8ilDoEapqA4uQ3TwS0jakGONKXVJqpy+RpM+3b7pLdOjghCrEiGp9SRkFbUHAmZW9vdnrENWHjaweIoTIJExSQ==
version "2.1.0"
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43"
integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==
minimist@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
minimist@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=
mkdirp-classic@^0.5.2:
version "0.5.3"
resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"
integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==
mkdirp@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
version "0.5.5"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
dependencies:
minimist "0.0.8"
nan@2.14.0:
version "2.14.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
minimist "^1.2.5"
napi-build-utils@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.1.tgz#1381a0f92c39d66bf19852e7873432fc2123e508"
integrity sha512-boQj1WFgQH3v4clhu3mTNfP+vOBxorDlE8EKiMjUlLG3C4qAESnn9AxIOkFgTR2c9LtzNjPrjS60cT27ZKBhaA==
version "1.0.2"
resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806"
integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==
node-abi@^2.7.0:
version "2.14.0"
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.14.0.tgz#24650e24e8ffad2b61352519263f0cf4e2ddbfe9"
integrity sha512-y54KGgEOHnRHlGQi7E5UiryRkH8bmksmQLj/9iLAjoje743YS+KaKB/sDYXgqtT0J16JT3c3AYJZNI98aU/kYg==
version "2.17.0"
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.17.0.tgz#f167c92780497ff01eeaf473fcf8138e0fcc87fa"
integrity sha512-dFRAA0ACk/aBo0TIXQMEWMLUTyWYYT8OBYIzLmEUrQTElGRjxDCvyBZIsDL0QA7QCaj9PrawhOmTEdsuLY4uOQ==
dependencies:
semver "^5.4.1"
node-addon-api@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.0.0.tgz#812446a1001a54f71663bed188314bba07e09247"
integrity sha512-sSHCgWfJ+Lui/u+0msF3oyCgvdkhxDbkCS6Q8uiJquzOimkJBvX6hl5aSSA7DR1XbMpdM8r7phjcF63sF4rkKg==
node-fetch@2.6.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd"
integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==
noop-logger@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/noop-logger/-/noop-logger-0.1.1.tgz#94a2b1633c4f1317553007d8966fd0e841b6a4c2"
@ -259,15 +335,15 @@ once@^1.3.1, once@^1.4.0:
dependencies:
wrappy "1"
prebuild-install@5.3.3:
version "5.3.3"
resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-5.3.3.tgz#ef4052baac60d465f5ba6bf003c9c1de79b9da8e"
integrity sha512-GV+nsUXuPW2p8Zy7SarF/2W/oiK8bFQgJcncoJ0d7kRpekEA0ftChjfEaF9/Y+QJEc/wFR7RAEa8lYByuUIe2g==
prebuild-install@5.3.4:
version "5.3.4"
resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-5.3.4.tgz#6982d10084269d364c1856550b7d090ea31fa293"
integrity sha512-AkKN+pf4fSEihjapLEEj8n85YIw/tN6BQqkhzbDc0RvEZGdkpJBGMUYx66AAMcPG2KzmPQS7Cm16an4HVBRRMA==
dependencies:
detect-libc "^1.0.3"
expand-template "^2.0.3"
github-from-package "0.0.0"
minimist "^1.2.0"
minimist "^1.2.3"
mkdirp "^0.5.1"
napi-build-utils "^1.0.1"
node-abi "^2.7.0"
@ -316,19 +392,19 @@ readable-stream@^2.0.6:
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
readable-stream@^3.0.1, readable-stream@^3.1.1:
version "3.5.0"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.5.0.tgz#465d70e6d1087f6162d079cd0b5db7fbebfd1606"
integrity sha512-gSz026xs2LfxBPudDuI41V1lka8cxg64E66SGe78zJlsUofOg/yqwezdIcdfwik6B4h8LFmWPA9ef9X3FiNFLA==
readable-stream@^3.1.1, readable-stream@^3.4.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
dependencies:
inherits "^2.0.3"
string_decoder "^1.1.1"
util-deprecate "^1.0.1"
safe-buffer@^5.0.1, safe-buffer@~5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519"
integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==
version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.2"
@ -346,9 +422,9 @@ set-blocking@~2.0.0:
integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
signal-exit@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=
version "3.0.3"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
simple-concat@^1.0.0:
version "1.0.0"
@ -415,21 +491,21 @@ strip-json-comments@~2.0.1:
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
tar-fs@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.0.0.tgz#677700fc0c8b337a78bee3623fdc235f21d7afad"
integrity sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA==
version "2.1.0"
resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.0.tgz#d1cdd121ab465ee0eb9ccde2d35049d3f3daf0d5"
integrity sha512-9uW5iDvrIMCVpvasdFHW0wJPez0K4JnMZtsuIeDI7HyMGJNxmDZDOCQROr7lXyS+iL/QMpj07qcjGYTSdRFXUg==
dependencies:
chownr "^1.1.1"
mkdirp "^0.5.1"
mkdirp-classic "^0.5.2"
pump "^3.0.0"
tar-stream "^2.0.0"
tar-stream@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.0.tgz#d1aaa3661f05b38b5acc9b7020efdca5179a2cc3"
integrity sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw==
version "2.1.2"
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.2.tgz#6d5ef1a7e5783a95ff70b69b97455a5968dc1325"
integrity sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==
dependencies:
bl "^3.0.0"
bl "^4.0.1"
end-of-stream "^1.4.1"
fs-constants "^1.0.0"
inherits "^2.0.3"
@ -443,19 +519,19 @@ tunnel-agent@^0.6.0:
safe-buffer "^5.0.1"
typescript@^3.7.5:
version "3.7.5"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.5.tgz#0692e21f65fd4108b9330238aac11dd2e177a1ae"
integrity sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==
version "3.9.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.3.tgz#d3ac8883a97c26139e42df5e93eeece33d610b8a"
integrity sha512-D/wqnB2xzNFIcoBG9FG8cXRDjiqSTbG2wd8DMZeQyJlP1vfTkIxH4GKveWaEBYySKIg+USu+E+EDIR47SqnaMQ==
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"
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
uuid@^3.3.3:
version "3.4.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
uuid@8.1.0:
version "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.1:
version "0.1.1"

3
extensions/github-browser/.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,3 @@
dist
out
node_modules

Просмотреть файл

@ -0,0 +1,11 @@
.vscode/**
build/**
dist/**
out/**
src/**
typings/**
.gitignore
extension-browser.webpack.config.js
extension.webpack.config.js
tsconfig.json
yarn.lock

Просмотреть файл

@ -0,0 +1,7 @@
# GitHub FileSystem for Visual Studio Code
**Notice:** This extension is bundled with Visual Studio Code. It can be disabled but not uninstalled.
## Features
This extension provides remote GitHub repository features for VS Code.

Просмотреть файл

@ -0,0 +1,24 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
//@ts-check
'use strict';
const path = require('path');
const withDefaults = require('../shared.webpack.config');
module.exports = withDefaults({
context: __dirname,
target: 'webworker',
node: false,
entry: {
extension: './src/extension.ts',
},
resolve: {
alias: {
'node-fetch': path.resolve(__dirname, 'node_modules/node-fetch/browser.js'),
},
}
});

Просмотреть файл

@ -0,0 +1,17 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
//@ts-check
'use strict';
const withDefaults = require('../shared.webpack.config');
module.exports = withDefaults({
context: __dirname,
entry: {
extension: './src/extension.ts'
}
});

Просмотреть файл

@ -0,0 +1,60 @@
{
"name": "github-browser",
"displayName": "%displayName%",
"description": "%description%",
"publisher": "vscode",
"version": "0.0.1",
"engines": {
"vscode": "^1.45.0"
},
"enableProposedApi": true,
"private": true,
"categories": [
"Other"
],
"activationEvents": [
"onFileSystem:github"
],
"browser": "./dist/extension.js",
"main": "./out/extension.js",
"contributes": {
"resourceLabelFormatters": [
{
"scheme": "github",
"authority": "HEAD",
"formatting": {
"label": "github.com${path}",
"separator": "/",
"workspaceSuffix": "GitHub"
}
},
{
"scheme": "github",
"authority": "*",
"formatting": {
"label": "github.com${path} (${authority})",
"separator": "/",
"workspaceSuffix": "GitHub"
}
}
]
},
"scripts": {
"compile": "gulp compile-extension:github-browser",
"compile-web": "npx webpack-cli --config extension-browser.webpack.config --mode none",
"watch": "gulp watch-extension:github-browser",
"watch-web": "npx webpack-cli --config extension-browser.webpack.config --mode none --watch --info-verbosity verbose",
"vscode:prepublish": "npm run compile"
},
"dependencies": {
"@octokit/graphql": "4.5.0",
"@octokit/rest": "17.11.0",
"fuzzysort": "1.1.4",
"node-fetch": "2.6.0"
},
"devDependencies": {
"@types/node-fetch": "2.5.7",
"webpack": "4.43.0",
"webpack-cli": "3.3.11"
}
}

Просмотреть файл

@ -0,0 +1,4 @@
{
"displayName": "GitHub Browser",
"description": "Remotely browse a GitHub repository"
}

Просмотреть файл

@ -0,0 +1,11 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { GitHubFS } from './githubfs';
export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(new GitHubFS());
}

Просмотреть файл

@ -0,0 +1,496 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import {
authentication,
AuthenticationSession2,
CancellationToken,
Disposable,
Event,
EventEmitter,
FileChangeEvent,
FileSearchOptions,
FileSearchProvider,
FileSearchQuery,
FileStat,
FileSystemError,
FileSystemProvider,
FileType,
Progress,
Range,
TextSearchComplete,
TextSearchOptions,
TextSearchProvider,
TextSearchQuery,
TextSearchResult,
Uri,
workspace,
} from 'vscode';
import { Octokit } from '@octokit/rest';
import { graphql } from '@octokit/graphql/';
import * as fuzzySort from 'fuzzysort';
import fetch from 'node-fetch';
import { Iterables } from './iterables';
const emptyDisposable = { dispose: () => { /* noop */ } };
const replaceBackslashRegex = /(\/|\\)/g;
const textEncoder = new TextEncoder();
interface Fuzzysort extends Fuzzysort.Fuzzysort {
prepareSlow(target: string): Fuzzysort.Prepared;
cleanup(): void;
}
export class GitHubFS implements FileSystemProvider, FileSearchProvider, TextSearchProvider, Disposable {
static scheme = 'github';
private _onDidChangeFile = new EventEmitter<FileChangeEvent[]>();
get onDidChangeFile(): Event<FileChangeEvent[]> {
return this._onDidChangeFile.event;
}
private readonly disposable: Disposable;
private fsCache = new Map<string, any>();
constructor() {
this.disposable = Disposable.from(
workspace.registerFileSystemProvider(GitHubFS.scheme, this, {
isCaseSensitive: true,
isReadonly: true,
}),
workspace.registerFileSearchProvider(GitHubFS.scheme, this),
workspace.registerTextSearchProvider(GitHubFS.scheme, this),
);
}
dispose() {
this.disposable?.dispose();
}
private _github: Promise<GitHubApi | undefined> | undefined;
get github(): Promise<GitHubApi | undefined> {
if (this._github === undefined) {
this._github = this.getGitHubApi();
}
return this._github;
}
private async getGitHubApi(): Promise<GitHubApi | undefined> {
try {
const session = await authentication.getSession('github', ['repo'], { createIfNone: true });
return new GitHubApi(session);
} catch (ex) {
this._github = undefined;
throw ex;
}
}
//#region FileSystemProvider
watch(): Disposable {
return emptyDisposable;
}
async stat(uri: Uri): Promise<FileStat> {
if (uri.path === '' || uri.path.lastIndexOf('/') === 0) {
return { type: FileType.Directory, size: 0, ctime: 0, mtime: 0 };
}
const data = await this.fsQuery<{
__typename: string;
byteSize: number | undefined;
}>(
uri,
`__typename
...on Blob {
byteSize
}`,
this.fsCache,
);
return {
type: typenameToFileType(data?.__typename),
size: data?.byteSize ?? 0,
ctime: 0,
mtime: 0,
};
}
async readDirectory(uri: Uri): Promise<[string, FileType][]> {
const data = await this.fsQuery<{
entries: { name: string; type: string }[];
}>(
uri,
`... on Tree {
entries {
name
type
}
}`,
this.fsCache,
);
return (data?.entries ?? []).map<[string, FileType]>(e => [
e.name,
typenameToFileType(e.type),
]);
}
createDirectory(): void | Thenable<void> {
throw FileSystemError.NoPermissions;
}
async readFile(uri: Uri): Promise<Uint8Array> {
const data = await this.fsQuery<{
oid: string;
isBinary: boolean;
text: string;
}>(
uri,
`... on Blob {
oid,
isBinary,
text
}`,
);
if (data?.isBinary) {
const { owner, repo, path } = fromGitHubUri(uri);
// e.g. https://raw.githubusercontent.com/eamodio/vscode-gitlens/HEAD/images/gitlens-icon.png
const downloadUri = uri.with({
scheme: 'https',
authority: 'raw.githubusercontent.com',
path: `/${owner}/${repo}/HEAD/${path}`,
});
return downloadBinary(downloadUri);
}
return textEncoder.encode(data?.text ?? '');
}
writeFile(): void | Thenable<void> {
throw FileSystemError.NoPermissions;
}
delete(): void | Thenable<void> {
throw FileSystemError.NoPermissions;
}
rename(): void | Thenable<void> {
throw FileSystemError.NoPermissions;
}
copy?(): void | Thenable<void> {
throw FileSystemError.NoPermissions;
}
//#endregion
//#region FileSearchProvider
private fileSearchCache = new Map<string, Fuzzysort.Prepared[]>();
async provideFileSearchResults(
query: FileSearchQuery,
options: FileSearchOptions,
token: CancellationToken,
): Promise<Uri[]> {
let searchable = this.fileSearchCache.get(options.folder.toString(true));
if (searchable === undefined) {
const matches = await (await this.github)?.filesQuery(options.folder);
if (matches === undefined || token.isCancellationRequested) { return []; }
searchable = [...Iterables.map(matches, m => (fuzzySort as Fuzzysort).prepareSlow(m))];
this.fileSearchCache.set(options.folder.toString(true), searchable);
}
if (options.maxResults === undefined || options.maxResults === 0 || options.maxResults >= searchable.length) {
const results = searchable.map(m => Uri.joinPath(options.folder, m.target));
return results;
}
const results = fuzzySort
.go(query.pattern.replace(replaceBackslashRegex, '/'), searchable, {
allowTypo: true,
limit: options.maxResults,
})
.map(m => Uri.joinPath(options.folder, m.target));
(fuzzySort as Fuzzysort).cleanup();
return results;
}
//#endregion
//#region TextSearchProvider
async provideTextSearchResults(
query: TextSearchQuery,
options: TextSearchOptions,
progress: Progress<TextSearchResult>,
token: CancellationToken,
): Promise<TextSearchComplete> {
const results = await (await this.github)?.searchQuery(
query.pattern,
options.folder,
{ maxResults: options.maxResults, context: { before: options.beforeContext, after: options.afterContext } },
token,
);
if (results === undefined) { return { limitHit: true }; }
let uri;
for (const m of results.matches) {
uri = Uri.joinPath(options.folder, m.path);
progress.report({
uri: uri,
ranges: m.ranges,
preview: {
text: m.preview,
matches: m.matches,
},
});
}
return { limitHit: false };
}
//#endregion
private async fsQuery<T>(uri: Uri, query: string, cache?: Map<string, any>): Promise<T | undefined> {
const key = `${uri.toString()}:${getHashCode(query)}`;
let data = cache?.get(key);
if (data !== undefined) { return data as T; }
data = await (await this.github)?.fsQuery<T>(uri, query);
cache?.set(key, data);
return data;
}
}
async function downloadBinary(uri: Uri) {
const resp = await fetch(uri.toString());
const array = new Uint8Array(await resp.arrayBuffer());
return array;
}
function typenameToFileType(typename: string | undefined | null) {
if (typename) {
typename = typename.toLocaleLowerCase();
}
switch (typename) {
case 'blob':
return FileType.File;
case 'tree':
return FileType.Directory;
default:
return FileType.Unknown;
}
}
type RepoInfo = { owner: string; repo: string; path: string | undefined; ref?: string };
function fromGitHubUri(uri: Uri): RepoInfo {
const [, owner, repo, ...rest] = uri.path.split('/');
let ref;
if (uri.authority) {
ref = uri.authority;
}
return { owner: owner, repo: repo, path: rest.join('/'), ref: ref };
}
function getHashCode(s: string): number {
let hash = 0;
if (s.length === 0) {
return hash;
}
let char;
const len = s.length;
for (let i = 0; i < len; i++) {
char = s.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash |= 0; // Convert to 32bit integer
}
return hash;
}
interface SearchQueryMatch {
path: string;
ranges: Range[];
preview: string;
matches: Range[];
}
interface SearchQueryResults {
matches: SearchQueryMatch[];
limitHit: boolean;
}
class GitHubApi {
constructor(private readonly session: AuthenticationSession2) { }
private _graphql: typeof graphql | undefined;
private get graphql() {
if (this._graphql === undefined) {
this._graphql = graphql.defaults({
headers: {
Authorization: `Bearer ${this.token}`,
}
});
}
return this._graphql;
}
get token() {
return this.session.accessToken;
}
async filesQuery(uri: Uri) {
const { owner, repo, ref } = fromGitHubUri(uri);
try {
const resp = await new Octokit({
auth: `token ${this.token}`,
}).git.getTree({
owner: owner,
repo: repo,
recursive: '1',
tree_sha: ref ?? 'HEAD',
});
return Iterables.filterMap(resp.data.tree, p => p.type === 'blob' ? p.path : undefined);
} catch (ex) {
return [];
}
}
async searchQuery(
query: string,
uri: Uri,
options: { maxResults?: number; context?: { before?: number; after?: number } },
_token: CancellationToken,
): Promise<SearchQueryResults> {
const { owner, repo, ref } = fromGitHubUri(uri);
// If we have a specific ref, don't try to search, because GitHub search only works against the default branch
if (ref === undefined) {
return { matches: [], limitHit: true };
}
try {
const resp = await new Octokit({
auth: `token ${this.token}`,
request: {
headers: {
accept: 'application/vnd.github.v3.text-match+json',
},
}
}).search.code({
q: `${query} repo:${owner}/${repo}`,
});
// Since GitHub doesn't return ANY line numbers just fake it at the top of the file 😢
const range = new Range(0, 0, 0, 0);
const matches: SearchQueryMatch[] = [];
console.log(resp.data.items.length, resp.data.items);
let counter = 0;
let match: SearchQueryMatch;
for (const item of resp.data.items) {
for (const m of (item as typeof item & { text_matches: GitHubSearchTextMatch[] }).text_matches) {
counter++;
if (options.maxResults !== undefined && counter > options.maxResults) {
return { matches: matches, limitHit: true };
}
match = {
path: item.path,
ranges: [],
preview: m.fragment,
matches: [],
};
for (const lm of m.matches) {
let line = 0;
let shartChar = 0;
let endChar = 0;
for (let i = 0; i < lm.indices[1]; i++) {
if (i === lm.indices[0]) {
shartChar = endChar;
}
if (m.fragment[i] === '\n') {
line++;
endChar = 0;
} else {
endChar++;
}
}
match.ranges.push(range);
match.matches.push(new Range(line, shartChar, line, endChar));
}
matches.push(match);
}
}
return { matches: matches, limitHit: false };
} catch (ex) {
return { matches: [], limitHit: true };
}
}
async fsQuery<T>(uri: Uri, innerQuery: string): Promise<T | undefined> {
try {
const query = `query fs($owner: String!, $repo: String!, $path: String) {
repository(owner: $owner, name: $repo) {
object(expression: $path) {
${innerQuery}
}
}
}`;
const { owner, repo, path, ref } = fromGitHubUri(uri);
const variables = {
owner: owner,
repo: repo,
path: `${ref ?? 'HEAD'}:${path}`,
};
const rsp = await this.query<{
repository: { object: T | null | undefined };
}>(query, variables);
return rsp?.repository?.object ?? undefined;
} catch (ex) {
return undefined;
}
}
query<T>(query: string, variables: { [key: string]: string | number }): Promise<T | undefined> {
return this.graphql(query, variables) as Promise<T | undefined>;
}
}
interface GitHubSearchTextMatch {
object_url: string;
object_type: string;
property: string;
fragment: string;
matches: GitHubSearchMatch[];
}
interface GitHubSearchMatch {
text: string;
indices: number[];
}

Просмотреть файл

@ -0,0 +1,28 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
export namespace Iterables {
export function* filterMap<T, TMapped>(
source: Iterable<T> | IterableIterator<T>,
predicateMapper: (item: T) => TMapped | undefined | null,
): Iterable<TMapped> {
for (const item of source) {
const mapped = predicateMapper(item);
// eslint-disable-next-line eqeqeq
if (mapped != null) { yield mapped; }
}
}
export function* map<T, TMapped>(
source: Iterable<T> | IterableIterator<T>,
mapper: (item: T) => TMapped,
): Iterable<TMapped> {
for (const item of source) {
yield mapper(item);
}
}
}

8
extensions/github-browser/src/typings/ref.d.ts поставляемый Normal file
Просмотреть файл

@ -0,0 +1,8 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/// <reference path='../../../../src/vs/vscode.d.ts'/>
/// <reference path='../../../../src/vs/vscode.proposed.d.ts'/>
/// <reference path="../../../types/lib.textEncoder.d.ts" />

Просмотреть файл

@ -0,0 +1,13 @@
{
"extends": "../shared.tsconfig.json",
"compilerOptions": {
"outDir": "./out",
// "experimentalDecorators": true,
// "typeRoots": [
// "./node_modules/@types"
// ]
},
"include": [
"src/**/*"
]
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -24,7 +24,7 @@ function getAgent(url: string | undefined = process.env.HTTPS_PROXY): Agent {
}
}
const scopes = ['repo'];
const scopes = ['repo', 'workflow'];
export async function getSession(): Promise<AuthenticationSession> {
const authenticationSessions = await authentication.getSessions('github', scopes);

Просмотреть файл

@ -11,9 +11,15 @@ import { GithubCredentialProviderManager } from './credentialProvider';
export async function activate(context: vscode.ExtensionContext) {
const gitExtension = vscode.extensions.getExtension<GitExtension>('vscode.git')!.exports;
const gitAPI = gitExtension.getAPI(1);
context.subscriptions.push(...registerCommands(gitAPI));
context.subscriptions.push(gitAPI.registerRemoteSourceProvider(new GithubRemoteSourceProvider(gitAPI)));
context.subscriptions.push(new GithubCredentialProviderManager(gitAPI));
try {
const gitAPI = gitExtension.getAPI(1);
context.subscriptions.push(...registerCommands(gitAPI));
context.subscriptions.push(gitAPI.registerRemoteSourceProvider(new GithubRemoteSourceProvider(gitAPI)));
context.subscriptions.push(new GithubCredentialProviderManager(gitAPI));
} catch (err) {
console.error('Could not initialize GitHub extension');
console.warn(err);
}
}

Просмотреть файл

@ -0,0 +1,29 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
//@ts-check
'use strict';
const withDefaults = require('../shared.webpack.config');
const path = require('path');
const clientConfig = withDefaults({
context: __dirname,
target: 'webworker',
entry: {
extension: './src/extension.ts'
},
resolve: {
alias: {
'vscode-extension-telemetry': path.resolve(__dirname, '../../build/polyfills/vscode-extension-telemetry.js'),
'vscode-nls': path.resolve(__dirname, '../../build/polyfills/vscode-nls.js'),
},
}
});
clientConfig.module.rules[0].use.shift(); // remove nls loader
module.exports = clientConfig;

Просмотреть файл

@ -2,7 +2,10 @@
"name": "image-preview",
"displayName": "%displayName%",
"description": "%description%",
"extensionKind": ["ui", "workspace"],
"extensionKind": [
"ui",
"workspace"
],
"version": "1.0.0",
"publisher": "vscode",
"icon": "icon.png",
@ -13,6 +16,7 @@
"vscode": "^1.39.0"
},
"main": "./out/extension",
"browser": "./dist/extension.js",
"categories": [
"Other"
],
@ -65,7 +69,9 @@
"compile": "gulp compile-extension:image-preview",
"watch": "npm run build-preview && gulp watch-extension:image-preview",
"vscode:prepublish": "npm run build-ext",
"build-ext": "node ../../node_modules/gulp/bin/gulp.js --gulpfile ../../build/gulpfile.extensions.js compile-extension:image-preview ./tsconfig.json"
"build-ext": "node ../../node_modules/gulp/bin/gulp.js --gulpfile ../../build/gulpfile.extensions.js compile-extension:image-preview ./tsconfig.json",
"compile-web": "npx webpack-cli --config extension-browser.webpack.config --mode none",
"watch-web": "npx webpack-cli --config extension-browser.webpack.config --mode none --watch --info-verbosity verbose"
},
"dependencies": {
"vscode-extension-telemetry": "0.1.1",

Просмотреть файл

@ -10,8 +10,6 @@ import { BinarySizeStatusBarEntry } from './binarySizeStatusBarEntry';
import { ZoomStatusBarEntry } from './zoomStatusBarEntry';
export function activate(context: vscode.ExtensionContext) {
const extensionRoot = vscode.Uri.file(context.extensionPath);
const sizeStatusBarEntry = new SizeStatusBarEntry();
context.subscriptions.push(sizeStatusBarEntry);
@ -21,9 +19,9 @@ export function activate(context: vscode.ExtensionContext) {
const zoomStatusBarEntry = new ZoomStatusBarEntry();
context.subscriptions.push(zoomStatusBarEntry);
const previewManager = new PreviewManager(extensionRoot, sizeStatusBarEntry, binarySizeStatusBarEntry, zoomStatusBarEntry);
const previewManager = new PreviewManager(context.extensionUri, sizeStatusBarEntry, binarySizeStatusBarEntry, zoomStatusBarEntry);
context.subscriptions.push(vscode.window.registerCustomEditorProvider2(PreviewManager.viewType, previewManager, {
context.subscriptions.push(vscode.window.registerCustomEditorProvider(PreviewManager.viewType, previewManager, {
supportsMultipleEditorsPerDocument: true,
}));

Просмотреть файл

@ -15,4 +15,6 @@ server/.npmignore
yarn.lock
CONTRIBUTING.md
server/extension.webpack.config.js
extension.webpack.config.js
extension.webpack.config.js
server/extension-browser.webpack.config.js
extension-browser.webpack.config.js

Просмотреть файл

@ -0,0 +1,40 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ExtensionContext } from 'vscode';
import { LanguageClientOptions } from 'vscode-languageclient';
import { startClient, LanguageClientConstructor } from '../jsonClient';
import { LanguageClient } from 'vscode-languageclient/browser';
import { RequestService } from '../requests';
declare const Worker: {
new(stringUrl: string): any;
};
declare function fetch(uri: string, options: any): any;
// this method is called when vs code is activated
export function activate(context: ExtensionContext) {
const serverMain = context.asAbsolutePath('server/dist/browser/jsonServerMain.js');
try {
const worker = new Worker(serverMain);
const newLanguageClient: LanguageClientConstructor = (id: string, name: string, clientOptions: LanguageClientOptions) => {
return new LanguageClient(id, name, clientOptions, worker);
};
const http: RequestService = {
getContent(uri: string) {
return fetch(uri, { mode: 'cors' })
.then(function (response: any) {
return response.text();
});
}
};
startClient(context, newLanguageClient, { http });
} catch (e) {
console.log(e);
}
}

Просмотреть файл

@ -2,11 +2,7 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as path from 'path';
import * as fs from 'fs';
import * as nls from 'vscode-nls';
import { xhr, XHRResponse, getErrorStatusDescription } from 'request-light';
const localize = nls.loadMessageBundle();
@ -16,13 +12,13 @@ import {
ProviderResult, TextEdit, Range, Position, Disposable, CompletionItem, CompletionList, CompletionContext, Hover, MarkdownString,
} from 'vscode';
import {
LanguageClient, LanguageClientOptions, RequestType, ServerOptions, TransportKind, NotificationType,
LanguageClientOptions, RequestType, NotificationType,
DidChangeConfigurationNotification, HandleDiagnosticsSignature, ResponseError, DocumentRangeFormattingParams,
DocumentRangeFormattingRequest, ProvideCompletionItemsSignature, ProvideHoverSignature
DocumentRangeFormattingRequest, ProvideCompletionItemsSignature, ProvideHoverSignature, CommonLanguageClient
} from 'vscode-languageclient';
import TelemetryReporter from 'vscode-extension-telemetry';
import { hash } from './utils/hash';
import { RequestService, joinPath } from './requests';
namespace VSCodeContentRequest {
export const type: RequestType<string, string, any, any> = new RequestType('vscode/content');
@ -53,12 +49,6 @@ namespace ResultLimitReachedNotification {
export const type: NotificationType<string, any> = new NotificationType('json/resultLimitReached');
}
interface IPackageInfo {
name: string;
version: string;
aiKey: string;
}
interface Settings {
json?: {
schemas?: JSONSchemaSettings[];
@ -83,29 +73,27 @@ namespace SettingIds {
export const maxItemsComputed = 'json.maxItemsComputed';
}
let telemetryReporter: TelemetryReporter | undefined;
export interface TelemetryReporter {
sendTelemetryEvent(eventName: string, properties?: {
[key: string]: string;
}, measurements?: {
[key: string]: number;
}): void;
}
export function activate(context: ExtensionContext) {
export type LanguageClientConstructor = (name: string, description: string, clientOptions: LanguageClientOptions) => CommonLanguageClient;
export interface Runtime {
http: RequestService;
telemetry?: TelemetryReporter
}
export function startClient(context: ExtensionContext, newLanguageClient: LanguageClientConstructor, runtime: Runtime) {
const toDispose = context.subscriptions;
let rangeFormatting: Disposable | undefined = undefined;
const packageInfo = getPackageInfo(context);
telemetryReporter = packageInfo && new TelemetryReporter(packageInfo.name, packageInfo.version, packageInfo.aiKey);
const serverMain = readJSONFile(context.asAbsolutePath('./server/package.json')).main;
const serverModule = context.asAbsolutePath(path.join('server', serverMain));
// The debug options for the server
const debugOptions = { execArgv: ['--nolazy', '--inspect=' + (9000 + Math.round(Math.random() * 10000))] };
// If the extension is launch in debug mode the debug server options are use
// Otherwise the run options are used
const serverOptions: ServerOptions = {
run: { module: serverModule, transport: TransportKind.ipc },
debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions }
};
const documentSelector = ['json', 'jsonc'];
@ -119,6 +107,7 @@ export function activate(context: ExtensionContext) {
toDispose.push(schemaResolutionErrorStatusBarItem);
const fileSchemaErrors = new Map<string, string>();
let schemaDownloadEnabled = true;
// Options to control the language client
const clientOptions: LanguageClientOptions = {
@ -139,7 +128,7 @@ export function activate(context: ExtensionContext) {
didChangeConfiguration: () => client.sendNotification(DidChangeConfigurationNotification.type, { settings: getSettings() })
},
handleDiagnostics: (uri: Uri, diagnostics: Diagnostic[], next: HandleDiagnosticsSignature) => {
const schemaErrorIndex = diagnostics.findIndex(candidate => candidate.code === /* SchemaResolveError */ 0x300);
const schemaErrorIndex = diagnostics.findIndex(isSchemaResolveError);
if (schemaErrorIndex === -1) {
fileSchemaErrors.delete(uri.toString());
@ -149,6 +138,10 @@ export function activate(context: ExtensionContext) {
const schemaResolveDiagnostic = diagnostics[schemaErrorIndex];
fileSchemaErrors.set(uri.toString(), schemaResolveDiagnostic.message);
if (!schemaDownloadEnabled) {
diagnostics = diagnostics.filter(d => !isSchemaResolveError(d));
}
if (window.activeTextEditor && window.activeTextEditor.document.uri.toString() === uri.toString()) {
schemaResolutionErrorStatusBarItem.show();
}
@ -197,49 +190,39 @@ export function activate(context: ExtensionContext) {
};
// Create the language client and start the client.
const client = new LanguageClient('json', localize('jsonserver.name', 'JSON Language Server'), serverOptions, clientOptions);
const client = newLanguageClient('json', localize('jsonserver.name', 'JSON Language Server'), clientOptions);
client.registerProposedFeatures();
const disposable = client.start();
toDispose.push(disposable);
client.onReady().then(() => {
const schemaDocuments: { [uri: string]: boolean } = {};
let schemaDownloadEnabled = true;
// handle content request
client.onRequest(VSCodeContentRequest.type, (uriPath: string) => {
const uri = Uri.parse(uriPath);
if (uri.scheme === 'untitled') {
return Promise.reject(new Error(localize('untitled.schema', 'Unable to load {0}', uri.toString())));
return Promise.reject(new ResponseError(3, localize('untitled.schema', 'Unable to load {0}', uri.toString())));
}
if (uri.scheme !== 'http' && uri.scheme !== 'https') {
return workspace.openTextDocument(uri).then(doc => {
schemaDocuments[uri.toString()] = true;
return doc.getText();
}, error => {
return Promise.reject(error);
return Promise.reject(new ResponseError(2, error.toString()));
});
} else if (schemaDownloadEnabled) {
if (telemetryReporter && uri.authority === 'schema.management.azure.com') {
if (runtime.telemetry && uri.authority === 'schema.management.azure.com') {
/* __GDPR__
"json.schema" : {
"schemaURL" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
telemetryReporter.sendTelemetryEvent('json.schema', { schemaURL: uriPath });
runtime.telemetry.sendTelemetryEvent('json.schema', { schemaURL: uriPath });
}
const headers = { 'Accept-Encoding': 'gzip, deflate' };
return xhr({ url: uriPath, followRedirects: 5, headers }).then(response => {
return response.responseText;
}, (error: XHRResponse) => {
let extraInfo = error.responseText || error.toString();
if (extraInfo.length > 256) {
extraInfo = `${extraInfo.substr(0, 256)}...`;
}
return Promise.reject(new ResponseError(error.status, getErrorStatusDescription(error.status) + '\n' + extraInfo));
});
return runtime.http.getContent(uriPath);
} else {
return Promise.reject(localize('schemaDownloadDisabled', 'Downloading schemas is disabled through setting \'{0}\'', SettingIds.enableSchemaDownload));
return Promise.reject(new ResponseError(1, localize('schemaDownloadDisabled', 'Downloading schemas is disabled through setting \'{0}\'', SettingIds.enableSchemaDownload)));
}
});
@ -280,7 +263,7 @@ export function activate(context: ExtensionContext) {
schemaResolutionErrorStatusBarItem.text = '$(watch)';
const activeDocUri = window.activeTextEditor.document.uri.toString();
client.sendRequest(ForceValidateRequest.type, activeDocUri).then((diagnostics) => {
const schemaErrorIndex = diagnostics.findIndex(candidate => candidate.code === /* SchemaResolveError */ 0x300);
const schemaErrorIndex = diagnostics.findIndex(isSchemaResolveError);
if (schemaErrorIndex !== -1) {
// Show schema resolution errors in status bar only; ref: #51032
const schemaResolveDiagnostic = diagnostics[schemaErrorIndex];
@ -335,7 +318,7 @@ export function activate(context: ExtensionContext) {
return client.sendRequest(DocumentRangeFormattingRequest.type, params, token).then(
client.protocol2CodeConverter.asTextEdits,
(error) => {
client.logFailedRequest(DocumentRangeFormattingRequest.type, error);
client.handleFailedRequest(DocumentRangeFormattingRequest.type, error, []);
return Promise.resolve([]);
}
);
@ -370,12 +353,6 @@ export function activate(context: ExtensionContext) {
}
export function deactivate(): Promise<any> {
return telemetryReporter ? telemetryReporter.dispose() : Promise.resolve(null);
}
function getSchemaAssociations(_context: ExtensionContext): ISchemaAssociation[] {
const associations: ISchemaAssociation[] = [];
extensions.all.forEach(extension => {
@ -388,9 +365,10 @@ function getSchemaAssociations(_context: ExtensionContext): ISchemaAssociation[]
if (typeof fileMatch === 'string') {
fileMatch = [fileMatch];
}
if (Array.isArray(fileMatch) && url) {
if (url[0] === '.' && url[1] === '/') {
url = Uri.file(path.join(extension.extensionPath, url)).toString();
if (Array.isArray(fileMatch) && typeof url === 'string') {
let uri: string = url;
if (uri[0] === '.' && uri[1] === '/') {
uri = joinPath(extension.extensionUri, uri).toString();
}
fileMatch = fileMatch.map(fm => {
if (fm[0] === '%') {
@ -402,7 +380,7 @@ function getSchemaAssociations(_context: ExtensionContext): ISchemaAssociation[]
}
return fm;
});
associations.push({ fileMatch, uri: url });
associations.push({ fileMatch, uri });
}
});
}
@ -504,39 +482,18 @@ function getSettings(): Settings {
return settings;
}
function getSchemaId(schema: JSONSchemaSettings, folderUri?: Uri) {
function getSchemaId(schema: JSONSchemaSettings, folderUri?: Uri): string | undefined {
let url = schema.url;
if (!url) {
if (schema.schema) {
url = schema.schema.id || `vscode://schemas/custom/${encodeURIComponent(hash(schema.schema).toString(16))}`;
}
} else if (folderUri && (url[0] === '.' || url[0] === '/')) {
url = folderUri.with({ path: path.posix.join(folderUri.path, url) }).toString();
url = joinPath(folderUri, url).toString();
}
return url;
}
function getPackageInfo(context: ExtensionContext): IPackageInfo | undefined {
const extensionPackage = readJSONFile(context.asAbsolutePath('./package.json'));
if (extensionPackage) {
return {
name: extensionPackage.name,
version: extensionPackage.version,
aiKey: extensionPackage.aiKey
};
}
return undefined;
}
function readJSONFile(location: string) {
try {
return JSON.parse(fs.readFileSync(location).toString());
} catch (e) {
console.log(`Problems reading ${location}: ${e}`);
return {};
}
}
function isThenable<T>(obj: ProviderResult<T>): obj is Thenable<T> {
return obj && (<any>obj)['then'];
}
@ -546,3 +503,7 @@ function updateMarkdownString(h: MarkdownString): MarkdownString {
n.isTrusted = h.isTrusted;
return n;
}
function isSchemaResolveError(d: Diagnostic) {
return d.code === /* SchemaResolveError */ 0x300;
}

Просмотреть файл

@ -0,0 +1,76 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ExtensionContext } from 'vscode';
import { startClient, LanguageClientConstructor } from '../jsonClient';
import { ServerOptions, TransportKind, LanguageClientOptions, LanguageClient } from 'vscode-languageclient/node';
import * as fs from 'fs';
import { xhr, XHRResponse, getErrorStatusDescription } from 'request-light';
import TelemetryReporter from 'vscode-extension-telemetry';
import { RequestService } from '../requests';
let telemetry: TelemetryReporter | undefined;
// this method is called when vs code is activated
export function activate(context: ExtensionContext) {
const clientPackageJSON = getPackageInfo(context);
telemetry = new TelemetryReporter(clientPackageJSON.name, clientPackageJSON.version, clientPackageJSON.aiKey);
const serverMain = `./server/${clientPackageJSON.main.indexOf('/dist/') !== -1 ? 'dist' : 'out'}/node/jsonServerMain`;
const serverModule = context.asAbsolutePath(serverMain);
// The debug options for the server
const debugOptions = { execArgv: ['--nolazy', '--inspect=6044'] };
// If the extension is launch in debug mode the debug server options are use
// Otherwise the run options are used
const serverOptions: ServerOptions = {
run: { module: serverModule, transport: TransportKind.ipc },
debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions }
};
const newLanguageClient: LanguageClientConstructor = (id: string, name: string, clientOptions: LanguageClientOptions) => {
return new LanguageClient(id, name, serverOptions, clientOptions);
};
startClient(context, newLanguageClient, { http: getHTTPRequestService(), telemetry });
}
export function deactivate(): Promise<any> {
return telemetry ? telemetry.dispose() : Promise.resolve(null);
}
interface IPackageInfo {
name: string;
version: string;
aiKey: string;
main: string;
}
function getPackageInfo(context: ExtensionContext): IPackageInfo {
const location = context.asAbsolutePath('./package.json');
try {
return JSON.parse(fs.readFileSync(location).toString());
} catch (e) {
console.log(`Problems reading ${location}: ${e}`);
return { name: '', version: '', aiKey: '', main: '' };
}
}
function getHTTPRequestService(): RequestService {
return {
getContent(uri: string, _encoding?: string) {
const headers = { 'Accept-Encoding': 'gzip, deflate' };
return xhr({ url: uri, followRedirects: 5, headers }).then(response => {
return response.responseText;
}, (error: XHRResponse) => {
return Promise.reject(error.responseText || getErrorStatusDescription(error.status) || error.toString());
});
}
};
}

Просмотреть файл

@ -0,0 +1,68 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Uri } from 'vscode';
export interface RequestService {
getContent(uri: string, encoding?: string): Thenable<string>;
}
export function getScheme(uri: string) {
return uri.substr(0, uri.indexOf(':'));
}
export function dirname(uri: string) {
const lastIndexOfSlash = uri.lastIndexOf('/');
return lastIndexOfSlash !== -1 ? uri.substr(0, lastIndexOfSlash) : '';
}
export function basename(uri: string) {
const lastIndexOfSlash = uri.lastIndexOf('/');
return uri.substr(lastIndexOfSlash + 1);
}
const Slash = '/'.charCodeAt(0);
const Dot = '.'.charCodeAt(0);
export function isAbsolutePath(path: string) {
return path.charCodeAt(0) === Slash;
}
export function resolvePath(uri: Uri, path: string): Uri {
if (isAbsolutePath(path)) {
return uri.with({ path: normalizePath(path.split('/')) });
}
return joinPath(uri, path);
}
export function normalizePath(parts: string[]): string {
const newParts: string[] = [];
for (const part of parts) {
if (part.length === 0 || part.length === 1 && part.charCodeAt(0) === Dot) {
// ignore
} else if (part.length === 2 && part.charCodeAt(0) === Dot && part.charCodeAt(1) === Dot) {
newParts.pop();
} else {
newParts.push(part);
}
}
if (parts.length > 1 && parts[parts.length - 1].length === 0) {
newParts.push('');
}
let res = newParts.join('/');
if (parts[0].length === 0) {
res = '/' + res;
}
return res;
}
export function joinPath(uri: Uri, ...paths: string[]): Uri {
const parts = uri.path.split('/');
for (let path of paths) {
parts.push(...path.split('/'));
}
return uri.with({ path: normalizePath(parts) });
}

Просмотреть файл

@ -0,0 +1,34 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
//@ts-check
'use strict';
const withDefaults = require('../shared.webpack.config');
const path = require('path');
const clientConfig = withDefaults({
target: 'webworker',
context: path.join(__dirname, 'client'),
entry: {
extension: './src/browser/jsonClientMain.ts'
},
output: {
filename: 'jsonClientMain.js',
path: path.join(__dirname, 'client', 'dist', 'browser')
},
performance: {
hints: false
},
resolve: {
alias: {
'vscode-nls': path.resolve(__dirname, '../../build/polyfills/vscode-nls.js')
}
}
});
clientConfig.module.rules[0].use.shift(); // remove nls loader
module.exports = clientConfig;

Просмотреть файл

@ -14,11 +14,11 @@ const webpack = require('webpack');
const config = withDefaults({
context: path.join(__dirname, 'client'),
entry: {
extension: './src/jsonMain.ts',
extension: './src/node/jsonClientMain.ts'
},
output: {
filename: 'jsonMain.js',
path: path.join(__dirname, 'client', 'dist')
filename: 'jsonClientMain.js',
path: path.join(__dirname, 'client', 'dist', 'node')
}
});

Просмотреть файл

@ -14,7 +14,8 @@
"onLanguage:json",
"onLanguage:jsonc"
],
"main": "./client/out/jsonMain",
"main": "./client/out/node/jsonClientMain",
"browser": "./client/dist/browser/jsonClientMain",
"enableProposedApi": true,
"scripts": {
"compile": "gulp compile-extension:json-language-features-client compile-extension:json-language-features-server",
@ -128,7 +129,7 @@
"dependencies": {
"request-light": "^0.3.0",
"vscode-extension-telemetry": "0.1.1",
"vscode-languageclient": "^6.1.3",
"vscode-languageclient": "7.0.0-next.5",
"vscode-nls": "^4.1.2"
},
"devDependencies": {

Просмотреть файл

@ -0,0 +1,35 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
//@ts-check
'use strict';
const withDefaults = require('../../shared.webpack.config');
const path = require('path');
const serverConfig = withDefaults({
target: 'webworker',
context: __dirname,
entry: {
extension: './src/browser/jsonServerMain.ts',
},
output: {
filename: 'jsonServerMain.js',
path: path.join(__dirname, 'dist', 'browser'),
libraryTarget: 'var'
},
performance: {
hints: false
},
resolve: {
alias: {
'vscode-nls': path.resolve(__dirname, '../../../build/polyfills/vscode-nls.js')
}
}
});
serverConfig.module.rules[0].use.shift(); // remove nls loader
module.exports = serverConfig;

Просмотреть файл

@ -14,11 +14,11 @@ const webpack = require('webpack');
const config = withDefaults({
context: path.join(__dirname),
entry: {
extension: './src/jsonServerMain.ts',
extension: './src/node/jsonServerMain.ts',
},
output: {
filename: 'jsonServerMain.js',
path: path.join(__dirname, 'dist')
path: path.join(__dirname, 'dist', 'node'),
}
});

Просмотреть файл

@ -14,9 +14,9 @@
"dependencies": {
"jsonc-parser": "^2.2.1",
"request-light": "^0.3.0",
"vscode-json-languageservice": "^3.6.0",
"vscode-languageserver": "^6.1.1",
"vscode-uri": "^2.1.1"
"vscode-json-languageservice": "^3.7.0",
"vscode-languageserver": "7.0.0-next.3",
"vscode-uri": "^2.1.2"
},
"devDependencies": {
"@types/mocha": "2.2.33",

Просмотреть файл

@ -0,0 +1,16 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { createConnection, BrowserMessageReader, BrowserMessageWriter } from 'vscode-languageserver/browser';
import { startServer } from '../jsonServer';
declare let self: any;
const messageReader = new BrowserMessageReader(self);
const messageWriter = new BrowserMessageWriter(self);
const connection = createConnection(messageReader, messageWriter);
startServer(connection, {});

Просмотреть файл

@ -0,0 +1,504 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import {
Connection,
TextDocuments, InitializeParams, InitializeResult, NotificationType, RequestType,
DocumentRangeFormattingRequest, Disposable, ServerCapabilities, TextDocumentSyncKind, TextEdit
} from 'vscode-languageserver';
import { formatError, runSafe, runSafeAsync } from './utils/runner';
import { TextDocument, JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration, ClientCapabilities, Diagnostic, Range, Position } from 'vscode-json-languageservice';
import { getLanguageModelCache } from './languageModelCache';
import { RequestService, basename, resolvePath } from './requests';
interface ISchemaAssociations {
[pattern: string]: string[];
}
interface ISchemaAssociation {
fileMatch: string[];
uri: string;
}
namespace SchemaAssociationNotification {
export const type: NotificationType<ISchemaAssociations | ISchemaAssociation[], any> = new NotificationType('json/schemaAssociations');
}
namespace VSCodeContentRequest {
export const type: RequestType<string, string, any, any> = new RequestType('vscode/content');
}
namespace SchemaContentChangeNotification {
export const type: NotificationType<string, any> = new NotificationType('json/schemaContent');
}
namespace ResultLimitReachedNotification {
export const type: NotificationType<string, any> = new NotificationType('json/resultLimitReached');
}
namespace ForceValidateRequest {
export const type: RequestType<string, Diagnostic[], any, any> = new RequestType('json/validate');
}
const workspaceContext = {
resolveRelativePath: (relativePath: string, resource: string) => {
const base = resource.substr(0, resource.lastIndexOf('/') + 1);
return resolvePath(base, relativePath);
}
};
export interface RuntimeEnvironment {
file?: RequestService;
http?: RequestService
configureHttpRequests?(proxy: string, strictSSL: boolean): void;
}
export function startServer(connection: Connection, runtime: RuntimeEnvironment) {
function getSchemaRequestService(handledSchemas: string[] = ['https', 'http', 'file']) {
const builtInHandlers: { [protocol: string]: RequestService | undefined } = {};
for (let protocol of handledSchemas) {
if (protocol === 'file') {
builtInHandlers[protocol] = runtime.file;
} else if (protocol === 'http' || protocol === 'https') {
builtInHandlers[protocol] = runtime.http;
}
}
return (uri: string): Thenable<string> => {
const protocol = uri.substr(0, uri.indexOf(':'));
const builtInHandler = builtInHandlers[protocol];
if (builtInHandler) {
return builtInHandler.getContent(uri);
}
return connection.sendRequest(VSCodeContentRequest.type, uri).then(responseText => {
return responseText;
}, error => {
return Promise.reject(error.message);
});
};
}
// create the JSON language service
let languageService = getLanguageService({
workspaceContext,
contributions: [],
clientCapabilities: ClientCapabilities.LATEST
});
// Create a text document manager.
const documents = new TextDocuments(TextDocument);
// Make the text document manager listen on the connection
// for open, change and close text document events
documents.listen(connection);
let clientSnippetSupport = false;
let dynamicFormatterRegistration = false;
let hierarchicalDocumentSymbolSupport = false;
let foldingRangeLimitDefault = Number.MAX_VALUE;
let foldingRangeLimit = Number.MAX_VALUE;
let resultLimit = Number.MAX_VALUE;
let formatterMaxNumberOfEdits = Number.MAX_VALUE;
// After the server has started the client sends an initialize request. The server receives
// in the passed params the rootPath of the workspace plus the client capabilities.
connection.onInitialize((params: InitializeParams): InitializeResult => {
const handledProtocols = params.initializationOptions?.handledSchemaProtocols;
languageService = getLanguageService({
schemaRequestService: getSchemaRequestService(handledProtocols),
workspaceContext,
contributions: [],
clientCapabilities: params.capabilities
});
function getClientCapability<T>(name: string, def: T) {
const keys = name.split('.');
let c: any = params.capabilities;
for (let i = 0; c && i < keys.length; i++) {
if (!c.hasOwnProperty(keys[i])) {
return def;
}
c = c[keys[i]];
}
return c;
}
clientSnippetSupport = getClientCapability('textDocument.completion.completionItem.snippetSupport', false);
dynamicFormatterRegistration = getClientCapability('textDocument.rangeFormatting.dynamicRegistration', false) && (typeof params.initializationOptions?.provideFormatter !== 'boolean');
foldingRangeLimitDefault = getClientCapability('textDocument.foldingRange.rangeLimit', Number.MAX_VALUE);
hierarchicalDocumentSymbolSupport = getClientCapability('textDocument.documentSymbol.hierarchicalDocumentSymbolSupport', false);
formatterMaxNumberOfEdits = params.initializationOptions?.customCapabilities?.rangeFormatting?.editLimit || Number.MAX_VALUE;
const capabilities: ServerCapabilities = {
textDocumentSync: TextDocumentSyncKind.Incremental,
completionProvider: clientSnippetSupport ? {
resolveProvider: false, // turn off resolving as the current language service doesn't do anything on resolve. Also fixes #91747
triggerCharacters: ['"', ':']
} : undefined,
hoverProvider: true,
documentSymbolProvider: true,
documentRangeFormattingProvider: params.initializationOptions.provideFormatter === true,
colorProvider: {},
foldingRangeProvider: true,
selectionRangeProvider: true,
definitionProvider: true
};
return { capabilities };
});
// The settings interface describes the server relevant settings part
interface Settings {
json: {
schemas: JSONSchemaSettings[];
format: { enable: boolean; };
resultLimit?: number;
};
http: {
proxy: string;
proxyStrictSSL: boolean;
};
}
interface JSONSchemaSettings {
fileMatch?: string[];
url?: string;
schema?: JSONSchema;
}
const limitExceededWarnings = function () {
const pendingWarnings: { [uri: string]: { features: { [name: string]: string }; timeout?: NodeJS.Timeout; } } = {};
return {
cancel(uri: string) {
const warning = pendingWarnings[uri];
if (warning && warning.timeout) {
clearTimeout(warning.timeout);
delete pendingWarnings[uri];
}
},
onResultLimitExceeded(uri: string, resultLimit: number, name: string) {
return () => {
let warning = pendingWarnings[uri];
if (warning) {
if (!warning.timeout) {
// already shown
return;
}
warning.features[name] = name;
warning.timeout.refresh();
} else {
warning = { features: { [name]: name } };
warning.timeout = setTimeout(() => {
connection.sendNotification(ResultLimitReachedNotification.type, `${basename(uri)}: For performance reasons, ${Object.keys(warning.features).join(' and ')} have been limited to ${resultLimit} items.`);
warning.timeout = undefined;
}, 2000);
pendingWarnings[uri] = warning;
}
};
}
};
}();
let jsonConfigurationSettings: JSONSchemaSettings[] | undefined = undefined;
let schemaAssociations: ISchemaAssociations | ISchemaAssociation[] | undefined = undefined;
let formatterRegistration: Thenable<Disposable> | null = null;
// The settings have changed. Is send on server activation as well.
connection.onDidChangeConfiguration((change) => {
let settings = <Settings>change.settings;
if (runtime.configureHttpRequests) {
runtime.configureHttpRequests(settings.http && settings.http.proxy, settings.http && settings.http.proxyStrictSSL);
}
jsonConfigurationSettings = settings.json && settings.json.schemas;
updateConfiguration();
foldingRangeLimit = Math.trunc(Math.max(settings.json && settings.json.resultLimit || foldingRangeLimitDefault, 0));
resultLimit = Math.trunc(Math.max(settings.json && settings.json.resultLimit || Number.MAX_VALUE, 0));
// dynamically enable & disable the formatter
if (dynamicFormatterRegistration) {
const enableFormatter = settings && settings.json && settings.json.format && settings.json.format.enable;
if (enableFormatter) {
if (!formatterRegistration) {
formatterRegistration = connection.client.register(DocumentRangeFormattingRequest.type, { documentSelector: [{ language: 'json' }, { language: 'jsonc' }] });
}
} else if (formatterRegistration) {
formatterRegistration.then(r => r.dispose());
formatterRegistration = null;
}
}
});
// The jsonValidation extension configuration has changed
connection.onNotification(SchemaAssociationNotification.type, associations => {
schemaAssociations = associations;
updateConfiguration();
});
// A schema has changed
connection.onNotification(SchemaContentChangeNotification.type, uri => {
languageService.resetSchema(uri);
});
// Retry schema validation on all open documents
connection.onRequest(ForceValidateRequest.type, uri => {
return new Promise<Diagnostic[]>(resolve => {
const document = documents.get(uri);
if (document) {
updateConfiguration();
validateTextDocument(document, diagnostics => {
resolve(diagnostics);
});
} else {
resolve([]);
}
});
});
function updateConfiguration() {
const languageSettings = {
validate: true,
allowComments: true,
schemas: new Array<SchemaConfiguration>()
};
if (schemaAssociations) {
if (Array.isArray(schemaAssociations)) {
Array.prototype.push.apply(languageSettings.schemas, schemaAssociations);
} else {
for (const pattern in schemaAssociations) {
const association = schemaAssociations[pattern];
if (Array.isArray(association)) {
association.forEach(uri => {
languageSettings.schemas.push({ uri, fileMatch: [pattern] });
});
}
}
}
}
if (jsonConfigurationSettings) {
jsonConfigurationSettings.forEach((schema, index) => {
let uri = schema.url;
if (!uri && schema.schema) {
uri = schema.schema.id || `vscode://schemas/custom/${index}`;
}
if (uri) {
languageSettings.schemas.push({ uri, fileMatch: schema.fileMatch, schema: schema.schema });
}
});
}
languageService.configure(languageSettings);
// Revalidate any open text documents
documents.all().forEach(triggerValidation);
}
// The content of a text document has changed. This event is emitted
// when the text document first opened or when its content has changed.
documents.onDidChangeContent((change) => {
limitExceededWarnings.cancel(change.document.uri);
triggerValidation(change.document);
});
// a document has closed: clear all diagnostics
documents.onDidClose(event => {
limitExceededWarnings.cancel(event.document.uri);
cleanPendingValidation(event.document);
connection.sendDiagnostics({ uri: event.document.uri, diagnostics: [] });
});
const pendingValidationRequests: { [uri: string]: NodeJS.Timer; } = {};
const validationDelayMs = 300;
function cleanPendingValidation(textDocument: TextDocument): void {
const request = pendingValidationRequests[textDocument.uri];
if (request) {
clearTimeout(request);
delete pendingValidationRequests[textDocument.uri];
}
}
function triggerValidation(textDocument: TextDocument): void {
cleanPendingValidation(textDocument);
pendingValidationRequests[textDocument.uri] = setTimeout(() => {
delete pendingValidationRequests[textDocument.uri];
validateTextDocument(textDocument);
}, validationDelayMs);
}
function validateTextDocument(textDocument: TextDocument, callback?: (diagnostics: Diagnostic[]) => void): void {
const respond = (diagnostics: Diagnostic[]) => {
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
if (callback) {
callback(diagnostics);
}
};
if (textDocument.getText().length === 0) {
respond([]); // ignore empty documents
return;
}
const jsonDocument = getJSONDocument(textDocument);
const version = textDocument.version;
const documentSettings: DocumentLanguageSettings = textDocument.languageId === 'jsonc' ? { comments: 'ignore', trailingCommas: 'warning' } : { comments: 'error', trailingCommas: 'error' };
languageService.doValidation(textDocument, jsonDocument, documentSettings).then(diagnostics => {
setImmediate(() => {
const currDocument = documents.get(textDocument.uri);
if (currDocument && currDocument.version === version) {
respond(diagnostics); // Send the computed diagnostics to VSCode.
}
});
}, error => {
connection.console.error(formatError(`Error while validating ${textDocument.uri}`, error));
});
}
connection.onDidChangeWatchedFiles((change) => {
// Monitored files have changed in VSCode
let hasChanges = false;
change.changes.forEach(c => {
if (languageService.resetSchema(c.uri)) {
hasChanges = true;
}
});
if (hasChanges) {
documents.all().forEach(triggerValidation);
}
});
const jsonDocuments = getLanguageModelCache<JSONDocument>(10, 60, document => languageService.parseJSONDocument(document));
documents.onDidClose(e => {
jsonDocuments.onDocumentRemoved(e.document);
});
connection.onShutdown(() => {
jsonDocuments.dispose();
});
function getJSONDocument(document: TextDocument): JSONDocument {
return jsonDocuments.get(document);
}
connection.onCompletion((textDocumentPosition, token) => {
return runSafeAsync(async () => {
const document = documents.get(textDocumentPosition.textDocument.uri);
if (document) {
const jsonDocument = getJSONDocument(document);
return languageService.doComplete(document, textDocumentPosition.position, jsonDocument);
}
return null;
}, null, `Error while computing completions for ${textDocumentPosition.textDocument.uri}`, token);
});
connection.onHover((textDocumentPositionParams, token) => {
return runSafeAsync(async () => {
const document = documents.get(textDocumentPositionParams.textDocument.uri);
if (document) {
const jsonDocument = getJSONDocument(document);
return languageService.doHover(document, textDocumentPositionParams.position, jsonDocument);
}
return null;
}, null, `Error while computing hover for ${textDocumentPositionParams.textDocument.uri}`, token);
});
connection.onDocumentSymbol((documentSymbolParams, token) => {
return runSafe(() => {
const document = documents.get(documentSymbolParams.textDocument.uri);
if (document) {
const jsonDocument = getJSONDocument(document);
const onResultLimitExceeded = limitExceededWarnings.onResultLimitExceeded(document.uri, resultLimit, 'document symbols');
if (hierarchicalDocumentSymbolSupport) {
return languageService.findDocumentSymbols2(document, jsonDocument, { resultLimit, onResultLimitExceeded });
} else {
return languageService.findDocumentSymbols(document, jsonDocument, { resultLimit, onResultLimitExceeded });
}
}
return [];
}, [], `Error while computing document symbols for ${documentSymbolParams.textDocument.uri}`, token);
});
connection.onDocumentRangeFormatting((formatParams, token) => {
return runSafe(() => {
const document = documents.get(formatParams.textDocument.uri);
if (document) {
const edits = languageService.format(document, formatParams.range, formatParams.options);
if (edits.length > formatterMaxNumberOfEdits) {
const newText = TextDocument.applyEdits(document, edits);
return [TextEdit.replace(Range.create(Position.create(0, 0), document.positionAt(document.getText().length)), newText)];
}
return edits;
}
return [];
}, [], `Error while formatting range for ${formatParams.textDocument.uri}`, token);
});
connection.onDocumentColor((params, token) => {
return runSafeAsync(async () => {
const document = documents.get(params.textDocument.uri);
if (document) {
const onResultLimitExceeded = limitExceededWarnings.onResultLimitExceeded(document.uri, resultLimit, 'document colors');
const jsonDocument = getJSONDocument(document);
return languageService.findDocumentColors(document, jsonDocument, { resultLimit, onResultLimitExceeded });
}
return [];
}, [], `Error while computing document colors for ${params.textDocument.uri}`, token);
});
connection.onColorPresentation((params, token) => {
return runSafe(() => {
const document = documents.get(params.textDocument.uri);
if (document) {
const jsonDocument = getJSONDocument(document);
return languageService.getColorPresentations(document, jsonDocument, params.color, params.range);
}
return [];
}, [], `Error while computing color presentations for ${params.textDocument.uri}`, token);
});
connection.onFoldingRanges((params, token) => {
return runSafe(() => {
const document = documents.get(params.textDocument.uri);
if (document) {
const onRangeLimitExceeded = limitExceededWarnings.onResultLimitExceeded(document.uri, foldingRangeLimit, 'folding ranges');
return languageService.getFoldingRanges(document, { rangeLimit: foldingRangeLimit, onRangeLimitExceeded });
}
return null;
}, null, `Error while computing folding ranges for ${params.textDocument.uri}`, token);
});
connection.onSelectionRanges((params, token) => {
return runSafe(() => {
const document = documents.get(params.textDocument.uri);
if (document) {
const jsonDocument = getJSONDocument(document);
return languageService.getSelectionRanges(document, params.positions, jsonDocument);
}
return [];
}, [], `Error while computing selection ranges for ${params.textDocument.uri}`, token);
});
connection.onDefinition((params, token) => {
return runSafeAsync(async () => {
const document = documents.get(params.textDocument.uri);
if (document) {
const jsonDocument = getJSONDocument(document);
return languageService.findDefinition(document, params.position, jsonDocument);
}
return [];
}, [], `Error while computing definitions for ${params.textDocument.uri}`, token);
});
// Listen on the connection
connection.listen();
}

Просмотреть файл

@ -1,532 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import {
createConnection, IConnection,
TextDocuments, InitializeParams, InitializeResult, NotificationType, RequestType,
DocumentRangeFormattingRequest, Disposable, ServerCapabilities, TextDocumentSyncKind, TextEdit
} from 'vscode-languageserver';
import { xhr, XHRResponse, configure as configureHttpRequests, getErrorStatusDescription } from 'request-light';
import * as fs from 'fs';
import { URI } from 'vscode-uri';
import * as URL from 'url';
import { posix } from 'path';
import { setTimeout, clearTimeout } from 'timers';
import { formatError, runSafe, runSafeAsync } from './utils/runner';
import { TextDocument, JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration, ClientCapabilities, SchemaRequestService, Diagnostic, Range, Position } from 'vscode-json-languageservice';
import { getLanguageModelCache } from './languageModelCache';
interface ISchemaAssociations {
[pattern: string]: string[];
}
interface ISchemaAssociation {
fileMatch: string[];
uri: string;
}
namespace SchemaAssociationNotification {
export const type: NotificationType<ISchemaAssociations | ISchemaAssociation[], any> = new NotificationType('json/schemaAssociations');
}
namespace VSCodeContentRequest {
export const type: RequestType<string, string, any, any> = new RequestType('vscode/content');
}
namespace SchemaContentChangeNotification {
export const type: NotificationType<string, any> = new NotificationType('json/schemaContent');
}
namespace ResultLimitReachedNotification {
export const type: NotificationType<string, any> = new NotificationType('json/resultLimitReached');
}
namespace ForceValidateRequest {
export const type: RequestType<string, Diagnostic[], any, any> = new RequestType('json/validate');
}
// Create a connection for the server
const connection: IConnection = createConnection();
process.on('unhandledRejection', (e: any) => {
console.error(formatError(`Unhandled exception`, e));
});
process.on('uncaughtException', (e: any) => {
console.error(formatError(`Unhandled exception`, e));
});
console.log = connection.console.log.bind(connection.console);
console.error = connection.console.error.bind(connection.console);
const workspaceContext = {
resolveRelativePath: (relativePath: string, resource: string) => {
return URL.resolve(resource, relativePath);
}
};
const fileRequestService: SchemaRequestService = (uri: string) => {
const fsPath = URI.parse(uri).fsPath;
return new Promise<string>((c, e) => {
fs.readFile(fsPath, 'UTF-8', (err, result) => {
err ? e(err.message || err.toString()) : c(result.toString());
});
});
};
const httpRequestService: SchemaRequestService = (uri: string) => {
const headers = { 'Accept-Encoding': 'gzip, deflate' };
return xhr({ url: uri, followRedirects: 5, headers }).then(response => {
return response.responseText;
}, (error: XHRResponse) => {
return Promise.reject(error.responseText || getErrorStatusDescription(error.status) || error.toString());
});
};
function getSchemaRequestService(handledSchemas: string[] = ['https', 'http', 'file']) {
const builtInHandlers: { [protocol: string]: SchemaRequestService } = {};
for (let protocol of handledSchemas) {
if (protocol === 'file') {
builtInHandlers[protocol] = fileRequestService;
} else if (protocol === 'http' || protocol === 'https') {
builtInHandlers[protocol] = httpRequestService;
}
}
return (uri: string): Thenable<string> => {
const protocol = uri.substr(0, uri.indexOf(':'));
const builtInHandler = builtInHandlers[protocol];
if (builtInHandler) {
return builtInHandler(uri);
}
return connection.sendRequest(VSCodeContentRequest.type, uri).then(responseText => {
return responseText;
}, error => {
return Promise.reject(error.message);
});
};
}
// create the JSON language service
let languageService = getLanguageService({
workspaceContext,
contributions: [],
clientCapabilities: ClientCapabilities.LATEST
});
// Create a text document manager.
const documents = new TextDocuments(TextDocument);
// Make the text document manager listen on the connection
// for open, change and close text document events
documents.listen(connection);
let clientSnippetSupport = false;
let dynamicFormatterRegistration = false;
let hierarchicalDocumentSymbolSupport = false;
let foldingRangeLimitDefault = Number.MAX_VALUE;
let foldingRangeLimit = Number.MAX_VALUE;
let resultLimit = Number.MAX_VALUE;
let formatterMaxNumberOfEdits = Number.MAX_VALUE;
// After the server has started the client sends an initialize request. The server receives
// in the passed params the rootPath of the workspace plus the client capabilities.
connection.onInitialize((params: InitializeParams): InitializeResult => {
const handledProtocols = params.initializationOptions?.handledSchemaProtocols;
languageService = getLanguageService({
schemaRequestService: getSchemaRequestService(handledProtocols),
workspaceContext,
contributions: [],
clientCapabilities: params.capabilities
});
function getClientCapability<T>(name: string, def: T) {
const keys = name.split('.');
let c: any = params.capabilities;
for (let i = 0; c && i < keys.length; i++) {
if (!c.hasOwnProperty(keys[i])) {
return def;
}
c = c[keys[i]];
}
return c;
}
clientSnippetSupport = getClientCapability('textDocument.completion.completionItem.snippetSupport', false);
dynamicFormatterRegistration = getClientCapability('textDocument.rangeFormatting.dynamicRegistration', false) && (typeof params.initializationOptions?.provideFormatter !== 'boolean');
foldingRangeLimitDefault = getClientCapability('textDocument.foldingRange.rangeLimit', Number.MAX_VALUE);
hierarchicalDocumentSymbolSupport = getClientCapability('textDocument.documentSymbol.hierarchicalDocumentSymbolSupport', false);
formatterMaxNumberOfEdits = params.initializationOptions?.customCapabilities?.rangeFormatting?.editLimit || Number.MAX_VALUE;
const capabilities: ServerCapabilities = {
textDocumentSync: TextDocumentSyncKind.Incremental,
completionProvider: clientSnippetSupport ? {
resolveProvider: false, // turn off resolving as the current language service doesn't do anything on resolve. Also fixes #91747
triggerCharacters: ['"', ':']
} : undefined,
hoverProvider: true,
documentSymbolProvider: true,
documentRangeFormattingProvider: params.initializationOptions.provideFormatter === true,
colorProvider: {},
foldingRangeProvider: true,
selectionRangeProvider: true,
definitionProvider: true
};
return { capabilities };
});
// The settings interface describes the server relevant settings part
interface Settings {
json: {
schemas: JSONSchemaSettings[];
format: { enable: boolean; };
resultLimit?: number;
};
http: {
proxy: string;
proxyStrictSSL: boolean;
};
}
interface JSONSchemaSettings {
fileMatch?: string[];
url?: string;
schema?: JSONSchema;
}
namespace LimitExceededWarnings {
const pendingWarnings: { [uri: string]: { features: { [name: string]: string }; timeout?: NodeJS.Timeout; } } = {};
export function cancel(uri: string) {
const warning = pendingWarnings[uri];
if (warning && warning.timeout) {
clearTimeout(warning.timeout);
delete pendingWarnings[uri];
}
}
export function onResultLimitExceeded(uri: string, resultLimit: number, name: string) {
return () => {
let warning = pendingWarnings[uri];
if (warning) {
if (!warning.timeout) {
// already shown
return;
}
warning.features[name] = name;
warning.timeout.refresh();
} else {
warning = { features: { [name]: name } };
warning.timeout = setTimeout(() => {
connection.sendNotification(ResultLimitReachedNotification.type, `${posix.basename(uri)}: For performance reasons, ${Object.keys(warning.features).join(' and ')} have been limited to ${resultLimit} items.`);
warning.timeout = undefined;
}, 2000);
pendingWarnings[uri] = warning;
}
};
}
}
let jsonConfigurationSettings: JSONSchemaSettings[] | undefined = undefined;
let schemaAssociations: ISchemaAssociations | ISchemaAssociation[] | undefined = undefined;
let formatterRegistration: Thenable<Disposable> | null = null;
// The settings have changed. Is send on server activation as well.
connection.onDidChangeConfiguration((change) => {
let settings = <Settings>change.settings;
configureHttpRequests(settings.http && settings.http.proxy, settings.http && settings.http.proxyStrictSSL);
jsonConfigurationSettings = settings.json && settings.json.schemas;
updateConfiguration();
foldingRangeLimit = Math.trunc(Math.max(settings.json && settings.json.resultLimit || foldingRangeLimitDefault, 0));
resultLimit = Math.trunc(Math.max(settings.json && settings.json.resultLimit || Number.MAX_VALUE, 0));
// dynamically enable & disable the formatter
if (dynamicFormatterRegistration) {
const enableFormatter = settings && settings.json && settings.json.format && settings.json.format.enable;
if (enableFormatter) {
if (!formatterRegistration) {
formatterRegistration = connection.client.register(DocumentRangeFormattingRequest.type, { documentSelector: [{ language: 'json' }, { language: 'jsonc' }] });
}
} else if (formatterRegistration) {
formatterRegistration.then(r => r.dispose());
formatterRegistration = null;
}
}
});
// The jsonValidation extension configuration has changed
connection.onNotification(SchemaAssociationNotification.type, associations => {
schemaAssociations = associations;
updateConfiguration();
});
// A schema has changed
connection.onNotification(SchemaContentChangeNotification.type, uri => {
languageService.resetSchema(uri);
});
// Retry schema validation on all open documents
connection.onRequest(ForceValidateRequest.type, uri => {
return new Promise<Diagnostic[]>(resolve => {
const document = documents.get(uri);
if (document) {
updateConfiguration();
validateTextDocument(document, diagnostics => {
resolve(diagnostics);
});
} else {
resolve([]);
}
});
});
function updateConfiguration() {
const languageSettings = {
validate: true,
allowComments: true,
schemas: new Array<SchemaConfiguration>()
};
if (schemaAssociations) {
if (Array.isArray(schemaAssociations)) {
Array.prototype.push.apply(languageSettings.schemas, schemaAssociations);
} else {
for (const pattern in schemaAssociations) {
const association = schemaAssociations[pattern];
if (Array.isArray(association)) {
association.forEach(uri => {
languageSettings.schemas.push({ uri, fileMatch: [pattern] });
});
}
}
}
}
if (jsonConfigurationSettings) {
jsonConfigurationSettings.forEach((schema, index) => {
let uri = schema.url;
if (!uri && schema.schema) {
uri = schema.schema.id || `vscode://schemas/custom/${index}`;
}
if (uri) {
languageSettings.schemas.push({ uri, fileMatch: schema.fileMatch, schema: schema.schema });
}
});
}
languageService.configure(languageSettings);
// Revalidate any open text documents
documents.all().forEach(triggerValidation);
}
// The content of a text document has changed. This event is emitted
// when the text document first opened or when its content has changed.
documents.onDidChangeContent((change) => {
LimitExceededWarnings.cancel(change.document.uri);
triggerValidation(change.document);
});
// a document has closed: clear all diagnostics
documents.onDidClose(event => {
LimitExceededWarnings.cancel(event.document.uri);
cleanPendingValidation(event.document);
connection.sendDiagnostics({ uri: event.document.uri, diagnostics: [] });
});
const pendingValidationRequests: { [uri: string]: NodeJS.Timer; } = {};
const validationDelayMs = 300;
function cleanPendingValidation(textDocument: TextDocument): void {
const request = pendingValidationRequests[textDocument.uri];
if (request) {
clearTimeout(request);
delete pendingValidationRequests[textDocument.uri];
}
}
function triggerValidation(textDocument: TextDocument): void {
cleanPendingValidation(textDocument);
pendingValidationRequests[textDocument.uri] = setTimeout(() => {
delete pendingValidationRequests[textDocument.uri];
validateTextDocument(textDocument);
}, validationDelayMs);
}
function validateTextDocument(textDocument: TextDocument, callback?: (diagnostics: Diagnostic[]) => void): void {
const respond = (diagnostics: Diagnostic[]) => {
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
if (callback) {
callback(diagnostics);
}
};
if (textDocument.getText().length === 0) {
respond([]); // ignore empty documents
return;
}
const jsonDocument = getJSONDocument(textDocument);
const version = textDocument.version;
const documentSettings: DocumentLanguageSettings = textDocument.languageId === 'jsonc' ? { comments: 'ignore', trailingCommas: 'warning' } : { comments: 'error', trailingCommas: 'error' };
languageService.doValidation(textDocument, jsonDocument, documentSettings).then(diagnostics => {
setImmediate(() => {
const currDocument = documents.get(textDocument.uri);
if (currDocument && currDocument.version === version) {
respond(diagnostics); // Send the computed diagnostics to VSCode.
}
});
}, error => {
connection.console.error(formatError(`Error while validating ${textDocument.uri}`, error));
});
}
connection.onDidChangeWatchedFiles((change) => {
// Monitored files have changed in VSCode
let hasChanges = false;
change.changes.forEach(c => {
if (languageService.resetSchema(c.uri)) {
hasChanges = true;
}
});
if (hasChanges) {
documents.all().forEach(triggerValidation);
}
});
const jsonDocuments = getLanguageModelCache<JSONDocument>(10, 60, document => languageService.parseJSONDocument(document));
documents.onDidClose(e => {
jsonDocuments.onDocumentRemoved(e.document);
});
connection.onShutdown(() => {
jsonDocuments.dispose();
});
function getJSONDocument(document: TextDocument): JSONDocument {
return jsonDocuments.get(document);
}
connection.onCompletion((textDocumentPosition, token) => {
return runSafeAsync(async () => {
const document = documents.get(textDocumentPosition.textDocument.uri);
if (document) {
const jsonDocument = getJSONDocument(document);
return languageService.doComplete(document, textDocumentPosition.position, jsonDocument);
}
return null;
}, null, `Error while computing completions for ${textDocumentPosition.textDocument.uri}`, token);
});
connection.onCompletionResolve((completionItem, token) => {
return runSafeAsync(() => {
return languageService.doResolve(completionItem);
}, completionItem, `Error while resolving completion proposal`, token);
});
connection.onHover((textDocumentPositionParams, token) => {
return runSafeAsync(async () => {
const document = documents.get(textDocumentPositionParams.textDocument.uri);
if (document) {
const jsonDocument = getJSONDocument(document);
return languageService.doHover(document, textDocumentPositionParams.position, jsonDocument);
}
return null;
}, null, `Error while computing hover for ${textDocumentPositionParams.textDocument.uri}`, token);
});
connection.onDocumentSymbol((documentSymbolParams, token) => {
return runSafe(() => {
const document = documents.get(documentSymbolParams.textDocument.uri);
if (document) {
const jsonDocument = getJSONDocument(document);
const onResultLimitExceeded = LimitExceededWarnings.onResultLimitExceeded(document.uri, resultLimit, 'document symbols');
if (hierarchicalDocumentSymbolSupport) {
return languageService.findDocumentSymbols2(document, jsonDocument, { resultLimit, onResultLimitExceeded });
} else {
return languageService.findDocumentSymbols(document, jsonDocument, { resultLimit, onResultLimitExceeded });
}
}
return [];
}, [], `Error while computing document symbols for ${documentSymbolParams.textDocument.uri}`, token);
});
connection.onDocumentRangeFormatting((formatParams, token) => {
return runSafe(() => {
const document = documents.get(formatParams.textDocument.uri);
if (document) {
const edits = languageService.format(document, formatParams.range, formatParams.options);
if (edits.length > formatterMaxNumberOfEdits) {
const newText = TextDocument.applyEdits(document, edits);
return [TextEdit.replace(Range.create(Position.create(0, 0), document.positionAt(document.getText().length)), newText)];
}
return edits;
}
return [];
}, [], `Error while formatting range for ${formatParams.textDocument.uri}`, token);
});
connection.onDocumentColor((params, token) => {
return runSafeAsync(async () => {
const document = documents.get(params.textDocument.uri);
if (document) {
const onResultLimitExceeded = LimitExceededWarnings.onResultLimitExceeded(document.uri, resultLimit, 'document colors');
const jsonDocument = getJSONDocument(document);
return languageService.findDocumentColors(document, jsonDocument, { resultLimit, onResultLimitExceeded });
}
return [];
}, [], `Error while computing document colors for ${params.textDocument.uri}`, token);
});
connection.onColorPresentation((params, token) => {
return runSafe(() => {
const document = documents.get(params.textDocument.uri);
if (document) {
const jsonDocument = getJSONDocument(document);
return languageService.getColorPresentations(document, jsonDocument, params.color, params.range);
}
return [];
}, [], `Error while computing color presentations for ${params.textDocument.uri}`, token);
});
connection.onFoldingRanges((params, token) => {
return runSafe(() => {
const document = documents.get(params.textDocument.uri);
if (document) {
const onRangeLimitExceeded = LimitExceededWarnings.onResultLimitExceeded(document.uri, foldingRangeLimit, 'folding ranges');
return languageService.getFoldingRanges(document, { rangeLimit: foldingRangeLimit, onRangeLimitExceeded });
}
return null;
}, null, `Error while computing folding ranges for ${params.textDocument.uri}`, token);
});
connection.onSelectionRanges((params, token) => {
return runSafe(() => {
const document = documents.get(params.textDocument.uri);
if (document) {
const jsonDocument = getJSONDocument(document);
return languageService.getSelectionRanges(document, params.positions, jsonDocument);
}
return [];
}, [], `Error while computing selection ranges for ${params.textDocument.uri}`, token);
});
connection.onDefinition((params, token) => {
return runSafeAsync(async () => {
const document = documents.get(params.textDocument.uri);
if (document) {
const jsonDocument = getJSONDocument(document);
return languageService.findDefinition(document, params.position, jsonDocument);
}
return [];
}, [], `Error while computing definitions for ${params.textDocument.uri}`, token);
});
// Listen on the connection
connection.listen();

Просмотреть файл

@ -0,0 +1,55 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { createConnection, Connection } from 'vscode-languageserver/node';
import { formatError } from '../utils/runner';
import { startServer } from '../jsonServer';
import { RequestService } from '../requests';
import { xhr, XHRResponse, configure as configureHttpRequests, getErrorStatusDescription } from 'request-light';
import { URI as Uri } from 'vscode-uri';
import * as fs from 'fs';
// Create a connection for the server.
const connection: Connection = createConnection();
console.log = connection.console.log.bind(connection.console);
console.error = connection.console.error.bind(connection.console);
process.on('unhandledRejection', (e: any) => {
connection.console.error(formatError(`Unhandled exception`, e));
});
function getHTTPRequestService(): RequestService {
return {
getContent(uri: string, _encoding?: string) {
const headers = { 'Accept-Encoding': 'gzip, deflate' };
return xhr({ url: uri, followRedirects: 5, headers }).then(response => {
return response.responseText;
}, (error: XHRResponse) => {
return Promise.reject(error.responseText || getErrorStatusDescription(error.status) || error.toString());
});
}
};
}
function getFileRequestService(): RequestService {
return {
getContent(location: string, encoding?: string) {
return new Promise((c, e) => {
const uri = Uri.parse(location);
fs.readFile(uri.fsPath, encoding, (err, buf) => {
if (err) {
return e(err);
}
c(buf.toString());
});
});
}
};
}
startServer(connection, { file: getFileRequestService(), http: getHTTPRequestService(), configureHttpRequests });

Просмотреть файл

@ -0,0 +1,87 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { URI } from 'vscode-uri';
export interface RequestService {
getContent(uri: string, encoding?: string): Promise<string>;
}
export function getScheme(uri: string) {
return uri.substr(0, uri.indexOf(':'));
}
export function dirname(uri: string) {
const lastIndexOfSlash = uri.lastIndexOf('/');
return lastIndexOfSlash !== -1 ? uri.substr(0, lastIndexOfSlash) : '';
}
export function basename(uri: string) {
const lastIndexOfSlash = uri.lastIndexOf('/');
return uri.substr(lastIndexOfSlash + 1);
}
const Slash = '/'.charCodeAt(0);
const Dot = '.'.charCodeAt(0);
export function extname(uri: string) {
for (let i = uri.length - 1; i >= 0; i--) {
const ch = uri.charCodeAt(i);
if (ch === Dot) {
if (i > 0 && uri.charCodeAt(i - 1) !== Slash) {
return uri.substr(i);
} else {
break;
}
} else if (ch === Slash) {
break;
}
}
return '';
}
export function isAbsolutePath(path: string) {
return path.charCodeAt(0) === Slash;
}
export function resolvePath(uriString: string, path: string): string {
if (isAbsolutePath(path)) {
const uri = URI.parse(uriString);
const parts = path.split('/');
return uri.with({ path: normalizePath(parts) }).toString();
}
return joinPath(uriString, path);
}
export function normalizePath(parts: string[]): string {
const newParts: string[] = [];
for (const part of parts) {
if (part.length === 0 || part.length === 1 && part.charCodeAt(0) === Dot) {
// ignore
} else if (part.length === 2 && part.charCodeAt(0) === Dot && part.charCodeAt(1) === Dot) {
newParts.pop();
} else {
newParts.push(part);
}
}
if (parts.length > 1 && parts[parts.length - 1].length === 0) {
newParts.push('');
}
let res = newParts.join('/');
if (parts[0].length === 0) {
res = '/' + res;
}
return res;
}
export function joinPath(uriString: string, ...paths: string[]): string {
const uri = URI.parse(uriString);
const parts = uri.path.split('/');
for (let path of paths) {
parts.push(...path.split('/'));
}
return uri.with({ path: normalizePath(parts) }).toString();
}

Просмотреть файл

@ -80,46 +80,51 @@ request-light@^0.3.0:
https-proxy-agent "^2.2.4"
vscode-nls "^4.1.1"
vscode-json-languageservice@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.6.0.tgz#133a1e2c3a3dffe38564a1ba948516805c3c1869"
integrity sha512-dXzFywypUZ9T0tjr4fREZiknXDz6vAGx1zsxbQY1+9DOpjMfbz0VLP873KmcbuvL4K3nseKTxc4TKHu8kLXRMw==
vscode-json-languageservice@^3.7.0:
version "3.7.0"
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.7.0.tgz#0174417f139cf41dd60c84538fd052385bfb46f6"
integrity sha512-nGLqcBhTjdfkl8Dz9sYGK/ZCTjscYFoIjYw+qqkWB+vyNfM0k/AyIoT73DQvB/PArteCKjEVfQUF72GRZEDSbQ==
dependencies:
jsonc-parser "^2.2.1"
vscode-languageserver-textdocument "^1.0.1"
vscode-languageserver-types "^3.15.1"
vscode-nls "^4.1.2"
vscode-uri "^2.1.1"
vscode-uri "^2.1.2"
vscode-jsonrpc@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-5.0.1.tgz#9bab9c330d89f43fc8c1e8702b5c36e058a01794"
integrity sha512-JvONPptw3GAQGXlVV2utDcHx0BiY34FupW/kI6mZ5x06ER5DdPG/tXWMVHjTNULF5uKPOUUD0SaXg5QaubJL0A==
vscode-jsonrpc@6.0.0-next.2:
version "6.0.0-next.2"
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0-next.2.tgz#3d73f86d812304cb91b9fb1efee40ec60b09ed7f"
integrity sha512-dKQXRYNUY6BHALQJBJlyZyv9oWlYpbJ2vVoQNNVNPLAYQ3hzNp4zy+iSo7zGx1BPXByArJQDWTKLQh8dz3dnNw==
vscode-languageserver-protocol@^3.15.3:
version "3.15.3"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.3.tgz#3fa9a0702d742cf7883cb6182a6212fcd0a1d8bb"
integrity sha512-zrMuwHOAQRhjDSnflWdJG+O2ztMWss8GqUUB8dXLR/FPenwkiBNkMIJJYfSN6sgskvsF0rHAoBowNQfbyZnnvw==
vscode-languageserver-protocol@3.16.0-next.4:
version "3.16.0-next.4"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0-next.4.tgz#8f8b1b831d4dfd9b26aa1ba3d2a32c427a91c99f"
integrity sha512-6GmPUp2MhJy2H1CTWp2B40Pa9BeC9glrXWmQWVG6A/0V9UbcAjVC9m56znm2GL32iyLDIprTBe8gBvvvcjbpaQ==
dependencies:
vscode-jsonrpc "^5.0.1"
vscode-languageserver-types "3.15.1"
vscode-jsonrpc "6.0.0-next.2"
vscode-languageserver-types "3.16.0-next.2"
vscode-languageserver-textdocument@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz#178168e87efad6171b372add1dea34f53e5d330f"
integrity sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==
vscode-languageserver-types@3.15.1, vscode-languageserver-types@^3.15.1:
vscode-languageserver-types@3.16.0-next.2:
version "3.16.0-next.2"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0-next.2.tgz#940bd15c992295a65eae8ab6b8568a1e8daa3083"
integrity sha512-QjXB7CKIfFzKbiCJC4OWC8xUncLsxo19FzGVp/ADFvvi87PlmBSCAtZI5xwGjF5qE0xkLf0jjKUn3DzmpDP52Q==
vscode-languageserver-types@^3.15.1:
version "3.15.1"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz#17be71d78d2f6236d414f0001ce1ef4d23e6b6de"
integrity sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==
vscode-languageserver@^6.1.1:
version "6.1.1"
resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-6.1.1.tgz#d76afc68172c27d4327ee74332b468fbc740d762"
integrity sha512-DueEpkUAkD5XTR4MLYNr6bQIp/UFR0/IPApgXU3YfCBCB08u2sm9hRCs6DxYZELkk++STPjpcjksR2H8qI3cDQ==
vscode-languageserver@7.0.0-next.3:
version "7.0.0-next.3"
resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-7.0.0-next.3.tgz#3833bd09259a4a085baeba90783f1e4d06d81095"
integrity sha512-qSt8eb546iFuoFIN+9MPl4Avru6Iz2/JP0UmS/3djf40ICa31Np/yJ7anX2j0Az5rCzb0fak8oeKwDioGeVOYg==
dependencies:
vscode-languageserver-protocol "^3.15.3"
vscode-languageserver-protocol "3.16.0-next.4"
vscode-nls@^4.1.1:
version "4.1.1"
@ -131,7 +136,7 @@ vscode-nls@^4.1.2:
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.1.2.tgz#ca8bf8bb82a0987b32801f9fddfdd2fb9fd3c167"
integrity sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==
vscode-uri@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.1.1.tgz#5aa1803391b6ebdd17d047f51365cf62c38f6e90"
integrity sha512-eY9jmGoEnVf8VE8xr5znSah7Qt1P/xsCdErz+g8HYZtJ7bZqKH5E3d+6oVNm1AC/c6IHUDokbmVXKOi4qPAC9A==
vscode-uri@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.1.2.tgz#c8d40de93eb57af31f3c715dd650e2ca2c096f1c"
integrity sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==

Просмотреть файл

@ -120,31 +120,31 @@ vscode-extension-telemetry@0.1.1:
dependencies:
applicationinsights "1.0.8"
vscode-jsonrpc@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-5.0.1.tgz#9bab9c330d89f43fc8c1e8702b5c36e058a01794"
integrity sha512-JvONPptw3GAQGXlVV2utDcHx0BiY34FupW/kI6mZ5x06ER5DdPG/tXWMVHjTNULF5uKPOUUD0SaXg5QaubJL0A==
vscode-jsonrpc@6.0.0-next.2:
version "6.0.0-next.2"
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0-next.2.tgz#3d73f86d812304cb91b9fb1efee40ec60b09ed7f"
integrity sha512-dKQXRYNUY6BHALQJBJlyZyv9oWlYpbJ2vVoQNNVNPLAYQ3hzNp4zy+iSo7zGx1BPXByArJQDWTKLQh8dz3dnNw==
vscode-languageclient@^6.1.3:
version "6.1.3"
resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-6.1.3.tgz#c979c5bb5855714a0307e998c18ca827c1b3953a"
integrity sha512-YciJxk08iU5LmWu7j5dUt9/1OLjokKET6rME3cI4BRpiF6HZlusm2ZwPt0MYJ0lV5y43sZsQHhyon2xBg4ZJVA==
vscode-languageclient@7.0.0-next.5:
version "7.0.0-next.5"
resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-7.0.0-next.5.tgz#7ae84c598dff360bd2bc64322b74e10e5d0b9cd6"
integrity sha512-ec+fJg+JiNBIdbeKbzssSuORUaVdtLValtiYdNEUCUjpYE+Y6xXPtXwiZOlS/0OB9pC/RLCMxsj16UwWncQhYQ==
dependencies:
semver "^6.3.0"
vscode-languageserver-protocol "^3.15.3"
vscode-languageserver-protocol "3.16.0-next.4"
vscode-languageserver-protocol@^3.15.3:
version "3.15.3"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.3.tgz#3fa9a0702d742cf7883cb6182a6212fcd0a1d8bb"
integrity sha512-zrMuwHOAQRhjDSnflWdJG+O2ztMWss8GqUUB8dXLR/FPenwkiBNkMIJJYfSN6sgskvsF0rHAoBowNQfbyZnnvw==
vscode-languageserver-protocol@3.16.0-next.4:
version "3.16.0-next.4"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0-next.4.tgz#8f8b1b831d4dfd9b26aa1ba3d2a32c427a91c99f"
integrity sha512-6GmPUp2MhJy2H1CTWp2B40Pa9BeC9glrXWmQWVG6A/0V9UbcAjVC9m56znm2GL32iyLDIprTBe8gBvvvcjbpaQ==
dependencies:
vscode-jsonrpc "^5.0.1"
vscode-languageserver-types "3.15.1"
vscode-jsonrpc "6.0.0-next.2"
vscode-languageserver-types "3.16.0-next.2"
vscode-languageserver-types@3.15.1:
version "3.15.1"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz#17be71d78d2f6236d414f0001ce1ef4d23e6b6de"
integrity sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ==
vscode-languageserver-types@3.16.0-next.2:
version "3.16.0-next.2"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0-next.2.tgz#940bd15c992295a65eae8ab6b8568a1e8daa3083"
integrity sha512-QjXB7CKIfFzKbiCJC4OWC8xUncLsxo19FzGVp/ADFvvi87PlmBSCAtZI5xwGjF5qE0xkLf0jjKUn3DzmpDP52Q==
vscode-nls@^4.1.1:
version "4.1.1"

Просмотреть файл

@ -91,7 +91,8 @@ function createContext(): TestContext {
globalStoragePath: '',
logPath: '',
extensionUri: vscode.Uri.parse(''),
environmentVariableCollection: { } as any
environmentVariableCollection: { } as any,
extensionMode: undefined as any
},
outputChannel: {
name: '',

Просмотреть файл

@ -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/microsoft/vscode-markdown-tm-grammar/commit/7cf9aa7bb76c55428063383610edc0a631230d58",
"version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/a7e4475626a505472c76d18e0a1b3cfcf46f9cf9",
"name": "Markdown",
"scopeName": "text.html.markdown",
"patterns": [
@ -1715,6 +1715,72 @@
}
]
},
"fenced_code_block_erlang": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(erlang)((\\s+|:|\\{)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
"3": {
"name": "punctuation.definition.markdown"
},
"4": {
"name": "fenced_code.block.language.markdown"
},
"5": {
"name": "fenced_code.block.language.attributes.markdown"
}
},
"endCaptures": {
"3": {
"name": "punctuation.definition.markdown"
}
},
"patterns": [
{
"begin": "(^|\\G)(\\s*)(.*)",
"while": "(^|\\G)(?!\\s*([`~]{3,})\\s*$)",
"contentName": "meta.embedded.block.erlang",
"patterns": [
{
"include": "source.erlang"
}
]
}
]
},
"fenced_code_block_elixir": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(elixir)((\\s+|:|\\{)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
"3": {
"name": "punctuation.definition.markdown"
},
"4": {
"name": "fenced_code.block.language.markdown"
},
"5": {
"name": "fenced_code.block.language.attributes.markdown"
}
},
"endCaptures": {
"3": {
"name": "punctuation.definition.markdown"
}
},
"patterns": [
{
"begin": "(^|\\G)(\\s*)(.*)",
"while": "(^|\\G)(?!\\s*([`~]{3,})\\s*$)",
"contentName": "meta.embedded.block.elixir",
"patterns": [
{
"include": "source.elixir"
}
]
}
]
},
"fenced_code_block": {
"patterns": [
{
@ -1867,6 +1933,12 @@
{
"include": "#fenced_code_block_log"
},
{
"include": "#fenced_code_block_erlang"
},
{
"include": "#fenced_code_block_elixir"
},
{
"include": "#fenced_code_block_unknown"
}

Просмотреть файл

@ -4,6 +4,7 @@ tsconfig.json
out/test/**
out/**
extension.webpack.config.js
extension-browser.webpack.config.js
cgmanifest.json
yarn.lock
preview-src/**

Просмотреть файл

@ -0,0 +1,32 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
//@ts-check
'use strict';
const withDefaults = require('../shared.webpack.config');
const path = require('path');
const clientConfig = withDefaults({
context: __dirname,
target: 'webworker',
entry: {
extension: './src/extension.ts'
},
resolve: {
alias: {
'vscode-extension-telemetry': path.resolve(__dirname, '../../build/polyfills/vscode-extension-telemetry.js'),
'vscode-nls': path.resolve(__dirname, '../../build/polyfills/vscode-nls.js'),
},
},
performance: {
hints: false
},
});
clientConfig.module.rules[0].use.shift(); // remove nls loader
module.exports = clientConfig;

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
html, body {
font-family: var(--markdown-font-family, system-ui, -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", "Ubuntu", "Droid Sans", sans-serif);
font-family: var(--markdown-font-family, -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", system-ui, "Ubuntu", "Droid Sans", sans-serif);
font-size: var(--markdown-font-size, 14px);
padding: 0 26px;
line-height: var(--markdown-line-height, 22px);
@ -157,7 +157,7 @@ blockquote {
}
code {
font-family: var(--vscode-editor-font-family, Menlo, Monaco, Consolas, "Droid Sans Mono", "Courier New", monospace, "Droid Sans Fallback");
font-family: var(--vscode-editor-font-family, "SF Mono", Monaco, Menlo, Consolas, "Ubuntu Mono", "Liberation Mono", "DejaVu Sans Mono", "Courier New", monospace);
font-size: 1em;
line-height: 1.357em;
}

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -1,4 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.219 8.35484C11.6063 8.12309 12.049 8.00047 12.5003 8C12.8904 7.99939 13.2753 8.0901 13.6241 8.26486C13.9729 8.43963 14.276 8.6936 14.5091 9.00646C14.7421 9.31933 14.8987 9.6824 14.9664 10.0666C15.034 10.4509 15.0108 10.8456 14.8985 11.2192C14.7863 11.5929 14.5882 11.9351 14.32 12.2184C14.0518 12.5018 13.7211 12.7185 13.3542 12.8511C12.9873 12.9837 12.5944 13.0287 12.207 12.9823C11.8197 12.9359 11.4485 12.7995 11.1233 12.584L8.7683 14.9399L8.06055 14.2322L10.4163 11.877C10.1677 11.5003 10.0258 11.0634 10.0054 10.6126C9.98511 10.1618 10.0872 9.71384 10.3009 9.31634C10.5145 8.91885 10.8318 8.58659 11.219 8.35484ZM11.667 11.7472C11.9136 11.912 12.2036 12 12.5003 12C12.8981 12 13.2797 11.842 13.561 11.5607C13.8423 11.2794 14.0003 10.8978 14.0003 10.5C14.0003 10.2033 13.9123 9.91332 13.7475 9.66665C13.5827 9.41997 13.3484 9.22772 13.0743 9.11418C12.8002 9.00065 12.4986 8.97095 12.2077 9.02883C11.9167 9.0867 11.6494 9.22956 11.4396 9.43934C11.2299 9.64912 11.087 9.9164 11.0291 10.2074C10.9712 10.4983 11.001 10.7999 11.1145 11.074C11.228 11.3481 11.4203 11.5824 11.667 11.7472Z" fill="#C5C5C5"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M13 1L14 2V7.33573C13.6829 7.18584 13.3457 7.08481 13 7.03533V2L8 2L8 12.8787L6.87837 14H2L1 13V2L2 1H13ZM9.70794 14H9.70785L10 13.7077V13.7079L9.70794 14ZM13 10.5174C13.0002 10.5116 13.0003 10.5058 13.0003 10.5C13.0003 10.4942 13.0002 10.4884 13 10.4826V10.5174ZM2 2L7 2L7 13H2L2 2Z" fill="#C5C5C5"/>
</svg>

До

Ширина:  |  Высота:  |  Размер: 1.6 KiB

Просмотреть файл

@ -1,4 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.219 8.35484C11.6063 8.12309 12.049 8.00047 12.5003 8C12.8904 7.99939 13.2753 8.0901 13.6241 8.26486C13.9729 8.43963 14.276 8.6936 14.5091 9.00646C14.7421 9.31933 14.8987 9.6824 14.9664 10.0666C15.034 10.4509 15.0108 10.8456 14.8985 11.2192C14.7863 11.5929 14.5882 11.9351 14.32 12.2184C14.0518 12.5018 13.7211 12.7185 13.3542 12.8511C12.9873 12.9837 12.5944 13.0287 12.207 12.9823C11.8197 12.9359 11.4485 12.7995 11.1233 12.584L8.7683 14.9399L8.06055 14.2322L10.4163 11.877C10.1677 11.5003 10.0258 11.0634 10.0054 10.6126C9.98511 10.1618 10.0872 9.71384 10.3009 9.31634C10.5145 8.91885 10.8318 8.58659 11.219 8.35484ZM11.667 11.7472C11.9136 11.912 12.2036 12 12.5003 12C12.8981 12 13.2797 11.842 13.561 11.5607C13.8423 11.2794 14.0003 10.8978 14.0003 10.5C14.0003 10.2033 13.9123 9.91332 13.7475 9.66665C13.5827 9.41997 13.3484 9.22772 13.0743 9.11418C12.8002 9.00065 12.4986 8.97095 12.2077 9.02883C11.9167 9.0867 11.6494 9.22956 11.4396 9.43934C11.2299 9.64912 11.087 9.9164 11.0291 10.2074C10.9712 10.4983 11.001 10.7999 11.1145 11.074C11.228 11.3481 11.4203 11.5824 11.667 11.7472Z" fill="#424242"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M13 1L14 2V7.33573C13.6829 7.18584 13.3457 7.08481 13 7.03533V2L8 2L8 12.8787L6.87837 14H2L1 13V2L2 1H13ZM9.70794 14H9.70785L10 13.7077V13.7079L9.70794 14ZM13 10.5174C13.0002 10.5116 13.0003 10.5058 13.0003 10.5C13.0003 10.4942 13.0002 10.4884 13 10.4826V10.5174ZM2 2L7 2L7 13H2L2 2Z" fill="#424242"/>
</svg>

До

Ширина:  |  Высота:  |  Размер: 1.6 KiB

Просмотреть файл

@ -1,3 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.06065 3.85356L5.91421 6L5.2071 5.29289L6.49999 4H3.5C3.10218 4 2.72064 4.15804 2.43934 4.43934C2.15804 4.72065 2 5.10218 2 5.5C2 5.89783 2.15804 6.27936 2.43934 6.56066C2.72064 6.84197 3.10218 7 3.5 7H4V8H3.5C2.83696 8 2.20107 7.73661 1.73223 7.26777C1.26339 6.79893 1 6.16305 1 5.5C1 4.83696 1.26339 4.20108 1.73223 3.73224C2.20107 3.2634 2.83696 3 3.5 3H6.49999L6.49999 3H6.49996L6 2.50004V2.50001L5.2071 1.70711L5.91421 1L8.06065 3.14645L8.06065 3.85356ZM5 6.50003L5.91421 7.41424L6 7.32845V14H14V7H10V3H9.06065V2.73227L8.32838 2H11.2L11.5 2.1L14.9 5.6L15 6V14.5L14.5 15H5.5L5 14.5V9.00003V6.50003ZM11 3V6H13.9032L11 3Z" fill="#C5C5C5"/>
</svg>

До

Ширина:  |  Высота:  |  Размер: 796 B

Просмотреть файл

@ -1,3 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.06065 3.85356L5.91421 6L5.2071 5.29289L6.49999 4H3.5C3.10218 4 2.72064 4.15804 2.43934 4.43934C2.15804 4.72065 2 5.10218 2 5.5C2 5.89783 2.15804 6.27936 2.43934 6.56066C2.72064 6.84197 3.10218 7 3.5 7H4V8H3.5C2.83696 8 2.20107 7.73661 1.73223 7.26777C1.26339 6.79893 1 6.16305 1 5.5C1 4.83696 1.26339 4.20108 1.73223 3.73224C2.20107 3.2634 2.83696 3 3.5 3H6.49999L6.49999 3H6.49996L6 2.50004V2.50001L5.2071 1.70711L5.91421 1L8.06065 3.14645L8.06065 3.85356ZM5 6.50003L5.91421 7.41424L6 7.32845V14H14V7H10V3H9.06065V2.73227L8.32838 2H11.2L11.5 2.1L14.9 5.6L15 6V14.5L14.5 15H5.5L5 14.5V9.00003V6.50003ZM11 3V6H13.9032L11 3Z" fill="#424242"/>
</svg>

До

Ширина:  |  Высота:  |  Размер: 796 B

Просмотреть файл

@ -12,6 +12,7 @@
"vscode": "^1.20.0"
},
"main": "./out/extension",
"browser": "./dist/extension.js",
"categories": [
"Programming Languages"
],
@ -44,28 +45,19 @@
"command": "markdown.showPreviewToSide",
"title": "%markdown.previewSide.title%",
"category": "Markdown",
"icon": {
"light": "./media/preview-right-light.svg",
"dark": "./media/preview-right-dark.svg"
}
"icon": "$(open-preview)"
},
{
"command": "markdown.showLockedPreviewToSide",
"title": "%markdown.showLockedPreviewToSide.title%",
"category": "Markdown",
"icon": {
"light": "./media/preview-right-light.svg",
"dark": "./media/preview-right-dark.svg"
}
"icon": "$(open-preview)"
},
{
"command": "markdown.showSource",
"title": "%markdown.showSource.title%",
"category": "Markdown",
"icon": {
"light": "./media/view-source-light.svg",
"dark": "./media/view-source-dark.svg"
}
"icon": "$(go-to-file)"
},
{
"command": "markdown.showPreviewSecuritySelector",
@ -211,7 +203,7 @@
},
"markdown.preview.fontFamily": {
"type": "string",
"default": "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe WPC', 'Segoe UI', 'Ubuntu', 'Droid Sans', sans-serif",
"default": "-apple-system, BlinkMacSystemFont, 'Segoe WPC', 'Segoe UI', system-ui, 'Ubuntu', 'Droid Sans', sans-serif",
"description": "%markdown.preview.fontFamily.desc%",
"scope": "resource"
},
@ -328,7 +320,9 @@
"watch": "npm run build-preview && gulp watch-extension:markdown-language-features",
"vscode:prepublish": "npm run build-ext && npm run build-preview",
"build-ext": "node ../../node_modules/gulp/bin/gulp.js --gulpfile ../../build/gulpfile.extensions.js compile-extension:markdown-language-features ./tsconfig.json",
"build-preview": "webpack --mode production"
"build-preview": "webpack --mode production",
"compile-web": "npx webpack-cli --config extension-browser.webpack.config --mode none",
"watch-web": "npx webpack-cli --config extension-browser.webpack.config --mode none --watch --info-verbosity verbose"
},
"dependencies": {
"highlight.js": "9.15.10",

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше