mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-25 18:47:14 -05:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
49bf916346 | ||
|
|
ebd620bf7b | ||
|
|
79980d95e4 | ||
|
|
250d84923c |
9
.vscode/launch.json
vendored
9
.vscode/launch.json
vendored
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
|
|
||||||
{
|
{
|
||||||
"type": "node",
|
"type": "node",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
@@ -8,7 +9,7 @@
|
|||||||
"program": "${workspaceFolder}/node_modules/gulp/bin/gulp.js",
|
"program": "${workspaceFolder}/node_modules/gulp/bin/gulp.js",
|
||||||
"stopOnEntry": true,
|
"stopOnEntry": true,
|
||||||
"args": [
|
"args": [
|
||||||
"hygiene"
|
"watch-extension:json-client"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceFolder}"
|
"cwd": "${workspaceFolder}"
|
||||||
},
|
},
|
||||||
@@ -86,11 +87,7 @@
|
|||||||
"runtimeArgs": [
|
"runtimeArgs": [
|
||||||
"--inspect=5875"
|
"--inspect=5875"
|
||||||
],
|
],
|
||||||
"skipFiles": [
|
"webRoot": "${workspaceFolder}"
|
||||||
"**/winjs*.js"
|
|
||||||
],
|
|
||||||
"webRoot": "${workspaceFolder}",
|
|
||||||
"timeout": 15000
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "node",
|
"type": "node",
|
||||||
|
|||||||
8
.vscode/settings.json
vendored
8
.vscode/settings.json
vendored
@@ -10,9 +10,6 @@
|
|||||||
"when": "$(basename).ts"
|
"when": "$(basename).ts"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"files.associations": {
|
|
||||||
"OSSREADME.json": "jsonc"
|
|
||||||
},
|
|
||||||
"search.exclude": {
|
"search.exclude": {
|
||||||
"**/node_modules": true,
|
"**/node_modules": true,
|
||||||
"**/bower_components": true,
|
"**/bower_components": true,
|
||||||
@@ -38,5 +35,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"typescript.tsdk": "node_modules/typescript/lib"
|
"typescript.tsdk": "node_modules/typescript/lib",
|
||||||
}
|
"git.ignoreLimitWarning": true
|
||||||
|
}
|
||||||
2
.yarnrc
2
.yarnrc
@@ -1,3 +1,3 @@
|
|||||||
disturl "https://atom.io/download/electron"
|
disturl "https://atom.io/download/electron"
|
||||||
target "1.7.12"
|
target "1.7.11"
|
||||||
runtime "electron"
|
runtime "electron"
|
||||||
|
|||||||
54
CHANGELOG.md
54
CHANGELOG.md
@@ -1,43 +1,6 @@
|
|||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
## Version 0.28.6
|
## Version 0.26.4
|
||||||
* Release date: April 25, 2018
|
|
||||||
* Release status: Public Preview
|
|
||||||
|
|
||||||
## What's new in this version
|
|
||||||
The April Public Preview release contains some of the following highlights.
|
|
||||||
|
|
||||||
* Improvements to SQL Agent *Preview* extension
|
|
||||||
* Accessibility improvements for keyboard navigation, screen reader support and high-contrast mode.
|
|
||||||
* Improved large and protected file support for saving Admin protected and >256M files within SQL Ops Studio
|
|
||||||
* Integrated Terminal splitting to work with multiple open terminals at once
|
|
||||||
* Reduced installation on-disk file count foot print for faster installs and startup times
|
|
||||||
* Improvements to Server Reports extension
|
|
||||||
* Continue to fix GitHub issues
|
|
||||||
|
|
||||||
## Version 0.27.3
|
|
||||||
* Release date: March 28, 2017
|
|
||||||
* Release status: Public Preview
|
|
||||||
|
|
||||||
## What's new in this version
|
|
||||||
The March Public Preview release enables some key aspects of the SQL Operations
|
|
||||||
Studio extensibility story. Here are some highlights in this release.
|
|
||||||
|
|
||||||
* Enhance the Manage Dashboard extensibility model to support tabbed Insights and Configuration panes
|
|
||||||
* Dashboard Insights extensions for `sp_whoisactive` from [whoisactive.com](http://whoisactive.com)
|
|
||||||
* Extension Manager enables simple acquisition of 1st-party and 3rd-party extensions
|
|
||||||
* Add additional Extensibility APIs for `connection` and `objectexplorer` management
|
|
||||||
* Community Localization open for 10 languages
|
|
||||||
* Continue to fix important customer impacting GitHub issues
|
|
||||||
|
|
||||||
## Version 0.26.7
|
|
||||||
* Release date: February 16, 2017
|
|
||||||
* Release status: Public Preview Hotfix 1
|
|
||||||
|
|
||||||
## What's new in this version
|
|
||||||
* Bug fix for `#717 Selecting partial query and hitting Cmd or Ctrl+C opens terminal with Error message`
|
|
||||||
|
|
||||||
## Version 0.26.6
|
|
||||||
* Release date: February 15, 2017
|
* Release date: February 15, 2017
|
||||||
* Release status: Public Preview
|
* Release status: Public Preview
|
||||||
|
|
||||||
@@ -48,15 +11,16 @@ Here's some of the highlights in the February release.
|
|||||||
|
|
||||||
* Support Auto-Update installation on Windows and macOS
|
* Support Auto-Update installation on Windows and macOS
|
||||||
* Publish RPM and DEB packages to offical Microsoft repos
|
* Publish RPM and DEB packages to offical Microsoft repos
|
||||||
* Fix `#6 Keep connection and selected database when opening new query tabs`
|
* Fix #6 Keep connection and selected database when opening new query tabs
|
||||||
* Fix `#22 'Server Name' and 'Database Name' - Can these be drop downs instead of text` boxes?
|
* Fix #22 'Server Name' and 'Database Name' - Can these be drop downs instead of text boxes?
|
||||||
|
* Fix #549 Silent/Very Silent Install results in application opening after installation
|
||||||
* Fix #481 Add "Check for updates" option.
|
* Fix #481 Add "Check for updates" option.
|
||||||
* SQL Editor colorization and auto-completion fixes
|
* SQL Editor colorization and auto-completion fixes
|
||||||
* `#584 Keyword "FULL" not highlighted by IntelliSense`
|
* #584 Keyword "FULL" not highlighted by IntelliSense
|
||||||
* `#345 Colorize SQL functions within the editor`
|
* #345 Colorize SQL functions within the editor
|
||||||
* `#300 [#tempData] latest "]" will display green color`
|
* #300 [#tempData] latest "]" will display green color
|
||||||
* `#225 Keyword color mismatch`
|
* #225 Keyword color mismatch
|
||||||
* `#60 invalid sql syntax color highlighting when using temporary table in from clause`
|
* #60 invalid sql syntax color highlighting when using temporary table in from clause
|
||||||
* Introduce Connection extensibility API
|
* Introduce Connection extensibility API
|
||||||
* VS Code Editor 1.19 integration
|
* VS Code Editor 1.19 integration
|
||||||
* Update JustinPealing/html-query-plan component to pick-up several Query Plan viewer improvements
|
* Update JustinPealing/html-query-plan component to pick-up several Query Plan viewer improvements
|
||||||
|
|||||||
28
README.md
28
README.md
@@ -1,19 +1,17 @@
|
|||||||
# SQL Operations Studio
|
# SQL Operations Studio
|
||||||
|
|
||||||
[](https://gitter.im/Microsoft/sqlopsstudio?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
|
||||||
|
|
||||||
SQL Operations Studio is a data management tool that enables you to work with SQL Server, Azure SQL DB and SQL DW from Windows, macOS and Linux.
|
SQL Operations Studio is a data management tool that enables you to work with SQL Server, Azure SQL DB and SQL DW from Windows, macOS and Linux.
|
||||||
|
|
||||||
**Download SQL Operations Studio March Public Preview**
|
**Download SQL Operations Studio February Public Preview**
|
||||||
|
|
||||||
Platform | Link
|
Platform | Link
|
||||||
-- | --
|
-- | --
|
||||||
Windows Setup Installer | https://go.microsoft.com/fwlink/?linkid=872717
|
Windows Setup Installer | https://go.microsoft.com/fwlink/?linkid=866480
|
||||||
Windows ZIP | https://go.microsoft.com/fwlink/?linkid=872718
|
Windows ZIP | https://go.microsoft.com/fwlink/?linkid=866479
|
||||||
macOS ZIP | https://go.microsoft.com/fwlink/?linkid=872719
|
macOS ZIP | https://go.microsoft.com/fwlink/?linkid=866481
|
||||||
Linux TAR.GZ | https://go.microsoft.com/fwlink/?linkid=872720
|
Linux TAR.GZ | https://go.microsoft.com/fwlink/?linkid=866482
|
||||||
Linux DEB | https://go.microsoft.com/fwlink/?linkid=872722
|
Linux DEB | https://go.microsoft.com/fwlink/?linkid=866484
|
||||||
Linux RPM | https://go.microsoft.com/fwlink/?linkid=872721
|
Linux RPM | https://go.microsoft.com/fwlink/?linkid=866483
|
||||||
|
|
||||||
Go to our [download page](https://aka.ms/sqlopsstudio) for more specific instructions.
|
Go to our [download page](https://aka.ms/sqlopsstudio) for more specific instructions.
|
||||||
|
|
||||||
@@ -50,33 +48,23 @@ please see the document [How to Contribute](https://github.com/Microsoft/sqlopss
|
|||||||
|
|
||||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
||||||
|
|
||||||
## Localization
|
|
||||||
SQL Operations Studio localization is now open for community contributions. You can contribute to localization for both software and docs. https://aka.ms/SQLOpsStudioLoc
|
|
||||||
|
|
||||||
Localization is now opened for 10 languages: French, Italian, German, Spanish, Simplified Chinese, Traditional Chinese, Japanese, Korean, Russian, and Portuguese (Brazil). Help us make SQL Operations Studio available in your language!
|
|
||||||
|
|
||||||
## Privacy Statement
|
## Privacy Statement
|
||||||
The [Microsoft Enterprise and Developer Privacy Statement](https://privacy.microsoft.com/en-us/privacystatement) describes the privacy statement of this software.
|
The [Microsoft Enterprise and Developer Privacy Statement](https://privacy.microsoft.com/en-us/privacystatement) describes the privacy statement of this software.
|
||||||
|
|
||||||
## Contributions and "thank you"
|
## Contributions and "thank you"
|
||||||
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
|
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
|
||||||
|
|
||||||
* westerncj for `Removed duplicate contribution from README.md (#753)`
|
|
||||||
* ntovas for `Fix for duplicate extensions shown in "Save File" dialog. (#779)`
|
|
||||||
* SebastianPfliegel for `Add cursor snippet (#475)`
|
* SebastianPfliegel for `Add cursor snippet (#475)`
|
||||||
* mikaoelitiana for fix: `revert README and CONTRIBUTING after last VSCode merge (#574)`
|
* mikaoelitiana for fix: `revert README and CONTRIBUTING after last VSCode merge (#574)`
|
||||||
* alextercete for `Reinstate menu item to install from VSIX (#682)`
|
* alextercete for `Reinstate menu item to install from VSIX (#682)`
|
||||||
* alextercete for `Fix "No extension gallery service configured" error (#427)`
|
* alextercete for `Fix "No extension gallery service configured" error (#427)`
|
||||||
|
* SebastianPfliegel for `Add cursor snippet (#475)`
|
||||||
* mwiedemeyer for `Fix #58: Default sort order for DB size widget (#111)`
|
* mwiedemeyer for `Fix #58: Default sort order for DB size widget (#111)`
|
||||||
* AlexTroshkin for `Show disconnect in context menu only when connectionProfile connected (#150)`
|
* AlexTroshkin for `Show disconnect in context menu only when connectionProfile connected (#150)`
|
||||||
* AlexTroshkin for `Fix #138: Invalid syntax color highlighting (identity not highlighting) (#140))`
|
* AlexTroshkin for `Fix #138: Invalid syntax color highlighting (identity not highlighting) (#140))`
|
||||||
* stebet for `Fix #153: Fixing sql snippets that failed on a DB with case-sensitive collation. (#152)`
|
* stebet for `Fix #153: Fixing sql snippets that failed on a DB with case-sensitive collation. (#152)`
|
||||||
* SebastianPfliegel `Remove sqlExtensionHelp (#312)`
|
* SebastianPfliegel `Remove sqlExtensionHelp (#312)`
|
||||||
* olljanat for `Implemented npm version check (#314)`
|
* olljanat for `Implemented npm version check (#314)`
|
||||||
* Adam Mechanic for helping with the `whoisactive` extension
|
|
||||||
* All community localization contributors *(will get list of individuals next month)*
|
|
||||||
|
|
||||||
And of course we'd like to thank the authors of all upstream dependencies. Please see a full list in the [ThirdPartyNotices.txt](https://raw.githubusercontent.com/Microsoft/sqlopsstudio/master/ThirdPartyNotices.txt)
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ install:
|
|||||||
build_script:
|
build_script:
|
||||||
- yarn
|
- yarn
|
||||||
- .\node_modules\.bin\gulp electron
|
- .\node_modules\.bin\gulp electron
|
||||||
- .\node_modules\.bin\tsc -p .\src\tsconfig.monaco.json --noEmit
|
|
||||||
- npm run compile
|
- npm run compile
|
||||||
|
|
||||||
test_script:
|
test_script:
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"name": "ms-vscode.node-debug",
|
|
||||||
"version": "1.21.8",
|
|
||||||
"repo": "https://github.com/Microsoft/vscode-node-debug"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ms-vscode.node-debug2",
|
|
||||||
"version": "1.21.2",
|
|
||||||
"repo": "https://github.com/Microsoft/vscode-node-debug2"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"env": {
|
|
||||||
"node": true,
|
|
||||||
"es6": true,
|
|
||||||
"browser": true
|
|
||||||
},
|
|
||||||
"rules": {
|
|
||||||
"no-console": 0,
|
|
||||||
"no-cond-assign": 0,
|
|
||||||
"no-unused-vars": 1,
|
|
||||||
"no-extra-semi": "warn",
|
|
||||||
"semi": "warn"
|
|
||||||
},
|
|
||||||
"extends": "eslint:recommended",
|
|
||||||
"parserOptions": {
|
|
||||||
"ecmaFeatures": {
|
|
||||||
"experimentalObjectRestSpread": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
*--------------------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
const fs = require('fs');
|
|
||||||
const path = require('path');
|
|
||||||
const os = require('os');
|
|
||||||
// @ts-ignore review
|
|
||||||
const { remote } = require('electron');
|
|
||||||
const dialog = remote.dialog;
|
|
||||||
|
|
||||||
const builtInExtensionsPath = path.join(__dirname, '..', 'builtInExtensions.json');
|
|
||||||
const controlFilePath = path.join(os.homedir(), '.vscode-oss-dev', 'extensions', 'control.json');
|
|
||||||
|
|
||||||
function readJson(filePath) {
|
|
||||||
return JSON.parse(fs.readFileSync(filePath, { encoding: 'utf8' }));
|
|
||||||
}
|
|
||||||
|
|
||||||
function writeJson(filePath, obj) {
|
|
||||||
fs.writeFileSync(filePath, JSON.stringify(obj, null, 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderOption(form, id, title, value, checked) {
|
|
||||||
const input = document.createElement('input');
|
|
||||||
input.type = 'radio';
|
|
||||||
input.id = id;
|
|
||||||
input.name = 'choice';
|
|
||||||
input.value = value;
|
|
||||||
input.checked = !!checked;
|
|
||||||
form.appendChild(input);
|
|
||||||
|
|
||||||
const label = document.createElement('label');
|
|
||||||
label.setAttribute('for', id);
|
|
||||||
label.textContent = title;
|
|
||||||
form.appendChild(label);
|
|
||||||
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
|
|
||||||
function render(el, state) {
|
|
||||||
function setState(state) {
|
|
||||||
try {
|
|
||||||
writeJson(controlFilePath, state.control);
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
el.innerHTML = '';
|
|
||||||
render(el, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
const ul = document.createElement('ul');
|
|
||||||
const { builtin, control } = state;
|
|
||||||
|
|
||||||
for (const ext of builtin) {
|
|
||||||
const controlState = control[ext.name] || 'marketplace';
|
|
||||||
|
|
||||||
const li = document.createElement('li');
|
|
||||||
ul.appendChild(li);
|
|
||||||
|
|
||||||
const name = document.createElement('code');
|
|
||||||
name.textContent = ext.name;
|
|
||||||
li.appendChild(name);
|
|
||||||
|
|
||||||
const form = document.createElement('form');
|
|
||||||
li.appendChild(form);
|
|
||||||
|
|
||||||
const marketplaceInput = renderOption(form, `marketplace-${ext.name}`, 'Marketplace', 'marketplace', controlState === 'marketplace');
|
|
||||||
marketplaceInput.onchange = function () {
|
|
||||||
control[ext.name] = 'marketplace';
|
|
||||||
setState({ builtin, control });
|
|
||||||
};
|
|
||||||
|
|
||||||
const disabledInput = renderOption(form, `disabled-${ext.name}`, 'Disabled', 'disabled', controlState === 'disabled');
|
|
||||||
disabledInput.onchange = function () {
|
|
||||||
control[ext.name] = 'disabled';
|
|
||||||
setState({ builtin, control });
|
|
||||||
};
|
|
||||||
|
|
||||||
let local = undefined;
|
|
||||||
|
|
||||||
if (controlState !== 'marketplace' && controlState !== 'disabled') {
|
|
||||||
local = controlState;
|
|
||||||
}
|
|
||||||
|
|
||||||
const localInput = renderOption(form, `local-${ext.name}`, 'Local', 'local', !!local);
|
|
||||||
localInput.onchange = function () {
|
|
||||||
const result = dialog.showOpenDialog(remote.getCurrentWindow(), {
|
|
||||||
title: 'Choose Folder',
|
|
||||||
properties: ['openDirectory']
|
|
||||||
});
|
|
||||||
|
|
||||||
if (result && result.length >= 1) {
|
|
||||||
control[ext.name] = result[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
setState({ builtin, control });
|
|
||||||
};
|
|
||||||
|
|
||||||
if (local) {
|
|
||||||
const localSpan = document.createElement('code');
|
|
||||||
localSpan.className = 'local';
|
|
||||||
localSpan.textContent = local;
|
|
||||||
form.appendChild(localSpan);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
el.appendChild(ul);
|
|
||||||
}
|
|
||||||
|
|
||||||
function main() {
|
|
||||||
const el = document.getElementById('extensions');
|
|
||||||
const builtin = readJson(builtInExtensionsPath);
|
|
||||||
let control;
|
|
||||||
|
|
||||||
try {
|
|
||||||
control = readJson(controlFilePath);
|
|
||||||
} catch (err) {
|
|
||||||
control = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
render(el, { builtin, control });
|
|
||||||
}
|
|
||||||
|
|
||||||
window.onload = main;
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
<!-- Copyright (C) Microsoft Corporation. All rights reserved. -->
|
|
||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<title>Manage Built-in Extensions</title>
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<script src="browser-main.js"></script>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
|
|
||||||
font-size: 10pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
code {
|
|
||||||
font-family: 'Menlo', 'Courier New', 'Courier', monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
padding-left: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
li {
|
|
||||||
list-style: none;
|
|
||||||
padding: 0.3em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
margin-right: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
form {
|
|
||||||
padding: 0.3em 0 0.3em 0.3em;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<h1>Built-in Extensions</h1>
|
|
||||||
<div id="extensions"></div>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
*--------------------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
const { app, BrowserWindow } = require('electron');
|
|
||||||
const url = require('url');
|
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
let window = null;
|
|
||||||
|
|
||||||
app.once('ready', () => {
|
|
||||||
window = new BrowserWindow({ width: 800, height: 600 });
|
|
||||||
window.setMenuBarVisibility(false);
|
|
||||||
window.loadURL(url.format({ pathname: path.join(__dirname, 'index.html'), protocol: 'file:', slashes: true }));
|
|
||||||
// window.webContents.openDevTools();
|
|
||||||
window.once('closed', () => window = null);
|
|
||||||
});
|
|
||||||
|
|
||||||
app.on('window-all-closed', () => app.quit());
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "builtin",
|
|
||||||
"version": "0.1.0",
|
|
||||||
"main": "main.js"
|
|
||||||
}
|
|
||||||
@@ -12,7 +12,6 @@ var File = require('vinyl');
|
|||||||
|
|
||||||
var root = path.dirname(__dirname);
|
var root = path.dirname(__dirname);
|
||||||
var sha1 = util.getVersion(root);
|
var sha1 = util.getVersion(root);
|
||||||
// @ts-ignore Microsoft/TypeScript#21262 complains about a require of a JSON file
|
|
||||||
var semver = require('./monaco/package.json').version;
|
var semver = require('./monaco/package.json').version;
|
||||||
var headerVersion = semver + '(' + sha1 + ')';
|
var headerVersion = semver + '(' + sha1 + ')';
|
||||||
|
|
||||||
@@ -22,14 +21,14 @@ var editorEntryPoints = [
|
|||||||
{
|
{
|
||||||
name: 'vs/editor/editor.main',
|
name: 'vs/editor/editor.main',
|
||||||
include: [],
|
include: [],
|
||||||
exclude: ['vs/css', 'vs/nls'],
|
exclude: [ 'vs/css', 'vs/nls' ],
|
||||||
prepend: ['out-build/vs/css.js', 'out-build/vs/nls.js'],
|
prepend: [ 'out-build/vs/css.js', 'out-build/vs/nls.js' ],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'vs/base/common/worker/simpleWorker',
|
name: 'vs/base/common/worker/simpleWorker',
|
||||||
include: ['vs/editor/common/services/editorSimpleWorker'],
|
include: [ 'vs/editor/common/services/editorSimpleWorker' ],
|
||||||
prepend: ['vs/loader.js'],
|
prepend: [ 'vs/loader.js' ],
|
||||||
append: ['vs/base/worker/workerMain'],
|
append: [ 'vs/base/worker/workerMain' ],
|
||||||
dest: 'vs/base/worker/workerMain.js'
|
dest: 'vs/base/worker/workerMain.js'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
@@ -80,15 +79,14 @@ gulp.task('optimize-editor', ['clean-optimized-editor', 'compile-client-build'],
|
|||||||
bundleLoader: false,
|
bundleLoader: false,
|
||||||
header: BUNDLED_FILE_HEADER,
|
header: BUNDLED_FILE_HEADER,
|
||||||
bundleInfo: true,
|
bundleInfo: true,
|
||||||
out: 'out-editor',
|
out: 'out-editor'
|
||||||
languages: undefined
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
gulp.task('clean-minified-editor', util.rimraf('out-editor-min'));
|
gulp.task('clean-minified-editor', util.rimraf('out-editor-min'));
|
||||||
gulp.task('minify-editor', ['clean-minified-editor', 'optimize-editor'], common.minifyTask('out-editor'));
|
gulp.task('minify-editor', ['clean-minified-editor', 'optimize-editor'], common.minifyTask('out-editor'));
|
||||||
|
|
||||||
gulp.task('clean-editor-distro', util.rimraf('out-monaco-editor-core'));
|
gulp.task('clean-editor-distro', util.rimraf('out-monaco-editor-core'));
|
||||||
gulp.task('editor-distro', ['clean-editor-distro', 'minify-editor', 'optimize-editor'], function () {
|
gulp.task('editor-distro', ['clean-editor-distro', 'minify-editor', 'optimize-editor'], function() {
|
||||||
return es.merge(
|
return es.merge(
|
||||||
// other assets
|
// other assets
|
||||||
es.merge(
|
es.merge(
|
||||||
@@ -99,17 +97,17 @@ gulp.task('editor-distro', ['clean-editor-distro', 'minify-editor', 'optimize-ed
|
|||||||
|
|
||||||
// package.json
|
// package.json
|
||||||
gulp.src('build/monaco/package.json')
|
gulp.src('build/monaco/package.json')
|
||||||
.pipe(es.through(function (data) {
|
.pipe(es.through(function(data) {
|
||||||
var json = JSON.parse(data.contents.toString());
|
var json = JSON.parse(data.contents.toString());
|
||||||
json.private = false;
|
json.private = false;
|
||||||
data.contents = Buffer.from(JSON.stringify(json, null, ' '));
|
data.contents = new Buffer(JSON.stringify(json, null, ' '));
|
||||||
this.emit('data', data);
|
this.emit('data', data);
|
||||||
}))
|
}))
|
||||||
.pipe(gulp.dest('out-monaco-editor-core')),
|
.pipe(gulp.dest('out-monaco-editor-core')),
|
||||||
|
|
||||||
// README.md
|
// README.md
|
||||||
gulp.src('build/monaco/README-npm.md')
|
gulp.src('build/monaco/README-npm.md')
|
||||||
.pipe(es.through(function (data) {
|
.pipe(es.through(function(data) {
|
||||||
this.emit('data', new File({
|
this.emit('data', new File({
|
||||||
path: data.path.replace(/README-npm\.md/, 'README.md'),
|
path: data.path.replace(/README-npm\.md/, 'README.md'),
|
||||||
base: data.base,
|
base: data.base,
|
||||||
@@ -126,10 +124,10 @@ gulp.task('editor-distro', ['clean-editor-distro', 'minify-editor', 'optimize-ed
|
|||||||
// min folder
|
// min folder
|
||||||
es.merge(
|
es.merge(
|
||||||
gulp.src('out-editor-min/**/*')
|
gulp.src('out-editor-min/**/*')
|
||||||
).pipe(filterStream(function (path) {
|
).pipe(filterStream(function(path) {
|
||||||
// no map files
|
// no map files
|
||||||
return !/(\.js\.map$)|(nls\.metadata\.json$)|(bundleInfo\.json$)/.test(path);
|
return !/(\.js\.map$)|(nls\.metadata\.json$)|(bundleInfo\.json$)/.test(path);
|
||||||
})).pipe(es.through(function (data) {
|
})).pipe(es.through(function(data) {
|
||||||
// tweak the sourceMappingURL
|
// tweak the sourceMappingURL
|
||||||
if (!/\.js$/.test(data.path)) {
|
if (!/\.js$/.test(data.path)) {
|
||||||
this.emit('data', data);
|
this.emit('data', data);
|
||||||
@@ -142,50 +140,49 @@ gulp.task('editor-distro', ['clean-editor-distro', 'minify-editor', 'optimize-ed
|
|||||||
var newStr = '//# sourceMappingURL=' + relativePathToMap.replace(/\\/g, '/');
|
var newStr = '//# sourceMappingURL=' + relativePathToMap.replace(/\\/g, '/');
|
||||||
strContents = strContents.replace(/\/\/\# sourceMappingURL=[^ ]+$/, newStr);
|
strContents = strContents.replace(/\/\/\# sourceMappingURL=[^ ]+$/, newStr);
|
||||||
|
|
||||||
data.contents = Buffer.from(strContents);
|
data.contents = new Buffer(strContents);
|
||||||
this.emit('data', data);
|
this.emit('data', data);
|
||||||
})).pipe(gulp.dest('out-monaco-editor-core/min')),
|
})).pipe(gulp.dest('out-monaco-editor-core/min')),
|
||||||
|
|
||||||
// min-maps folder
|
// min-maps folder
|
||||||
es.merge(
|
es.merge(
|
||||||
gulp.src('out-editor-min/**/*')
|
gulp.src('out-editor-min/**/*')
|
||||||
).pipe(filterStream(function (path) {
|
).pipe(filterStream(function(path) {
|
||||||
// no map files
|
// no map files
|
||||||
return /\.js\.map$/.test(path);
|
return /\.js\.map$/.test(path);
|
||||||
})).pipe(gulp.dest('out-monaco-editor-core/min-maps'))
|
})).pipe(gulp.dest('out-monaco-editor-core/min-maps'))
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('analyze-editor-distro', function () {
|
gulp.task('analyze-editor-distro', function() {
|
||||||
// @ts-ignore Microsoft/TypeScript#21262 complains about a require of a JSON file
|
|
||||||
var bundleInfo = require('../out-editor/bundleInfo.json');
|
var bundleInfo = require('../out-editor/bundleInfo.json');
|
||||||
var graph = bundleInfo.graph;
|
var graph = bundleInfo.graph;
|
||||||
var bundles = bundleInfo.bundles;
|
var bundles = bundleInfo.bundles;
|
||||||
|
|
||||||
var inverseGraph = {};
|
var inverseGraph = {};
|
||||||
Object.keys(graph).forEach(function (module) {
|
Object.keys(graph).forEach(function(module) {
|
||||||
var dependencies = graph[module];
|
var dependencies = graph[module];
|
||||||
dependencies.forEach(function (dep) {
|
dependencies.forEach(function(dep) {
|
||||||
inverseGraph[dep] = inverseGraph[dep] || [];
|
inverseGraph[dep] = inverseGraph[dep] || [];
|
||||||
inverseGraph[dep].push(module);
|
inverseGraph[dep].push(module);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
var detailed = {};
|
var detailed = {};
|
||||||
Object.keys(bundles).forEach(function (entryPoint) {
|
Object.keys(bundles).forEach(function(entryPoint) {
|
||||||
var included = bundles[entryPoint];
|
var included = bundles[entryPoint];
|
||||||
var includedMap = {};
|
var includedMap = {};
|
||||||
included.forEach(function (included) {
|
included.forEach(function(included) {
|
||||||
includedMap[included] = true;
|
includedMap[included] = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
var explanation = [];
|
var explanation = [];
|
||||||
included.map(function (included) {
|
included.map(function(included) {
|
||||||
if (included.indexOf('!') >= 0) {
|
if (included.indexOf('!') >= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var reason = (inverseGraph[included] || []).filter(function (mod) {
|
var reason = (inverseGraph[included]||[]).filter(function(mod) {
|
||||||
return !!includedMap[mod];
|
return !!includedMap[mod];
|
||||||
});
|
});
|
||||||
explanation.push({
|
explanation.push({
|
||||||
@@ -201,7 +198,7 @@ gulp.task('analyze-editor-distro', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function filterStream(testFunc) {
|
function filterStream(testFunc) {
|
||||||
return es.through(function (data) {
|
return es.through(function(data) {
|
||||||
if (!testFunc(data.relative)) {
|
if (!testFunc(data.relative)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ const sourcemaps = require('gulp-sourcemaps');
|
|||||||
const nlsDev = require('vscode-nls-dev');
|
const nlsDev = require('vscode-nls-dev');
|
||||||
const root = path.dirname(__dirname);
|
const root = path.dirname(__dirname);
|
||||||
const commit = util.getVersion(root);
|
const commit = util.getVersion(root);
|
||||||
const i18n = require('./lib/i18n');
|
|
||||||
|
|
||||||
const extensionsPath = path.join(path.dirname(__dirname), 'extensions');
|
const extensionsPath = path.join(path.dirname(__dirname), 'extensions');
|
||||||
|
|
||||||
@@ -30,8 +29,7 @@ const compilations = glob.sync('**/tsconfig.json', {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const getBaseUrl = out => `https://ticino.blob.core.windows.net/sourcemaps/${commit}/${out}`;
|
const getBaseUrl = out => `https://ticino.blob.core.windows.net/sourcemaps/${commit}/${out}`;
|
||||||
|
const languages = ['chs', 'cht', 'jpn', 'kor', 'deu', 'fra', 'esn', 'rus', 'ita'];
|
||||||
const languages = i18n.defaultLanguages.concat(process.env.VSCODE_QUALITY !== 'stable' ? i18n.extraLanguages : []);
|
|
||||||
|
|
||||||
const tasks = compilations.map(function (tsconfigFile) {
|
const tasks = compilations.map(function (tsconfigFile) {
|
||||||
const absolutePath = path.join(extensionsPath, tsconfigFile);
|
const absolutePath = path.join(extensionsPath, tsconfigFile);
|
||||||
@@ -57,19 +55,9 @@ const tasks = compilations.map(function (tsconfigFile) {
|
|||||||
const srcBase = path.join(root, 'src');
|
const srcBase = path.join(root, 'src');
|
||||||
const src = path.join(srcBase, '**');
|
const src = path.join(srcBase, '**');
|
||||||
const out = path.join(root, 'out');
|
const out = path.join(root, 'out');
|
||||||
const i18nPath = path.join(__dirname, '..', 'i18n');
|
const i18n = path.join(__dirname, '..', 'i18n');
|
||||||
const baseUrl = getBaseUrl(out);
|
const baseUrl = getBaseUrl(out);
|
||||||
|
|
||||||
let headerId, headerOut;
|
|
||||||
let index = relativeDirname.indexOf('/');
|
|
||||||
if (index < 0) {
|
|
||||||
headerId = 'vscode.' + relativeDirname;
|
|
||||||
headerOut = 'out';
|
|
||||||
} else {
|
|
||||||
headerId = 'vscode.' + relativeDirname.substr(0, index);
|
|
||||||
headerOut = relativeDirname.substr(index + 1) + '/out';
|
|
||||||
}
|
|
||||||
|
|
||||||
function createPipeline(build, emitError) {
|
function createPipeline(build, emitError) {
|
||||||
const reporter = createReporter();
|
const reporter = createReporter();
|
||||||
|
|
||||||
@@ -94,9 +82,7 @@ const tasks = compilations.map(function (tsconfigFile) {
|
|||||||
sourceRoot: '../src'
|
sourceRoot: '../src'
|
||||||
}))
|
}))
|
||||||
.pipe(tsFilter.restore)
|
.pipe(tsFilter.restore)
|
||||||
.pipe(build ? nlsDev.createAdditionalLanguageFiles(languages, i18nPath, out) : es.through())
|
.pipe(build ? nlsDev.createAdditionalLanguageFiles(languages, i18n, out) : es.through())
|
||||||
.pipe(build ? nlsDev.bundleMetaDataFiles(headerId, headerOut) : es.through())
|
|
||||||
.pipe(build ? nlsDev.bundleLanguageFiles() : es.through())
|
|
||||||
.pipe(reporter.end(emitError));
|
.pipe(reporter.end(emitError));
|
||||||
|
|
||||||
return es.duplex(input, output);
|
return es.duplex(input, output);
|
||||||
@@ -143,7 +129,7 @@ const tasks = compilations.map(function (tsconfigFile) {
|
|||||||
const watchInput = watcher(src, srcOpts);
|
const watchInput = watcher(src, srcOpts);
|
||||||
|
|
||||||
return watchInput
|
return watchInput
|
||||||
.pipe(util.incremental(() => pipeline(), input))
|
.pipe(util.incremental(() => pipeline(true), input))
|
||||||
.pipe(gulp.dest(out));
|
.pipe(gulp.dest(out));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -12,11 +12,7 @@ const gulptslint = require('gulp-tslint');
|
|||||||
const gulpeslint = require('gulp-eslint');
|
const gulpeslint = require('gulp-eslint');
|
||||||
const tsfmt = require('typescript-formatter');
|
const tsfmt = require('typescript-formatter');
|
||||||
const tslint = require('tslint');
|
const tslint = require('tslint');
|
||||||
const VinylFile = require('vinyl');
|
|
||||||
const vfs = require('vinyl-fs');
|
const vfs = require('vinyl-fs');
|
||||||
const path = require('path');
|
|
||||||
const fs = require('fs');
|
|
||||||
const pall = require('p-all');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hygiene works by creating cascading subsets of all our files and
|
* Hygiene works by creating cascading subsets of all our files and
|
||||||
@@ -33,56 +29,55 @@ const all = [
|
|||||||
'extensions/**/*',
|
'extensions/**/*',
|
||||||
'scripts/**/*',
|
'scripts/**/*',
|
||||||
'src/**/*',
|
'src/**/*',
|
||||||
'test/**/*',
|
'test/**/*'
|
||||||
'!**/node_modules/**'
|
];
|
||||||
|
|
||||||
|
const eolFilter = [
|
||||||
|
'**',
|
||||||
|
'!ThirdPartyNotices.txt',
|
||||||
|
'!LICENSE.txt',
|
||||||
|
'!extensions/**/out/**',
|
||||||
|
'!test/smoke/out/**',
|
||||||
|
'!**/node_modules/**',
|
||||||
|
'!**/fixtures/**',
|
||||||
|
'!**/*.{svg,exe,png,bmp,scpt,bat,cmd,cur,ttf,woff,eot}',
|
||||||
|
'!build/{lib,tslintRules}/**/*.js',
|
||||||
|
'!build/monaco/**',
|
||||||
|
'!build/win32/**',
|
||||||
|
'!build/**/*.sh',
|
||||||
|
'!build/tfs/**/*.js',
|
||||||
|
'!**/Dockerfile'
|
||||||
];
|
];
|
||||||
|
|
||||||
const indentationFilter = [
|
const indentationFilter = [
|
||||||
'**',
|
'**',
|
||||||
|
|
||||||
// except specific files
|
|
||||||
'!ThirdPartyNotices.txt',
|
'!ThirdPartyNotices.txt',
|
||||||
'!LICENSE.txt',
|
'!**/*.md',
|
||||||
'!src/vs/nls.js',
|
'!**/*.ps1',
|
||||||
'!src/vs/css.js',
|
'!**/*.template',
|
||||||
'!src/vs/loader.js',
|
'!**/*.yaml',
|
||||||
'!src/vs/base/common/marked/raw.marked.js',
|
'!**/*.yml',
|
||||||
'!src/vs/base/common/winjs.base.raw.js',
|
|
||||||
'!src/vs/base/node/terminateProcess.sh',
|
|
||||||
'!src/vs/base/node/ps-win.ps1',
|
|
||||||
'!test/assert.js',
|
|
||||||
|
|
||||||
// except specific folders
|
|
||||||
'!test/smoke/out/**',
|
|
||||||
'!extensions/vscode-api-tests/testWorkspace/**',
|
|
||||||
'!extensions/vscode-api-tests/testWorkspace2/**',
|
|
||||||
'!build/monaco/**',
|
|
||||||
'!build/win32/**',
|
|
||||||
|
|
||||||
// except multiple specific files
|
|
||||||
'!**/package.json',
|
|
||||||
'!**/yarn.lock',
|
'!**/yarn.lock',
|
||||||
|
|
||||||
// except multiple specific folders
|
|
||||||
'!**/octicons/**',
|
|
||||||
'!**/fixtures/**',
|
|
||||||
'!**/lib/**',
|
'!**/lib/**',
|
||||||
'!extensions/**/out/**',
|
'!extensions/**/*.d.ts',
|
||||||
|
'!src/typings/**/*.d.ts',
|
||||||
|
'!src/vs/*/**/*.d.ts',
|
||||||
|
'!**/*.d.ts.recipe',
|
||||||
|
'!test/assert.js',
|
||||||
|
'!**/package.json',
|
||||||
|
'!**/octicons/**',
|
||||||
|
'!**/vs/base/common/marked/raw.marked.js',
|
||||||
|
'!**/vs/base/common/winjs.base.raw.js',
|
||||||
|
'!**/vs/base/node/terminateProcess.sh',
|
||||||
|
'!**/vs/base/node/ps-win.ps1',
|
||||||
|
'!**/vs/nls.js',
|
||||||
|
'!**/vs/css.js',
|
||||||
|
'!**/vs/loader.js',
|
||||||
'!extensions/**/snippets/**',
|
'!extensions/**/snippets/**',
|
||||||
'!extensions/**/syntaxes/**',
|
'!extensions/**/syntaxes/**',
|
||||||
'!extensions/**/themes/**',
|
'!extensions/**/themes/**',
|
||||||
'!extensions/**/colorize-fixtures/**',
|
'!extensions/**/colorize-fixtures/**',
|
||||||
|
'!extensions/vscode-api-tests/testWorkspace/**'
|
||||||
// except specific file types
|
|
||||||
'!src/vs/*/**/*.d.ts',
|
|
||||||
'!src/typings/**/*.d.ts',
|
|
||||||
'!extensions/**/*.d.ts',
|
|
||||||
'!**/*.{svg,exe,png,bmp,scpt,bat,cmd,cur,ttf,woff,eot,md,ps1,template,yaml,yml,d.ts.recipe}',
|
|
||||||
'!build/{lib,tslintRules}/**/*.js',
|
|
||||||
'!build/**/*.sh',
|
|
||||||
'!build/tfs/**/*.js',
|
|
||||||
'!**/Dockerfile',
|
|
||||||
'!extensions/markdown/media/*.js'
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const copyrightFilter = [
|
const copyrightFilter = [
|
||||||
@@ -100,7 +95,6 @@ const copyrightFilter = [
|
|||||||
'!**/*.xpm',
|
'!**/*.xpm',
|
||||||
'!**/*.opts',
|
'!**/*.opts',
|
||||||
'!**/*.disabled',
|
'!**/*.disabled',
|
||||||
'!**/*.code-workspace',
|
|
||||||
'!build/**/*.init',
|
'!build/**/*.init',
|
||||||
'!resources/linux/snap/snapcraft.yaml',
|
'!resources/linux/snap/snapcraft.yaml',
|
||||||
'!resources/win32/bin/code.js',
|
'!resources/win32/bin/code.js',
|
||||||
@@ -130,7 +124,6 @@ const tslintFilter = [
|
|||||||
'!**/node_modules/**',
|
'!**/node_modules/**',
|
||||||
'!extensions/typescript/test/colorize-fixtures/**',
|
'!extensions/typescript/test/colorize-fixtures/**',
|
||||||
'!extensions/vscode-api-tests/testWorkspace/**',
|
'!extensions/vscode-api-tests/testWorkspace/**',
|
||||||
'!extensions/vscode-api-tests/testWorkspace2/**',
|
|
||||||
'!extensions/**/*.test.ts',
|
'!extensions/**/*.test.ts',
|
||||||
'!extensions/html/server/lib/jquery.d.ts'
|
'!extensions/html/server/lib/jquery.d.ts'
|
||||||
];
|
];
|
||||||
@@ -151,23 +144,31 @@ gulp.task('eslint', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('tslint', () => {
|
gulp.task('tslint', () => {
|
||||||
// {{SQL CARBON EDIT}}
|
|
||||||
const options = { emitError: false };
|
const options = { emitError: false };
|
||||||
|
|
||||||
return vfs.src(all, { base: '.', follow: true, allowEmpty: true })
|
return vfs.src(all, { base: '.', follow: true, allowEmpty: true })
|
||||||
.pipe(filter(tslintFilter))
|
.pipe(filter(tslintFilter))
|
||||||
.pipe(gulptslint.default({ rulesDirectory: 'build/lib/tslint' }))
|
.pipe(gulptslint({ rulesDirectory: 'build/lib/tslint' }))
|
||||||
.pipe(gulptslint.default.report(options));
|
.pipe(gulptslint.report(options));
|
||||||
});
|
});
|
||||||
|
|
||||||
function hygiene(some) {
|
const hygiene = exports.hygiene = (some, options) => {
|
||||||
|
options = options || {};
|
||||||
let errorCount = 0;
|
let errorCount = 0;
|
||||||
|
|
||||||
const indentation = es.through(function (file) {
|
const eol = es.through(function (file) {
|
||||||
const lines = file.contents.toString('utf8').split(/\r\n|\r|\n/);
|
if (/\r\n?/g.test(file.contents.toString('utf8'))) {
|
||||||
file.__lines = lines;
|
console.error(file.relative + ': Bad EOL found');
|
||||||
|
errorCount++;
|
||||||
|
}
|
||||||
|
|
||||||
lines
|
this.emit('data', file);
|
||||||
|
});
|
||||||
|
|
||||||
|
const indentation = es.through(function (file) {
|
||||||
|
file.contents
|
||||||
|
.toString('utf8')
|
||||||
|
.split(/\r\n|\r|\n/)
|
||||||
.forEach((line, i) => {
|
.forEach((line, i) => {
|
||||||
if (/^\s*$/.test(line)) {
|
if (/^\s*$/.test(line)) {
|
||||||
// empty or whitespace lines are OK
|
// empty or whitespace lines are OK
|
||||||
@@ -185,14 +186,9 @@ function hygiene(some) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const copyrights = es.through(function (file) {
|
const copyrights = es.through(function (file) {
|
||||||
const lines = file.__lines;
|
if (file.contents.toString('utf8').indexOf(copyrightHeader) !== 0) {
|
||||||
|
console.error(file.relative + ': Missing or bad copyright statement');
|
||||||
for (let i = 0; i < copyrightHeaderLines.length; i++) {
|
errorCount++;
|
||||||
if (lines[i] !== copyrightHeaderLines[i]) {
|
|
||||||
console.error(file.relative + ': Missing or bad copyright statement');
|
|
||||||
errorCount++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.emit('data', file);
|
this.emit('data', file);
|
||||||
@@ -200,20 +196,12 @@ function hygiene(some) {
|
|||||||
|
|
||||||
const formatting = es.map(function (file, cb) {
|
const formatting = es.map(function (file, cb) {
|
||||||
tsfmt.processString(file.path, file.contents.toString('utf8'), {
|
tsfmt.processString(file.path, file.contents.toString('utf8'), {
|
||||||
verify: false,
|
verify: true,
|
||||||
tsfmt: true,
|
tsfmt: true,
|
||||||
// verbose: true
|
// verbose: true
|
||||||
// keep checkJS happy
|
|
||||||
editorconfig: undefined,
|
|
||||||
replace: undefined,
|
|
||||||
tsconfig: undefined,
|
|
||||||
tslint: undefined
|
|
||||||
}).then(result => {
|
}).then(result => {
|
||||||
let original = result.src.replace(/\r\n/gm, '\n');
|
if (result.error) {
|
||||||
let formatted = result.dest.replace(/\r\n/gm, '\n');
|
console.error(result.message);
|
||||||
|
|
||||||
if (original !== formatted) {
|
|
||||||
console.error('File not formatted:', file.relative);
|
|
||||||
errorCount++;
|
errorCount++;
|
||||||
}
|
}
|
||||||
cb(null, file);
|
cb(null, file);
|
||||||
@@ -223,31 +211,43 @@ function hygiene(some) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const tslintConfiguration = tslint.Configuration.findConfiguration('tslint.json', '.');
|
function reportFailures(failures) {
|
||||||
const tslintOptions = { fix: false, formatter: 'json' };
|
failures.forEach(failure => {
|
||||||
const tsLinter = new tslint.Linter(tslintOptions);
|
const name = failure.name || failure.fileName;
|
||||||
|
const position = failure.startPosition;
|
||||||
|
const line = position.lineAndCharacter ? position.lineAndCharacter.line : position.line;
|
||||||
|
const character = position.lineAndCharacter ? position.lineAndCharacter.character : position.character;
|
||||||
|
|
||||||
|
// console.error(`${name}:${line + 1}:${character + 1}:${failure.failure}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const tsl = es.through(function (file) {
|
const tsl = es.through(function (file) {
|
||||||
|
const configuration = tslint.Configuration.findConfiguration(null, '.');
|
||||||
|
const options = { formatter: 'json', rulesDirectory: 'build/lib/tslint' };
|
||||||
const contents = file.contents.toString('utf8');
|
const contents = file.contents.toString('utf8');
|
||||||
tsLinter.lint(file.relative, contents, tslintConfiguration.results);
|
const linter = new tslint.Linter(options);
|
||||||
|
linter.lint(file.relative, contents, configuration.results);
|
||||||
|
const result = linter.getResult();
|
||||||
|
|
||||||
|
if (result.failures.length > 0) {
|
||||||
|
reportFailures(result.failures);
|
||||||
|
errorCount += result.failures.length;
|
||||||
|
}
|
||||||
|
|
||||||
this.emit('data', file);
|
this.emit('data', file);
|
||||||
});
|
});
|
||||||
|
|
||||||
let input;
|
const result = vfs.src(some || all, { base: '.', follow: true, allowEmpty: true })
|
||||||
|
|
||||||
if (Array.isArray(some) || typeof some === 'string' || !some) {
|
|
||||||
input = vfs.src(some || all, { base: '.', follow: true, allowEmpty: true });
|
|
||||||
} else {
|
|
||||||
input = some;
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = input
|
|
||||||
.pipe(filter(f => !f.stat.isDirectory()))
|
.pipe(filter(f => !f.stat.isDirectory()))
|
||||||
|
.pipe(filter(eolFilter))
|
||||||
|
// {{SQL CARBON EDIT}}
|
||||||
|
//.pipe(options.skipEOL ? es.through() : eol)
|
||||||
.pipe(filter(indentationFilter))
|
.pipe(filter(indentationFilter))
|
||||||
.pipe(indentation)
|
.pipe(indentation)
|
||||||
.pipe(filter(copyrightFilter));
|
.pipe(filter(copyrightFilter))
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
// .pipe(copyrights);
|
//.pipe(copyrights);
|
||||||
|
|
||||||
const typescript = result
|
const typescript = result
|
||||||
.pipe(filter(tslintFilter))
|
.pipe(filter(tslintFilter))
|
||||||
@@ -257,52 +257,23 @@ function hygiene(some) {
|
|||||||
const javascript = result
|
const javascript = result
|
||||||
.pipe(filter(eslintFilter))
|
.pipe(filter(eslintFilter))
|
||||||
.pipe(gulpeslint('src/.eslintrc'))
|
.pipe(gulpeslint('src/.eslintrc'))
|
||||||
.pipe(gulpeslint.formatEach('compact'));
|
.pipe(gulpeslint.formatEach('compact'))
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
// .pipe(gulpeslint.failAfterError());
|
// .pipe(gulpeslint.failAfterError());
|
||||||
|
|
||||||
let count = 0;
|
return es.merge(typescript, javascript)
|
||||||
return es.merge(typescript, javascript)
|
.pipe(es.through(null, function () {
|
||||||
.pipe(es.through(function (data) {
|
// {{SQL CARBON EDIT}}
|
||||||
// {{SQL CARBON EDIT}}
|
// if (errorCount > 0) {
|
||||||
this.emit('end');
|
// this.emit('error', 'Hygiene failed with ' + errorCount + ' errors. Check \'build/gulpfile.hygiene.js\'.');
|
||||||
}));
|
// } else {
|
||||||
}
|
// this.emit('end');
|
||||||
|
// }
|
||||||
|
this.emit('end');
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
function createGitIndexVinyls(paths) {
|
gulp.task('hygiene', () => hygiene(''));
|
||||||
const cp = require('child_process');
|
|
||||||
const repositoryPath = process.cwd();
|
|
||||||
|
|
||||||
const fns = paths.map(relativePath => () => new Promise((c, e) => {
|
|
||||||
const fullPath = path.join(repositoryPath, relativePath);
|
|
||||||
|
|
||||||
fs.stat(fullPath, (err, stat) => {
|
|
||||||
if (err && err.code === 'ENOENT') { // ignore deletions
|
|
||||||
return c(null);
|
|
||||||
} else if (err) {
|
|
||||||
return e(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
cp.exec(`git show :${relativePath}`, { maxBuffer: 2000 * 1024, encoding: 'buffer' }, (err, out) => {
|
|
||||||
if (err) {
|
|
||||||
return e(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
c(new VinylFile({
|
|
||||||
path: fullPath,
|
|
||||||
base: repositoryPath,
|
|
||||||
contents: out,
|
|
||||||
stat
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
|
|
||||||
return pall(fns, { concurrency: 4 })
|
|
||||||
.then(r => r.filter(p => !!p));
|
|
||||||
}
|
|
||||||
|
|
||||||
gulp.task('hygiene', () => hygiene());
|
|
||||||
|
|
||||||
// this allows us to run hygiene as a git pre-commit hook
|
// this allows us to run hygiene as a git pre-commit hook
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
@@ -313,19 +284,22 @@ if (require.main === module) {
|
|||||||
process.exit(1);
|
process.exit(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (process.argv.length > 2) {
|
cp.exec('git config core.autocrlf', (err, out) => {
|
||||||
hygiene(process.argv.slice(2)).on('error', err => {
|
const skipEOL = out.trim() === 'true';
|
||||||
console.error();
|
|
||||||
console.error(err);
|
if (process.argv.length > 2) {
|
||||||
process.exit(1);
|
return hygiene(process.argv.slice(2), { skipEOL: skipEOL }).on('error', err => {
|
||||||
});
|
console.error();
|
||||||
} else {
|
console.error(err);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
cp.exec('git diff --cached --name-only', { maxBuffer: 2000 * 1024 }, (err, out) => {
|
cp.exec('git diff --cached --name-only', { maxBuffer: 2000 * 1024 }, (err, out) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error();
|
console.error();
|
||||||
console.error(err);
|
console.error(err);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const some = out
|
const some = out
|
||||||
@@ -333,18 +307,12 @@ if (require.main === module) {
|
|||||||
.filter(l => !!l);
|
.filter(l => !!l);
|
||||||
|
|
||||||
if (some.length > 0) {
|
if (some.length > 0) {
|
||||||
console.log('Reading git index versions...');
|
hygiene(some, { skipEOL: skipEOL }).on('error', err => {
|
||||||
|
console.error();
|
||||||
createGitIndexVinyls(some)
|
console.error(err);
|
||||||
.then(vinyls => new Promise((c, e) => hygiene(es.readArray(vinyls))
|
process.exit(1);
|
||||||
.on('end', () => c())
|
});
|
||||||
.on('error', e)))
|
|
||||||
.catch(err => {
|
|
||||||
console.error();
|
|
||||||
console.error(err);
|
|
||||||
process.exit(1);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,21 +6,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const gulp = require('gulp');
|
const gulp = require('gulp');
|
||||||
const json = require('gulp-json-editor');
|
|
||||||
const buffer = require('gulp-buffer');
|
|
||||||
const filter = require('gulp-filter');
|
|
||||||
const es = require('event-stream');
|
|
||||||
const util = require('./lib/util');
|
|
||||||
const remote = require('gulp-remote-src');
|
|
||||||
const zip = require('gulp-vinyl-zip');
|
|
||||||
const assign = require('object-assign');
|
|
||||||
|
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
const jeditor = require('gulp-json-editor');
|
const jeditor = require('gulp-json-editor');
|
||||||
|
|
||||||
// @ts-ignore Microsoft/TypeScript#21262 complains about a require of a JSON file
|
|
||||||
const pkg = require('../package.json');
|
|
||||||
|
|
||||||
gulp.task('mixin', function () {
|
gulp.task('mixin', function () {
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
const updateUrl = process.env['SQLOPS_UPDATEURL'];
|
const updateUrl = process.env['SQLOPS_UPDATEURL'];
|
||||||
@@ -36,17 +24,10 @@ gulp.task('mixin', function () {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
let serviceUrl = 'https://sqlopsextensions.blob.core.windows.net/marketplace/v1/extensionsGallery.json';
|
|
||||||
if (quality === 'insider') {
|
|
||||||
serviceUrl = `https://sqlopsextensions.blob.core.windows.net/marketplace/v1/extensionsGallery-${quality}.json`;
|
|
||||||
}
|
|
||||||
let newValues = {
|
let newValues = {
|
||||||
"updateUrl": updateUrl,
|
"updateUrl": updateUrl,
|
||||||
"quality": quality,
|
"quality": quality
|
||||||
"extensionsGallery": {
|
|
||||||
"serviceUrl": serviceUrl
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return gulp.src('./product.json')
|
return gulp.src('./product.json')
|
||||||
|
|||||||
@@ -13,6 +13,14 @@ const filter = require('gulp-filter');
|
|||||||
|
|
||||||
gulp.task('clean-mssql-extension', util.rimraf('extensions/mssql/node_modules'));
|
gulp.task('clean-mssql-extension', util.rimraf('extensions/mssql/node_modules'));
|
||||||
gulp.task('clean-credentials-extension', util.rimraf('extensions/credentials/node_modules'));
|
gulp.task('clean-credentials-extension', util.rimraf('extensions/credentials/node_modules'));
|
||||||
|
gulp.task('clean-extensions-modules', util.rimraf('extensions-modules/node_modules'));
|
||||||
|
gulp.task('clean-protocol', ['clean-extensions-modules', 'clean-mssql-extension', 'clean-credentials-extension', 'clean-client', 'clean-jsonrpc', 'clean-server', 'clean-types']);
|
||||||
|
|
||||||
|
// Tasks to clean extensions modules
|
||||||
|
gulp.task('clean-mssql-ext-mod', util.rimraf('extensions/mssql/node_modules/extensions-modules'));
|
||||||
|
gulp.task('clean-credentials-ext-mod', util.rimraf('extensions/credentials/node_modules/extensions-modules'));
|
||||||
|
gulp.task('clean-build-ext-mod', util.rimraf('build/node_modules/extensions-modules'));
|
||||||
|
gulp.task('clean-ext-mod', ['clean-mssql-ext-mod', 'clean-credentials-ext-mod', 'clean-build-ext-mod', 'clean-extensions-modules']);
|
||||||
|
|
||||||
gulp.task('fmt', () => formatStagedFiles());
|
gulp.task('fmt', () => formatStagedFiles());
|
||||||
const formatFiles = (some) => {
|
const formatFiles = (some) => {
|
||||||
|
|||||||
@@ -27,22 +27,17 @@ const common = require('./lib/optimize');
|
|||||||
const nlsDev = require('vscode-nls-dev');
|
const nlsDev = require('vscode-nls-dev');
|
||||||
const root = path.dirname(__dirname);
|
const root = path.dirname(__dirname);
|
||||||
const commit = util.getVersion(root);
|
const commit = util.getVersion(root);
|
||||||
// @ts-ignore Microsoft/TypeScript#21262 complains about a require of a JSON file
|
|
||||||
const packageJson = require('../package.json');
|
const packageJson = require('../package.json');
|
||||||
// @ts-ignore Microsoft/TypeScript#21262 complains about a require of a JSON file
|
|
||||||
const product = require('../product.json');
|
const product = require('../product.json');
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
const i18n = require('./lib/i18n');
|
const i18n = require('./lib/i18n');
|
||||||
// {{SQL CARBON EDIT}}
|
const serviceInstaller = require('../extensions-modules/lib/languageservice/serviceInstallerUtil');
|
||||||
const serviceDownloader = require('service-downloader').ServiceDownloadProvider;
|
|
||||||
const platformInfo = require('service-downloader/out/platform').PlatformInformation;
|
|
||||||
const glob = require('glob');
|
const glob = require('glob');
|
||||||
const deps = require('./dependencies');
|
const deps = require('./dependencies');
|
||||||
const getElectronVersion = require('./lib/electron').getElectronVersion;
|
const getElectronVersion = require('./lib/electron').getElectronVersion;
|
||||||
const createAsar = require('./lib/asar').createAsar;
|
|
||||||
|
|
||||||
const productionDependencies = deps.getProductionDependencies(path.dirname(__dirname));
|
const productionDependencies = deps.getProductionDependencies(path.dirname(__dirname));
|
||||||
// @ts-ignore
|
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
var del = require('del');
|
var del = require('del');
|
||||||
const extensionsRoot = path.join(root, 'extensions');
|
const extensionsRoot = path.join(root, 'extensions');
|
||||||
@@ -60,24 +55,16 @@ const nodeModules = [
|
|||||||
.concat(_.uniq(productionDependencies.map(d => d.name)))
|
.concat(_.uniq(productionDependencies.map(d => d.name)))
|
||||||
.concat(baseModules);
|
.concat(baseModules);
|
||||||
|
|
||||||
|
|
||||||
// Build
|
// Build
|
||||||
// @ts-ignore Microsoft/TypeScript#21262 complains about a require of a JSON file
|
|
||||||
const builtInExtensions = require('./builtInExtensions.json');
|
const builtInExtensions = [
|
||||||
|
{ name: 'ms-vscode.node-debug', version: '1.19.8' },
|
||||||
|
{ name: 'ms-vscode.node-debug2', version: '1.19.4' }
|
||||||
|
];
|
||||||
|
|
||||||
const excludedExtensions = [
|
const excludedExtensions = [
|
||||||
'vscode-api-tests',
|
'vscode-api-tests',
|
||||||
'vscode-colorize-tests',
|
'vscode-colorize-tests'
|
||||||
'ms-vscode.node-debug',
|
|
||||||
'ms-vscode.node-debug2',
|
|
||||||
];
|
|
||||||
|
|
||||||
// {{SQL CARBON EDIT}}
|
|
||||||
const vsce = require('vsce');
|
|
||||||
const sqlBuiltInExtensions = [
|
|
||||||
// Add SQL built-in extensions here.
|
|
||||||
// the extension will be excluded from SQLOps package and will have separate vsix packages
|
|
||||||
'agent'
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const vscodeEntryPoints = _.flatten([
|
const vscodeEntryPoints = _.flatten([
|
||||||
@@ -108,8 +95,7 @@ const vscodeResources = [
|
|||||||
'out-build/vs/workbench/parts/welcome/walkThrough/**/*.md',
|
'out-build/vs/workbench/parts/welcome/walkThrough/**/*.md',
|
||||||
'out-build/vs/workbench/services/files/**/*.exe',
|
'out-build/vs/workbench/services/files/**/*.exe',
|
||||||
'out-build/vs/workbench/services/files/**/*.md',
|
'out-build/vs/workbench/services/files/**/*.md',
|
||||||
'out-build/vs/code/electron-browser/sharedProcess/sharedProcess.js',
|
'out-build/vs/code/electron-browser/sharedProcess.js',
|
||||||
'out-build/vs/code/electron-browser/issue/issueReporter.js',
|
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
'out-build/sql/workbench/electron-browser/splashscreen/*',
|
'out-build/sql/workbench/electron-browser/splashscreen/*',
|
||||||
'out-build/sql/**/*.{svg,png,cur,html}',
|
'out-build/sql/**/*.{svg,png,cur,html}',
|
||||||
@@ -127,7 +113,6 @@ const vscodeResources = [
|
|||||||
'out-build/sql/parts/grid/views/**/*.html',
|
'out-build/sql/parts/grid/views/**/*.html',
|
||||||
'out-build/sql/parts/tasks/**/*.html',
|
'out-build/sql/parts/tasks/**/*.html',
|
||||||
'out-build/sql/parts/taskHistory/viewlet/media/**',
|
'out-build/sql/parts/taskHistory/viewlet/media/**',
|
||||||
'out-build/sql/parts/jobManagement/common/media/*.svg',
|
|
||||||
'out-build/sql/media/objectTypes/*.svg',
|
'out-build/sql/media/objectTypes/*.svg',
|
||||||
'out-build/sql/media/icons/*.svg',
|
'out-build/sql/media/icons/*.svg',
|
||||||
'!**/test/**'
|
'!**/test/**'
|
||||||
@@ -139,7 +124,10 @@ const BUNDLED_FILE_HEADER = [
|
|||||||
' *--------------------------------------------------------*/'
|
' *--------------------------------------------------------*/'
|
||||||
].join('\n');
|
].join('\n');
|
||||||
|
|
||||||
const languages = i18n.defaultLanguages.concat([]); // i18n.defaultLanguages.concat(process.env.VSCODE_QUALITY !== 'stable' ? i18n.extraLanguages : []);
|
var languages = ['chs', 'cht', 'jpn', 'kor', 'deu', 'fra', 'esn', 'rus', 'ita'];
|
||||||
|
if (process.env.VSCODE_QUALITY !== 'stable') {
|
||||||
|
languages = languages.concat(['ptb', 'hun', 'trk']); // Add languages requested by the community to non-stable builds
|
||||||
|
}
|
||||||
|
|
||||||
gulp.task('clean-optimized-vscode', util.rimraf('out-vscode'));
|
gulp.task('clean-optimized-vscode', util.rimraf('out-vscode'));
|
||||||
gulp.task('optimize-vscode', ['clean-optimized-vscode', 'compile-build', 'compile-extensions-build'], common.optimizeTask({
|
gulp.task('optimize-vscode', ['clean-optimized-vscode', 'compile-build', 'compile-extensions-build'], common.optimizeTask({
|
||||||
@@ -149,8 +137,7 @@ gulp.task('optimize-vscode', ['clean-optimized-vscode', 'compile-build', 'compil
|
|||||||
loaderConfig: common.loaderConfig(nodeModules),
|
loaderConfig: common.loaderConfig(nodeModules),
|
||||||
header: BUNDLED_FILE_HEADER,
|
header: BUNDLED_FILE_HEADER,
|
||||||
out: 'out-vscode',
|
out: 'out-vscode',
|
||||||
languages: languages,
|
languages: languages
|
||||||
bundleInfo: undefined
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
@@ -172,7 +159,7 @@ const config = {
|
|||||||
version: getElectronVersion(),
|
version: getElectronVersion(),
|
||||||
productAppName: product.nameLong,
|
productAppName: product.nameLong,
|
||||||
companyName: 'Microsoft Corporation',
|
companyName: 'Microsoft Corporation',
|
||||||
copyright: 'Copyright (C) 2018 Microsoft. All rights reserved',
|
copyright: 'Copyright (C) 2017 Microsoft. All rights reserved',
|
||||||
darwinIcon: 'resources/darwin/code.icns',
|
darwinIcon: 'resources/darwin/code.icns',
|
||||||
darwinBundleIdentifier: product.darwinBundleIdentifier,
|
darwinBundleIdentifier: product.darwinBundleIdentifier,
|
||||||
darwinApplicationCategoryType: 'public.app-category.developer-tools',
|
darwinApplicationCategoryType: 'public.app-category.developer-tools',
|
||||||
@@ -191,7 +178,7 @@ const config = {
|
|||||||
name: product.nameLong,
|
name: product.nameLong,
|
||||||
urlSchemes: [product.urlProtocol]
|
urlSchemes: [product.urlProtocol]
|
||||||
}],
|
}],
|
||||||
darwinCredits: darwinCreditsTemplate ? Buffer.from(darwinCreditsTemplate({ commit: commit, date: new Date().toISOString() })) : void 0,
|
darwinCredits: darwinCreditsTemplate ? new Buffer(darwinCreditsTemplate({ commit: commit, date: new Date().toISOString() })) : void 0,
|
||||||
linuxExecutableName: product.applicationName,
|
linuxExecutableName: product.applicationName,
|
||||||
winIcon: 'resources/win32/code.ico',
|
winIcon: 'resources/win32/code.ico',
|
||||||
token: process.env['VSCODE_MIXIN_PASSWORD'] || process.env['GITHUB_TOKEN'] || void 0,
|
token: process.env['VSCODE_MIXIN_PASSWORD'] || process.env['GITHUB_TOKEN'] || void 0,
|
||||||
@@ -255,26 +242,6 @@ function computeChecksum(filename) {
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
function packageBuiltInExtensions() {
|
|
||||||
const sqlBuiltInLocalExtensionDescriptions = glob.sync('extensions/*/package.json')
|
|
||||||
.map(manifestPath => {
|
|
||||||
const extensionPath = path.dirname(path.join(root, manifestPath));
|
|
||||||
const extensionName = path.basename(extensionPath);
|
|
||||||
return { name: extensionName, path: extensionPath };
|
|
||||||
})
|
|
||||||
.filter(({ name }) => excludedExtensions.indexOf(name) === -1)
|
|
||||||
.filter(({ name }) => builtInExtensions.every(b => b.name !== name))
|
|
||||||
.filter(({ name }) => sqlBuiltInExtensions.indexOf(name) >= 0);
|
|
||||||
sqlBuiltInLocalExtensionDescriptions.forEach(element => {
|
|
||||||
const packagePath = path.join(path.dirname(root), element.name + '.vsix');
|
|
||||||
console.info('Creating vsix for ' + element.path + ' result:' + packagePath);
|
|
||||||
vsce.createVSIX({
|
|
||||||
cwd: element.path,
|
|
||||||
packagePath: packagePath
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function packageTask(platform, arch, opts) {
|
function packageTask(platform, arch, opts) {
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
|
|
||||||
@@ -304,10 +271,7 @@ function packageTask(platform, arch, opts) {
|
|||||||
return { name: extensionName, path: extensionPath };
|
return { name: extensionName, path: extensionPath };
|
||||||
})
|
})
|
||||||
.filter(({ name }) => excludedExtensions.indexOf(name) === -1)
|
.filter(({ name }) => excludedExtensions.indexOf(name) === -1)
|
||||||
.filter(({ name }) => builtInExtensions.every(b => b.name !== name))
|
.filter(({ name }) => builtInExtensions.every(b => b.name !== name));
|
||||||
// {{SQL CARBON EDIT}}
|
|
||||||
.filter(({ name }) => sqlBuiltInExtensions.indexOf(name) === -1);
|
|
||||||
packageBuiltInExtensions();
|
|
||||||
|
|
||||||
const localExtensions = es.merge(...localExtensionDescriptions.map(extension => {
|
const localExtensions = es.merge(...localExtensionDescriptions.map(extension => {
|
||||||
const nlsFilter = filter('**/*.nls.json', { restore: true });
|
const nlsFilter = filter('**/*.nls.json', { restore: true });
|
||||||
@@ -329,12 +293,16 @@ function packageTask(platform, arch, opts) {
|
|||||||
const localExtensionDependencies = gulp.src(extensionDepsSrc, { base: '.', dot: true })
|
const localExtensionDependencies = gulp.src(extensionDepsSrc, { base: '.', dot: true })
|
||||||
.pipe(filter(['**', '!**/package-lock.json']))
|
.pipe(filter(['**', '!**/package-lock.json']))
|
||||||
.pipe(util.cleanNodeModule('account-provider-azure', ['node_modules/date-utils/doc/**', 'node_modules/adal_node/node_modules/**'], undefined))
|
.pipe(util.cleanNodeModule('account-provider-azure', ['node_modules/date-utils/doc/**', 'node_modules/adal_node/node_modules/**'], undefined))
|
||||||
|
.pipe(util.cleanNodeModule('dataprotocol-client', ['node_modules/**', 'src/*.js'], undefined))
|
||||||
|
.pipe(util.cleanNodeModule('extensions-modules', ['node_modules/**', 'src/*.js'], undefined))
|
||||||
.pipe(util.cleanNodeModule('typescript', ['**/**'], undefined));
|
.pipe(util.cleanNodeModule('typescript', ['**/**'], undefined));
|
||||||
|
|
||||||
|
|
||||||
const sources = es.merge(src, localExtensions, localExtensionDependencies)
|
const sources = es.merge(src, localExtensions, localExtensionDependencies)
|
||||||
.pipe(util.setExecutableBit(['**/*.sh']))
|
.pipe(util.setExecutableBit(['**/*.sh']))
|
||||||
.pipe(filter(['**', '!**/*.js.map']));
|
.pipe(filter(['**',
|
||||||
|
'!**/*.js.map',
|
||||||
|
'!extensions/**/node_modules/**/{test, tests}/**',
|
||||||
|
'!extensions/**/node_modules/**/test.js']));
|
||||||
|
|
||||||
let version = packageJson.version;
|
let version = packageJson.version;
|
||||||
const quality = product.quality;
|
const quality = product.quality;
|
||||||
@@ -358,7 +326,7 @@ function packageTask(platform, arch, opts) {
|
|||||||
|
|
||||||
// TODO the API should be copied to `out` during compile, not here
|
// TODO the API should be copied to `out` during compile, not here
|
||||||
const api = gulp.src('src/vs/vscode.d.ts').pipe(rename('out/vs/vscode.d.ts'));
|
const api = gulp.src('src/vs/vscode.d.ts').pipe(rename('out/vs/vscode.d.ts'));
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
const dataApi = gulp.src('src/vs/data.d.ts').pipe(rename('out/sql/data.d.ts'));
|
const dataApi = gulp.src('src/vs/data.d.ts').pipe(rename('out/sql/data.d.ts'));
|
||||||
|
|
||||||
const depsSrc = [
|
const depsSrc = [
|
||||||
@@ -372,7 +340,6 @@ function packageTask(platform, arch, opts) {
|
|||||||
.pipe(util.cleanNodeModule('oniguruma', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node', 'src/*.js']))
|
.pipe(util.cleanNodeModule('oniguruma', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node', 'src/*.js']))
|
||||||
.pipe(util.cleanNodeModule('windows-mutex', ['binding.gyp', 'build/**', 'src/**'], ['**/*.node']))
|
.pipe(util.cleanNodeModule('windows-mutex', ['binding.gyp', 'build/**', 'src/**'], ['**/*.node']))
|
||||||
.pipe(util.cleanNodeModule('native-keymap', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node']))
|
.pipe(util.cleanNodeModule('native-keymap', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node']))
|
||||||
.pipe(util.cleanNodeModule('native-is-elevated', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node']))
|
|
||||||
.pipe(util.cleanNodeModule('native-watchdog', ['binding.gyp', 'build/**', 'src/**'], ['**/*.node']))
|
.pipe(util.cleanNodeModule('native-watchdog', ['binding.gyp', 'build/**', 'src/**'], ['**/*.node']))
|
||||||
.pipe(util.cleanNodeModule('spdlog', ['binding.gyp', 'build/**', 'deps/**', 'src/**', 'test/**'], ['**/*.node']))
|
.pipe(util.cleanNodeModule('spdlog', ['binding.gyp', 'build/**', 'deps/**', 'src/**', 'test/**'], ['**/*.node']))
|
||||||
.pipe(util.cleanNodeModule('jschardet', ['dist/**']))
|
.pipe(util.cleanNodeModule('jschardet', ['dist/**']))
|
||||||
@@ -380,27 +347,18 @@ function packageTask(platform, arch, opts) {
|
|||||||
.pipe(util.cleanNodeModule('windows-process-tree', ['binding.gyp', 'build/**', 'src/**'], ['**/*.node']))
|
.pipe(util.cleanNodeModule('windows-process-tree', ['binding.gyp', 'build/**', 'src/**'], ['**/*.node']))
|
||||||
.pipe(util.cleanNodeModule('gc-signals', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node', 'src/index.js']))
|
.pipe(util.cleanNodeModule('gc-signals', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node', 'src/index.js']))
|
||||||
.pipe(util.cleanNodeModule('keytar', ['binding.gyp', 'build/**', 'src/**', 'script/**', 'node_modules/**'], ['**/*.node']))
|
.pipe(util.cleanNodeModule('keytar', ['binding.gyp', 'build/**', 'src/**', 'script/**', 'node_modules/**'], ['**/*.node']))
|
||||||
.pipe(util.cleanNodeModule('node-pty', ['binding.gyp', 'build/**', 'src/**', 'tools/**'], ['build/Release/*.exe', 'build/Release/*.dll', 'build/Release/*.node']))
|
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
|
.pipe(util.cleanNodeModule('node-pty', ['binding.gyp', 'build/**', 'src/**', 'tools/**'], ['build/Release/*.node', 'build/Release/*.dll', 'build/Release/*.exe']))
|
||||||
.pipe(util.cleanNodeModule('chart.js', ['node_modules/**'], undefined))
|
.pipe(util.cleanNodeModule('chart.js', ['node_modules/**'], undefined))
|
||||||
.pipe(util.cleanNodeModule('emmet', ['node_modules/**'], undefined))
|
.pipe(util.cleanNodeModule('emmet', ['node_modules/**'], undefined))
|
||||||
.pipe(util.cleanNodeModule('pty.js', ['build/**'], ['build/Release/**']))
|
.pipe(util.cleanNodeModule('pty.js', ['build/**'], ['build/Release/**']))
|
||||||
.pipe(util.cleanNodeModule('jquery-ui', ['external/**', 'demos/**'], undefined))
|
.pipe(util.cleanNodeModule('jquery-ui', ['external/**', 'demos/**'], undefined))
|
||||||
.pipe(util.cleanNodeModule('core-js', ['**/**'], undefined))
|
.pipe(util.cleanNodeModule('core-js', ['**/**'], undefined))
|
||||||
.pipe(util.cleanNodeModule('slickgrid', ['node_modules/**', 'examples/**'], undefined))
|
.pipe(util.cleanNodeModule('slickgrid', ['node_modules/**', 'examples/**'], undefined))
|
||||||
.pipe(util.cleanNodeModule('nsfw', ['binding.gyp', 'build/**', 'src/**', 'openpa/**', 'includes/**'], ['**/*.node', '**/*.a']))
|
|
||||||
.pipe(util.cleanNodeModule('vsda', ['binding.gyp', 'README.md', 'build/**', '*.bat', '*.sh', '*.cpp', '*.h'], ['build/Release/vsda.node']))
|
|
||||||
.pipe(createAsar(path.join(process.cwd(), 'node_modules'), ['**/*.node', '**/vscode-ripgrep/bin/*', '**/node-pty/build/Release/*'], 'app/node_modules.asar'));
|
|
||||||
|
|
||||||
// {{SQL CARBON EDIT}}
|
.pipe(util.cleanNodeModule('nsfw', ['binding.gyp', 'build/**', 'src/**', 'openpa/**', 'includes/**'], ['**/*.node', '**/*.a']))
|
||||||
let copiedModules = gulp.src([
|
.pipe(util.cleanNodeModule('vsda', ['binding.gyp', 'README.md', 'build/**', '*.bat', '*.sh', '*.cpp', '*.h'], ['build/Release/vsda.node']));
|
||||||
'node_modules/jquery/**/*.*',
|
|
||||||
'node_modules/reflect-metadata/**/*.*',
|
|
||||||
'node_modules/slickgrid/**/*.*',
|
|
||||||
'node_modules/underscore/**/*.*',
|
|
||||||
'node_modules/zone.js/**/*.*',
|
|
||||||
'node_modules/chart.js/**/*.*'
|
|
||||||
], { base: '.', dot: true });
|
|
||||||
|
|
||||||
let all = es.merge(
|
let all = es.merge(
|
||||||
packageJsonStream,
|
packageJsonStream,
|
||||||
@@ -408,8 +366,7 @@ function packageTask(platform, arch, opts) {
|
|||||||
license,
|
license,
|
||||||
watermark,
|
watermark,
|
||||||
api,
|
api,
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
copiedModules,
|
|
||||||
dataApi,
|
dataApi,
|
||||||
sources,
|
sources,
|
||||||
deps
|
deps
|
||||||
@@ -480,21 +437,25 @@ gulp.task('vscode-linux-x64-min', ['minify-vscode', 'clean-vscode-linux-x64'], p
|
|||||||
gulp.task('vscode-linux-arm-min', ['minify-vscode', 'clean-vscode-linux-arm'], packageTask('linux', 'arm', { minified: true }));
|
gulp.task('vscode-linux-arm-min', ['minify-vscode', 'clean-vscode-linux-arm'], packageTask('linux', 'arm', { minified: true }));
|
||||||
|
|
||||||
// Transifex Localizations
|
// Transifex Localizations
|
||||||
|
const vscodeLanguages = [
|
||||||
const innoSetupConfig = {
|
'zh-hans',
|
||||||
'zh-cn': { codePage: 'CP936', defaultInfo: { name: 'Simplified Chinese', id: '$0804', } },
|
'zh-hant',
|
||||||
'zh-tw': { codePage: 'CP950', defaultInfo: { name: 'Traditional Chinese', id: '$0404' } },
|
'ja',
|
||||||
'ko': { codePage: 'CP949', defaultInfo: { name: 'Korean', id: '$0412' } },
|
'ko',
|
||||||
'ja': { codePage: 'CP932' },
|
'de',
|
||||||
'de': { codePage: 'CP1252' },
|
'fr',
|
||||||
'fr': { codePage: 'CP1252' },
|
'es',
|
||||||
'es': { codePage: 'CP1252' },
|
'ru',
|
||||||
'ru': { codePage: 'CP1251' },
|
'it',
|
||||||
'it': { codePage: 'CP1252' },
|
'pt-br',
|
||||||
'pt-br': { codePage: 'CP1252' },
|
'hu',
|
||||||
'hu': { codePage: 'CP1250' },
|
'tr'
|
||||||
'tr': { codePage: 'CP1254' }
|
];
|
||||||
};
|
const setupDefaultLanguages = [
|
||||||
|
'zh-hans',
|
||||||
|
'zh-hant',
|
||||||
|
'ko'
|
||||||
|
];
|
||||||
|
|
||||||
const apiHostname = process.env.TRANSIFEX_API_URL;
|
const apiHostname = process.env.TRANSIFEX_API_URL;
|
||||||
const apiName = process.env.TRANSIFEX_API_NAME;
|
const apiName = process.env.TRANSIFEX_API_NAME;
|
||||||
@@ -502,48 +463,27 @@ const apiToken = process.env.TRANSIFEX_API_TOKEN;
|
|||||||
|
|
||||||
gulp.task('vscode-translations-push', ['optimize-vscode'], function () {
|
gulp.task('vscode-translations-push', ['optimize-vscode'], function () {
|
||||||
const pathToMetadata = './out-vscode/nls.metadata.json';
|
const pathToMetadata = './out-vscode/nls.metadata.json';
|
||||||
const pathToExtensions = './extensions/*';
|
const pathToExtensions = './extensions/**/*.nls.json';
|
||||||
const pathToSetup = 'build/win32/**/{Default.isl,messages.en.isl}';
|
const pathToSetup = 'build/win32/**/{Default.isl,messages.en.isl}';
|
||||||
|
|
||||||
return es.merge(
|
return es.merge(
|
||||||
gulp.src(pathToMetadata).pipe(i18n.createXlfFilesForCoreBundle()),
|
gulp.src(pathToMetadata).pipe(i18n.prepareXlfFiles()),
|
||||||
gulp.src(pathToSetup).pipe(i18n.createXlfFilesForIsl()),
|
gulp.src(pathToSetup).pipe(i18n.prepareXlfFiles()),
|
||||||
gulp.src(pathToExtensions).pipe(i18n.createXlfFilesForExtensions())
|
gulp.src(pathToExtensions).pipe(i18n.prepareXlfFiles('vscode-extensions'))
|
||||||
).pipe(i18n.findObsoleteResources(apiHostname, apiName, apiToken)
|
|
||||||
).pipe(i18n.pushXlfFiles(apiHostname, apiName, apiToken));
|
).pipe(i18n.pushXlfFiles(apiHostname, apiName, apiToken));
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('vscode-translations-push-test', ['optimize-vscode'], function () {
|
|
||||||
const pathToMetadata = './out-vscode/nls.metadata.json';
|
|
||||||
const pathToExtensions = './extensions/*';
|
|
||||||
const pathToSetup = 'build/win32/**/{Default.isl,messages.en.isl}';
|
|
||||||
|
|
||||||
return es.merge(
|
|
||||||
gulp.src(pathToMetadata).pipe(i18n.createXlfFilesForCoreBundle()),
|
|
||||||
gulp.src(pathToSetup).pipe(i18n.createXlfFilesForIsl()),
|
|
||||||
gulp.src(pathToExtensions).pipe(i18n.createXlfFilesForExtensions())
|
|
||||||
).pipe(i18n.findObsoleteResources(apiHostname, apiName, apiToken)
|
|
||||||
).pipe(vfs.dest('../vscode-transifex-input'));
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('vscode-translations-pull', function () {
|
gulp.task('vscode-translations-pull', function () {
|
||||||
[...i18n.defaultLanguages, ...i18n.extraLanguages].forEach(language => {
|
return es.merge(
|
||||||
i18n.pullCoreAndExtensionsXlfFiles(apiHostname, apiName, apiToken, language).pipe(vfs.dest(`../vscode-localization/${language.id}/build`));
|
i18n.pullXlfFiles('vscode-editor', apiHostname, apiName, apiToken, vscodeLanguages),
|
||||||
|
i18n.pullXlfFiles('vscode-workbench', apiHostname, apiName, apiToken, vscodeLanguages),
|
||||||
let includeDefault = !!innoSetupConfig[language.id].defaultInfo;
|
i18n.pullXlfFiles('vscode-extensions', apiHostname, apiName, apiToken, vscodeLanguages),
|
||||||
i18n.pullSetupXlfFiles(apiHostname, apiName, apiToken, language, includeDefault).pipe(vfs.dest(`../vscode-localization/${language.id}/setup`));
|
i18n.pullXlfFiles('vscode-setup', apiHostname, apiName, apiToken, setupDefaultLanguages)
|
||||||
});
|
).pipe(vfs.dest('../vscode-localization'));
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('vscode-translations-import', function () {
|
gulp.task('vscode-translations-import', function () {
|
||||||
[...i18n.defaultLanguages, ...i18n.extraLanguages].forEach(language => {
|
return gulp.src('../vscode-localization/**/*.xlf').pipe(i18n.prepareJsonFiles()).pipe(vfs.dest('./i18n'));
|
||||||
gulp.src(`../vscode-localization/${language.id}/build/*/*.xlf`)
|
|
||||||
.pipe(i18n.prepareI18nFiles())
|
|
||||||
.pipe(vfs.dest(`./i18n/${language.folderName}`));
|
|
||||||
gulp.src(`../vscode-localization/${language.id}/setup/*/*.xlf`)
|
|
||||||
.pipe(i18n.prepareIslFiles(language, innoSetupConfig[language.id]))
|
|
||||||
.pipe(vfs.dest(`./build/win32/i18n`));
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Sourcemaps
|
// Sourcemaps
|
||||||
@@ -569,8 +509,7 @@ gulp.task('upload-vscode-sourcemaps', ['minify-vscode'], () => {
|
|||||||
const allConfigDetailsPath = path.join(os.tmpdir(), 'configuration.json');
|
const allConfigDetailsPath = path.join(os.tmpdir(), 'configuration.json');
|
||||||
gulp.task('upload-vscode-configuration', ['generate-vscode-configuration'], () => {
|
gulp.task('upload-vscode-configuration', ['generate-vscode-configuration'], () => {
|
||||||
const branch = process.env.BUILD_SOURCEBRANCH;
|
const branch = process.env.BUILD_SOURCEBRANCH;
|
||||||
|
if (!branch.endsWith('/master') && branch.indexOf('/release/') < 0) {
|
||||||
if (!/\/master$/.test(branch) && branch.indexOf('/release/') < 0) {
|
|
||||||
console.log(`Only runs on master and release branches, not ${branch}`);
|
console.log(`Only runs on master and release branches, not ${branch}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -665,7 +604,6 @@ function versionStringToNumber(versionStr) {
|
|||||||
return parseInt(match[1], 10) * 1e4 + parseInt(match[2], 10) * 1e2 + parseInt(match[3], 10);
|
return parseInt(match[1], 10) * 1e4 + parseInt(match[2], 10) * 1e2 + parseInt(match[3], 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This task is only run for the MacOS build
|
|
||||||
gulp.task('generate-vscode-configuration', () => {
|
gulp.task('generate-vscode-configuration', () => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const buildDir = process.env['AGENT_BUILDDIRECTORY'];
|
const buildDir = process.env['AGENT_BUILDDIRECTORY'];
|
||||||
@@ -675,8 +613,7 @@ gulp.task('generate-vscode-configuration', () => {
|
|||||||
|
|
||||||
const userDataDir = path.join(os.tmpdir(), 'tmpuserdata');
|
const userDataDir = path.join(os.tmpdir(), 'tmpuserdata');
|
||||||
const extensionsDir = path.join(os.tmpdir(), 'tmpextdir');
|
const extensionsDir = path.join(os.tmpdir(), 'tmpextdir');
|
||||||
const appName = process.env.VSCODE_QUALITY === 'insider' ? 'Visual\\ Studio\\ Code\\ -\\ Insiders.app' : 'Visual\\ Studio\\ Code.app';
|
const appPath = path.join(buildDir, 'VSCode-darwin/Visual\\ Studio\\ Code\\ -\\ Insiders.app/Contents/Resources/app/bin/code');
|
||||||
const appPath = path.join(buildDir, `VSCode-darwin/${appName}/Contents/Resources/app/bin/code`);
|
|
||||||
const codeProc = cp.exec(`${appPath} --export-default-configuration='${allConfigDetailsPath}' --wait --user-data-dir='${userDataDir}' --extensions-dir='${extensionsDir}'`);
|
const codeProc = cp.exec(`${appPath} --export-default-configuration='${allConfigDetailsPath}' --wait --user-data-dir='${userDataDir}' --extensions-dir='${extensionsDir}'`);
|
||||||
|
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
@@ -705,25 +642,27 @@ gulp.task('generate-vscode-configuration', () => {
|
|||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
// Install service locally before building carbon
|
// Install service locally before building carbon
|
||||||
|
|
||||||
function installService() {
|
function installService(extObj, path) {
|
||||||
let config = require('../extensions/mssql/src/config.json');
|
var installer = new serviceInstaller.ServiceInstaller(extObj, path);
|
||||||
return platformInfo.getCurrent().then(p => {
|
installer.getServiceInstallDirectoryRoot().then(serviceInstallFolder => {
|
||||||
let runtime = p.runtimeId;
|
console.log('Cleaning up the install folder: ' + serviceInstallFolder);
|
||||||
// fix path since it won't be correct
|
del(serviceInstallFolder + '/*').then(() => {
|
||||||
config.installDirectory = path.join(__dirname, '../extensions/mssql/src', config.installDirectory);
|
console.log('Installing the service. Install folder: ' + serviceInstallFolder);
|
||||||
var installer = new serviceDownloader(config);
|
installer.installService();
|
||||||
let serviceInstallFolder = installer.getInstallDirectory(runtime);
|
}, delError => {
|
||||||
console.log('Cleaning up the install folder: ' + serviceInstallFolder);
|
console.log('failed to delete the install folder error: ' + delError);
|
||||||
return del(serviceInstallFolder + '/*').then(() => {
|
});
|
||||||
console.log('Installing the service. Install folder: ' + serviceInstallFolder);
|
}, getFolderPathError => {
|
||||||
return installer.installService(runtime);
|
console.log('failed to call getServiceInstallDirectoryRoot error: ' + getFolderPathError);
|
||||||
}, delError => {
|
|
||||||
console.log('failed to delete the install folder error: ' + delError);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gulp.task('install-sqltoolsservice', () => {
|
gulp.task('install-sqltoolsservice', () => {
|
||||||
return installService();
|
var mssqlExt = require('../extensions/mssql/client/out/models/constants');
|
||||||
|
var extObj = new mssqlExt.Constants();
|
||||||
|
var path = '../extensions/mssql/client/out/config.json';
|
||||||
|
return installService(extObj, path);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,12 +12,9 @@ const shell = require('gulp-shell');
|
|||||||
const es = require('event-stream');
|
const es = require('event-stream');
|
||||||
const vfs = require('vinyl-fs');
|
const vfs = require('vinyl-fs');
|
||||||
const util = require('./lib/util');
|
const util = require('./lib/util');
|
||||||
// @ts-ignore Microsoft/TypeScript#21262 complains about a require of a JSON file
|
|
||||||
const packageJson = require('../package.json');
|
const packageJson = require('../package.json');
|
||||||
// @ts-ignore Microsoft/TypeScript#21262 complains about a require of a JSON file
|
|
||||||
const product = require('../product.json');
|
const product = require('../product.json');
|
||||||
// @ts-ignore Microsoft/TypeScript#21262 complains about a require of a JSON file
|
const rpmDependencies = require('../resources/linux/rpm/dependencies');
|
||||||
const rpmDependencies = require('../resources/linux/rpm/dependencies.json');
|
|
||||||
|
|
||||||
const linuxPackageRevision = Math.floor(new Date().getTime() / 1000);
|
const linuxPackageRevision = Math.floor(new Date().getTime() / 1000);
|
||||||
|
|
||||||
@@ -114,7 +111,8 @@ function buildDebPackage(arch) {
|
|||||||
return shell.task([
|
return shell.task([
|
||||||
'chmod 755 ' + product.applicationName + '-' + debArch + '/DEBIAN/postinst ' + product.applicationName + '-' + debArch + '/DEBIAN/prerm ' + product.applicationName + '-' + debArch + '/DEBIAN/postrm',
|
'chmod 755 ' + product.applicationName + '-' + debArch + '/DEBIAN/postinst ' + product.applicationName + '-' + debArch + '/DEBIAN/prerm ' + product.applicationName + '-' + debArch + '/DEBIAN/postrm',
|
||||||
'mkdir -p deb',
|
'mkdir -p deb',
|
||||||
'fakeroot dpkg-deb -b ' + product.applicationName + '-' + debArch + ' deb'
|
'fakeroot dpkg-deb -b ' + product.applicationName + '-' + debArch + ' deb',
|
||||||
|
'dpkg-scanpackages deb /dev/null > Packages'
|
||||||
], { cwd: '.build/linux/deb/' + debArch });
|
], { cwd: '.build/linux/deb/' + debArch });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,10 +220,10 @@ function prepareSnapPackage(arch) {
|
|||||||
|
|
||||||
function buildSnapPackage(arch) {
|
function buildSnapPackage(arch) {
|
||||||
const snapBuildPath = getSnapBuildPath(arch);
|
const snapBuildPath = getSnapBuildPath(arch);
|
||||||
const snapFilename = `${product.applicationName}-${packageJson.version}-${linuxPackageRevision}-${arch}.snap`;
|
|
||||||
return shell.task([
|
return shell.task([
|
||||||
`chmod +x ${snapBuildPath}/electron-launch`,
|
`chmod +x ${snapBuildPath}/electron-launch`,
|
||||||
`cd ${snapBuildPath} && snapcraft snap --output ../${snapFilename}`
|
`cd ${snapBuildPath} && snapcraft snap`
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,11 +11,8 @@ const assert = require('assert');
|
|||||||
const cp = require('child_process');
|
const cp = require('child_process');
|
||||||
const _7z = require('7zip')['7z'];
|
const _7z = require('7zip')['7z'];
|
||||||
const util = require('./lib/util');
|
const util = require('./lib/util');
|
||||||
// @ts-ignore Microsoft/TypeScript#21262 complains about a require of a JSON file
|
|
||||||
const pkg = require('../package.json');
|
const pkg = require('../package.json');
|
||||||
// @ts-ignore Microsoft/TypeScript#21262 complains about a require of a JSON file
|
|
||||||
const product = require('../product.json');
|
const product = require('../product.json');
|
||||||
const vfs = require('vinyl-fs');
|
|
||||||
|
|
||||||
const repoPath = path.dirname(__dirname);
|
const repoPath = path.dirname(__dirname);
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
@@ -94,13 +91,3 @@ gulp.task('vscode-win32-ia32-archive', ['clean-vscode-win32-ia32-archive'], arch
|
|||||||
|
|
||||||
gulp.task('clean-vscode-win32-x64-archive', util.rimraf(zipDir('x64')));
|
gulp.task('clean-vscode-win32-x64-archive', util.rimraf(zipDir('x64')));
|
||||||
gulp.task('vscode-win32-x64-archive', ['clean-vscode-win32-x64-archive'], archiveWin32Setup('x64'));
|
gulp.task('vscode-win32-x64-archive', ['clean-vscode-win32-x64-archive'], archiveWin32Setup('x64'));
|
||||||
|
|
||||||
function copyInnoUpdater(arch) {
|
|
||||||
return () => {
|
|
||||||
return gulp.src('build/win32/{inno_updater.exe,vcruntime140.dll}', { base: 'build/win32' })
|
|
||||||
.pipe(vfs.dest(path.join(buildPath(arch), 'tools')));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
gulp.task('vscode-win32-ia32-copy-inno-updater', copyInnoUpdater('ia32'));
|
|
||||||
gulp.task('vscode-win32-x64-copy-inno-updater', copyInnoUpdater('x64'));
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------------------------
|
|
||||||
* 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 });
|
|
||||||
var path = require("path");
|
|
||||||
var es = require("event-stream");
|
|
||||||
var pickle = require("chromium-pickle-js");
|
|
||||||
var Filesystem = require("asar/lib/filesystem");
|
|
||||||
var VinylFile = require("vinyl");
|
|
||||||
var minimatch = require("minimatch");
|
|
||||||
function createAsar(folderPath, unpackGlobs, destFilename) {
|
|
||||||
var shouldUnpackFile = function (file) {
|
|
||||||
for (var i = 0; i < unpackGlobs.length; i++) {
|
|
||||||
if (minimatch(file.relative, unpackGlobs[i])) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
var filesystem = new Filesystem(folderPath);
|
|
||||||
var out = [];
|
|
||||||
// Keep track of pending inserts
|
|
||||||
var pendingInserts = 0;
|
|
||||||
var onFileInserted = function () { pendingInserts--; };
|
|
||||||
// Do not insert twice the same directory
|
|
||||||
var seenDir = {};
|
|
||||||
var insertDirectoryRecursive = function (dir) {
|
|
||||||
if (seenDir[dir]) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var lastSlash = dir.lastIndexOf('/');
|
|
||||||
if (lastSlash === -1) {
|
|
||||||
lastSlash = dir.lastIndexOf('\\');
|
|
||||||
}
|
|
||||||
if (lastSlash !== -1) {
|
|
||||||
insertDirectoryRecursive(dir.substring(0, lastSlash));
|
|
||||||
}
|
|
||||||
seenDir[dir] = true;
|
|
||||||
filesystem.insertDirectory(dir);
|
|
||||||
};
|
|
||||||
var insertDirectoryForFile = function (file) {
|
|
||||||
var lastSlash = file.lastIndexOf('/');
|
|
||||||
if (lastSlash === -1) {
|
|
||||||
lastSlash = file.lastIndexOf('\\');
|
|
||||||
}
|
|
||||||
if (lastSlash !== -1) {
|
|
||||||
insertDirectoryRecursive(file.substring(0, lastSlash));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var insertFile = function (relativePath, stat, shouldUnpack) {
|
|
||||||
insertDirectoryForFile(relativePath);
|
|
||||||
pendingInserts++;
|
|
||||||
filesystem.insertFile(relativePath, shouldUnpack, { stat: stat }, {}, onFileInserted);
|
|
||||||
};
|
|
||||||
return es.through(function (file) {
|
|
||||||
if (file.stat.isDirectory()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!file.stat.isFile()) {
|
|
||||||
throw new Error("unknown item in stream!");
|
|
||||||
}
|
|
||||||
var shouldUnpack = shouldUnpackFile(file);
|
|
||||||
insertFile(file.relative, { size: file.contents.length, mode: file.stat.mode }, shouldUnpack);
|
|
||||||
if (shouldUnpack) {
|
|
||||||
// The file goes outside of xx.asar, in a folder xx.asar.unpacked
|
|
||||||
var relative = path.relative(folderPath, file.path);
|
|
||||||
this.queue(new VinylFile({
|
|
||||||
cwd: folderPath,
|
|
||||||
base: folderPath,
|
|
||||||
path: path.join(destFilename + '.unpacked', relative),
|
|
||||||
stat: file.stat,
|
|
||||||
contents: file.contents
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// The file goes inside of xx.asar
|
|
||||||
out.push(file.contents);
|
|
||||||
}
|
|
||||||
}, function () {
|
|
||||||
var _this = this;
|
|
||||||
var finish = function () {
|
|
||||||
{
|
|
||||||
var headerPickle = pickle.createEmpty();
|
|
||||||
headerPickle.writeString(JSON.stringify(filesystem.header));
|
|
||||||
var headerBuf = headerPickle.toBuffer();
|
|
||||||
var sizePickle = pickle.createEmpty();
|
|
||||||
sizePickle.writeUInt32(headerBuf.length);
|
|
||||||
var sizeBuf = sizePickle.toBuffer();
|
|
||||||
out.unshift(headerBuf);
|
|
||||||
out.unshift(sizeBuf);
|
|
||||||
}
|
|
||||||
var contents = Buffer.concat(out);
|
|
||||||
out.length = 0;
|
|
||||||
_this.queue(new VinylFile({
|
|
||||||
cwd: folderPath,
|
|
||||||
base: folderPath,
|
|
||||||
path: destFilename,
|
|
||||||
contents: contents
|
|
||||||
}));
|
|
||||||
_this.queue(null);
|
|
||||||
};
|
|
||||||
// Call finish() only when all file inserts have finished...
|
|
||||||
if (pendingInserts === 0) {
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
onFileInserted = function () {
|
|
||||||
pendingInserts--;
|
|
||||||
if (pendingInserts === 0) {
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.createAsar = createAsar;
|
|
||||||
@@ -1,131 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------------------------
|
|
||||||
* 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 * as path from 'path';
|
|
||||||
import * as es from 'event-stream';
|
|
||||||
import * as pickle from 'chromium-pickle-js';
|
|
||||||
import * as Filesystem from 'asar/lib/filesystem';
|
|
||||||
import * as VinylFile from 'vinyl';
|
|
||||||
import * as minimatch from 'minimatch';
|
|
||||||
|
|
||||||
export function createAsar(folderPath: string, unpackGlobs: string[], destFilename: string): NodeJS.ReadWriteStream {
|
|
||||||
|
|
||||||
const shouldUnpackFile = (file: VinylFile): boolean => {
|
|
||||||
for (let i = 0; i < unpackGlobs.length; i++) {
|
|
||||||
if (minimatch(file.relative, unpackGlobs[i])) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
const filesystem = new Filesystem(folderPath);
|
|
||||||
const out: Buffer[] = [];
|
|
||||||
|
|
||||||
// Keep track of pending inserts
|
|
||||||
let pendingInserts = 0;
|
|
||||||
let onFileInserted = () => { pendingInserts--; };
|
|
||||||
|
|
||||||
// Do not insert twice the same directory
|
|
||||||
const seenDir: { [key: string]: boolean; } = {};
|
|
||||||
const insertDirectoryRecursive = (dir: string) => {
|
|
||||||
if (seenDir[dir]) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let lastSlash = dir.lastIndexOf('/');
|
|
||||||
if (lastSlash === -1) {
|
|
||||||
lastSlash = dir.lastIndexOf('\\');
|
|
||||||
}
|
|
||||||
if (lastSlash !== -1) {
|
|
||||||
insertDirectoryRecursive(dir.substring(0, lastSlash));
|
|
||||||
}
|
|
||||||
seenDir[dir] = true;
|
|
||||||
filesystem.insertDirectory(dir);
|
|
||||||
};
|
|
||||||
|
|
||||||
const insertDirectoryForFile = (file: string) => {
|
|
||||||
let lastSlash = file.lastIndexOf('/');
|
|
||||||
if (lastSlash === -1) {
|
|
||||||
lastSlash = file.lastIndexOf('\\');
|
|
||||||
}
|
|
||||||
if (lastSlash !== -1) {
|
|
||||||
insertDirectoryRecursive(file.substring(0, lastSlash));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const insertFile = (relativePath: string, stat: { size: number; mode: number; }, shouldUnpack: boolean) => {
|
|
||||||
insertDirectoryForFile(relativePath);
|
|
||||||
pendingInserts++;
|
|
||||||
filesystem.insertFile(relativePath, shouldUnpack, { stat: stat }, {}, onFileInserted);
|
|
||||||
};
|
|
||||||
|
|
||||||
return es.through(function (file) {
|
|
||||||
if (file.stat.isDirectory()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!file.stat.isFile()) {
|
|
||||||
throw new Error(`unknown item in stream!`);
|
|
||||||
}
|
|
||||||
const shouldUnpack = shouldUnpackFile(file);
|
|
||||||
insertFile(file.relative, { size: file.contents.length, mode: file.stat.mode }, shouldUnpack);
|
|
||||||
|
|
||||||
if (shouldUnpack) {
|
|
||||||
// The file goes outside of xx.asar, in a folder xx.asar.unpacked
|
|
||||||
const relative = path.relative(folderPath, file.path);
|
|
||||||
this.queue(new VinylFile({
|
|
||||||
cwd: folderPath,
|
|
||||||
base: folderPath,
|
|
||||||
path: path.join(destFilename + '.unpacked', relative),
|
|
||||||
stat: file.stat,
|
|
||||||
contents: file.contents
|
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
// The file goes inside of xx.asar
|
|
||||||
out.push(file.contents);
|
|
||||||
}
|
|
||||||
}, function () {
|
|
||||||
|
|
||||||
let finish = () => {
|
|
||||||
{
|
|
||||||
const headerPickle = pickle.createEmpty();
|
|
||||||
headerPickle.writeString(JSON.stringify(filesystem.header));
|
|
||||||
const headerBuf = headerPickle.toBuffer();
|
|
||||||
|
|
||||||
const sizePickle = pickle.createEmpty();
|
|
||||||
sizePickle.writeUInt32(headerBuf.length);
|
|
||||||
const sizeBuf = sizePickle.toBuffer();
|
|
||||||
|
|
||||||
out.unshift(headerBuf);
|
|
||||||
out.unshift(sizeBuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
const contents = Buffer.concat(out);
|
|
||||||
out.length = 0;
|
|
||||||
|
|
||||||
this.queue(new VinylFile({
|
|
||||||
cwd: folderPath,
|
|
||||||
base: folderPath,
|
|
||||||
path: destFilename,
|
|
||||||
contents: contents
|
|
||||||
}));
|
|
||||||
this.queue(null);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Call finish() only when all file inserts have finished...
|
|
||||||
if (pendingInserts === 0) {
|
|
||||||
finish();
|
|
||||||
} else {
|
|
||||||
onFileInserted = () => {
|
|
||||||
pendingInserts--;
|
|
||||||
if (pendingInserts === 0) {
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
*--------------------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const fs = require('fs');
|
|
||||||
const path = require('path');
|
|
||||||
const os = require('os');
|
|
||||||
const mkdirp = require('mkdirp');
|
|
||||||
const rimraf = require('rimraf');
|
|
||||||
const es = require('event-stream');
|
|
||||||
const rename = require('gulp-rename');
|
|
||||||
const vfs = require('vinyl-fs');
|
|
||||||
const ext = require('./extensions');
|
|
||||||
const util = require('gulp-util');
|
|
||||||
|
|
||||||
const root = path.dirname(path.dirname(__dirname));
|
|
||||||
// @ts-ignore Microsoft/TypeScript#21262 complains about a require of a JSON file
|
|
||||||
const builtInExtensions = require('../builtInExtensions.json');
|
|
||||||
const controlFilePath = path.join(os.homedir(), '.vscode-oss-dev', 'extensions', 'control.json');
|
|
||||||
|
|
||||||
function getExtensionPath(extension) {
|
|
||||||
return path.join(root, '.build', 'builtInExtensions', extension.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
function isUpToDate(extension) {
|
|
||||||
const packagePath = path.join(getExtensionPath(extension), 'package.json');
|
|
||||||
|
|
||||||
if (!fs.existsSync(packagePath)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const packageContents = fs.readFileSync(packagePath, { encoding: 'utf8' });
|
|
||||||
|
|
||||||
try {
|
|
||||||
const diskVersion = JSON.parse(packageContents).version;
|
|
||||||
return (diskVersion === extension.version);
|
|
||||||
} catch (err) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function syncMarketplaceExtension(extension) {
|
|
||||||
if (isUpToDate(extension)) {
|
|
||||||
util.log(util.colors.blue('[marketplace]'), `${extension.name}@${extension.version}`, util.colors.green('✔︎'));
|
|
||||||
return es.readArray([]);
|
|
||||||
}
|
|
||||||
|
|
||||||
rimraf.sync(getExtensionPath(extension));
|
|
||||||
|
|
||||||
return ext.fromMarketplace(extension.name, extension.version)
|
|
||||||
.pipe(rename(p => p.dirname = `${extension.name}/${p.dirname}`))
|
|
||||||
.pipe(vfs.dest('.build/builtInExtensions'))
|
|
||||||
.on('end', () => util.log(util.colors.blue('[marketplace]'), extension.name, util.colors.green('✔︎')));
|
|
||||||
}
|
|
||||||
|
|
||||||
function syncExtension(extension, controlState) {
|
|
||||||
switch (controlState) {
|
|
||||||
case 'disabled':
|
|
||||||
util.log(util.colors.blue('[disabled]'), util.colors.gray(extension.name));
|
|
||||||
return es.readArray([]);
|
|
||||||
|
|
||||||
case 'marketplace':
|
|
||||||
return syncMarketplaceExtension(extension);
|
|
||||||
|
|
||||||
default:
|
|
||||||
if (!fs.existsSync(controlState)) {
|
|
||||||
util.log(util.colors.red(`Error: Built-in extension '${extension.name}' is configured to run from '${controlState}' but that path does not exist.`));
|
|
||||||
return es.readArray([]);
|
|
||||||
|
|
||||||
} else if (!fs.existsSync(path.join(controlState, 'package.json'))) {
|
|
||||||
util.log(util.colors.red(`Error: Built-in extension '${extension.name}' is configured to run from '${controlState}' but there is no 'package.json' file in that directory.`));
|
|
||||||
return es.readArray([]);
|
|
||||||
}
|
|
||||||
|
|
||||||
util.log(util.colors.blue('[local]'), `${extension.name}: ${util.colors.cyan(controlState)}`, util.colors.green('✔︎'));
|
|
||||||
return es.readArray([]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function readControlFile() {
|
|
||||||
try {
|
|
||||||
return JSON.parse(fs.readFileSync(controlFilePath, 'utf8'));
|
|
||||||
} catch (err) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function writeControlFile(control) {
|
|
||||||
mkdirp.sync(path.dirname(controlFilePath));
|
|
||||||
fs.writeFileSync(controlFilePath, JSON.stringify(control, null, 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
function main() {
|
|
||||||
util.log('Syncronizing built-in extensions...');
|
|
||||||
util.log(`You can manage built-in extensions with the ${util.colors.cyan('--builtin')} flag`);
|
|
||||||
|
|
||||||
const control = readControlFile();
|
|
||||||
const streams = [];
|
|
||||||
|
|
||||||
for (const extension of builtInExtensions) {
|
|
||||||
let controlState = control[extension.name] || 'marketplace';
|
|
||||||
control[extension.name] = controlState;
|
|
||||||
|
|
||||||
streams.push(syncExtension(extension, controlState));
|
|
||||||
}
|
|
||||||
|
|
||||||
writeControlFile(control);
|
|
||||||
|
|
||||||
es.merge(streams)
|
|
||||||
.on('error', err => {
|
|
||||||
console.error(err);
|
|
||||||
process.exit(1);
|
|
||||||
})
|
|
||||||
.on('end', () => {
|
|
||||||
process.exit(0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
main();
|
|
||||||
@@ -217,7 +217,6 @@ function removeDuplicateTSBoilerplate(destFiles) {
|
|||||||
{ start: /^var __metadata/, end: /^};$/ },
|
{ start: /^var __metadata/, end: /^};$/ },
|
||||||
{ start: /^var __param/, end: /^};$/ },
|
{ start: /^var __param/, end: /^};$/ },
|
||||||
{ start: /^var __awaiter/, end: /^};$/ },
|
{ start: /^var __awaiter/, end: /^};$/ },
|
||||||
{ start: /^var __generator/, end: /^};$/ },
|
|
||||||
];
|
];
|
||||||
destFiles.forEach(function (destFile) {
|
destFiles.forEach(function (destFile) {
|
||||||
var SEEN_BOILERPLATE = [];
|
var SEEN_BOILERPLATE = [];
|
||||||
|
|||||||
@@ -44,11 +44,11 @@ interface ILoaderPluginReqFunc {
|
|||||||
|
|
||||||
export interface IEntryPoint {
|
export interface IEntryPoint {
|
||||||
name: string;
|
name: string;
|
||||||
include?: string[];
|
include: string[];
|
||||||
exclude?: string[];
|
exclude: string[];
|
||||||
prepend: string[];
|
prepend: string[];
|
||||||
append?: string[];
|
append: string[];
|
||||||
dest?: string;
|
dest: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IEntryPointMap {
|
interface IEntryPointMap {
|
||||||
@@ -339,7 +339,6 @@ function removeDuplicateTSBoilerplate(destFiles: IConcatFile[]): IConcatFile[] {
|
|||||||
{ start: /^var __metadata/, end: /^};$/ },
|
{ start: /^var __metadata/, end: /^};$/ },
|
||||||
{ start: /^var __param/, end: /^};$/ },
|
{ start: /^var __param/, end: /^};$/ },
|
||||||
{ start: /^var __awaiter/, end: /^};$/ },
|
{ start: /^var __awaiter/, end: /^};$/ },
|
||||||
{ start: /^var __generator/, end: /^};$/ },
|
|
||||||
];
|
];
|
||||||
|
|
||||||
destFiles.forEach((destFile) => {
|
destFiles.forEach((destFile) => {
|
||||||
|
|||||||
@@ -22,9 +22,6 @@ var rootDir = path.join(__dirname, '../../src');
|
|||||||
var options = require('../../src/tsconfig.json').compilerOptions;
|
var options = require('../../src/tsconfig.json').compilerOptions;
|
||||||
options.verbose = false;
|
options.verbose = false;
|
||||||
options.sourceMap = true;
|
options.sourceMap = true;
|
||||||
if (process.env['VSCODE_NO_SOURCEMAP']) {
|
|
||||||
options.sourceMap = false;
|
|
||||||
}
|
|
||||||
options.rootDir = rootDir;
|
options.rootDir = rootDir;
|
||||||
options.sourceRoot = util.toFileUri(rootDir);
|
options.sourceRoot = util.toFileUri(rootDir);
|
||||||
function createCompile(build, emitError) {
|
function createCompile(build, emitError) {
|
||||||
@@ -61,13 +58,9 @@ function compileTask(out, build) {
|
|||||||
return function () {
|
return function () {
|
||||||
var compile = createCompile(build, true);
|
var compile = createCompile(build, true);
|
||||||
var src = es.merge(gulp.src('src/**', { base: 'src' }), gulp.src('node_modules/typescript/lib/lib.d.ts'));
|
var src = es.merge(gulp.src('src/**', { base: 'src' }), gulp.src('node_modules/typescript/lib/lib.d.ts'));
|
||||||
// Do not write .d.ts files to disk, as they are not needed there.
|
|
||||||
var dtsFilter = util.filter(function (data) { return !/\.d\.ts$/.test(data.path); });
|
|
||||||
return src
|
return src
|
||||||
.pipe(compile())
|
.pipe(compile())
|
||||||
.pipe(dtsFilter)
|
|
||||||
.pipe(gulp.dest(out))
|
.pipe(gulp.dest(out))
|
||||||
.pipe(dtsFilter.restore)
|
|
||||||
.pipe(monacodtsTask(out, false));
|
.pipe(monacodtsTask(out, false));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -77,19 +70,54 @@ function watchTask(out, build) {
|
|||||||
var compile = createCompile(build);
|
var compile = createCompile(build);
|
||||||
var src = es.merge(gulp.src('src/**', { base: 'src' }), gulp.src('node_modules/typescript/lib/lib.d.ts'));
|
var src = es.merge(gulp.src('src/**', { base: 'src' }), gulp.src('node_modules/typescript/lib/lib.d.ts'));
|
||||||
var watchSrc = watch('src/**', { base: 'src' });
|
var watchSrc = watch('src/**', { base: 'src' });
|
||||||
// Do not write .d.ts files to disk, as they are not needed there.
|
|
||||||
var dtsFilter = util.filter(function (data) { return !/\.d\.ts$/.test(data.path); });
|
|
||||||
return watchSrc
|
return watchSrc
|
||||||
.pipe(util.incremental(compile, src, true))
|
.pipe(util.incremental(compile, src, true))
|
||||||
.pipe(dtsFilter)
|
|
||||||
.pipe(gulp.dest(out))
|
.pipe(gulp.dest(out))
|
||||||
.pipe(dtsFilter.restore)
|
|
||||||
.pipe(monacodtsTask(out, true));
|
.pipe(monacodtsTask(out, true));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
exports.watchTask = watchTask;
|
exports.watchTask = watchTask;
|
||||||
|
function reloadTypeScriptNodeModule() {
|
||||||
|
var util = require('gulp-util');
|
||||||
|
function log(message) {
|
||||||
|
var rest = [];
|
||||||
|
for (var _i = 1; _i < arguments.length; _i++) {
|
||||||
|
rest[_i - 1] = arguments[_i];
|
||||||
|
}
|
||||||
|
util.log.apply(util, [util.colors.cyan('[memory watch dog]'), message].concat(rest));
|
||||||
|
}
|
||||||
|
function heapUsed() {
|
||||||
|
return (process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2) + ' MB';
|
||||||
|
}
|
||||||
|
return es.through(function (data) {
|
||||||
|
this.emit('data', data);
|
||||||
|
}, function () {
|
||||||
|
log('memory usage after compilation finished: ' + heapUsed());
|
||||||
|
// It appears we are running into some variant of
|
||||||
|
// https://bugs.chromium.org/p/v8/issues/detail?id=2073
|
||||||
|
//
|
||||||
|
// Even though all references are dropped, some
|
||||||
|
// optimized methods in the TS compiler end up holding references
|
||||||
|
// to the entire TypeScript language host (>600MB)
|
||||||
|
//
|
||||||
|
// The idea is to force v8 to drop references to these
|
||||||
|
// optimized methods, by "reloading" the typescript node module
|
||||||
|
log('Reloading typescript node module...');
|
||||||
|
var resolvedName = require.resolve('typescript');
|
||||||
|
var originalModule = require.cache[resolvedName];
|
||||||
|
delete require.cache[resolvedName];
|
||||||
|
var newExports = require('typescript');
|
||||||
|
require.cache[resolvedName] = originalModule;
|
||||||
|
for (var prop in newExports) {
|
||||||
|
if (newExports.hasOwnProperty(prop)) {
|
||||||
|
originalModule.exports[prop] = newExports[prop];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log('typescript node module reloaded.');
|
||||||
|
this.emit('end');
|
||||||
|
});
|
||||||
|
}
|
||||||
function monacodtsTask(out, isWatch) {
|
function monacodtsTask(out, isWatch) {
|
||||||
var basePath = path.resolve(process.cwd(), out);
|
|
||||||
var neededFiles = {};
|
var neededFiles = {};
|
||||||
monacodts.getFilesToWatch(out).forEach(function (filePath) {
|
monacodts.getFilesToWatch(out).forEach(function (filePath) {
|
||||||
filePath = path.normalize(filePath);
|
filePath = path.normalize(filePath);
|
||||||
@@ -132,7 +160,7 @@ function monacodtsTask(out, isWatch) {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
resultStream = es.through(function (data) {
|
resultStream = es.through(function (data) {
|
||||||
var filePath = path.normalize(path.resolve(basePath, data.relative));
|
var filePath = path.normalize(data.path);
|
||||||
if (neededFiles[filePath]) {
|
if (neededFiles[filePath]) {
|
||||||
setInputFile(filePath, data.contents.toString());
|
setInputFile(filePath, data.contents.toString());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,9 +25,6 @@ const rootDir = path.join(__dirname, '../../src');
|
|||||||
const options = require('../../src/tsconfig.json').compilerOptions;
|
const options = require('../../src/tsconfig.json').compilerOptions;
|
||||||
options.verbose = false;
|
options.verbose = false;
|
||||||
options.sourceMap = true;
|
options.sourceMap = true;
|
||||||
if (process.env['VSCODE_NO_SOURCEMAP']) { // To be used by developers in a hurry
|
|
||||||
options.sourceMap = false;
|
|
||||||
}
|
|
||||||
options.rootDir = rootDir;
|
options.rootDir = rootDir;
|
||||||
options.sourceRoot = util.toFileUri(rootDir);
|
options.sourceRoot = util.toFileUri(rootDir);
|
||||||
|
|
||||||
@@ -52,6 +49,7 @@ function createCompile(build: boolean, emitError?: boolean): (token?: util.ICanc
|
|||||||
.pipe(tsFilter)
|
.pipe(tsFilter)
|
||||||
.pipe(util.loadSourcemaps())
|
.pipe(util.loadSourcemaps())
|
||||||
.pipe(ts(token))
|
.pipe(ts(token))
|
||||||
|
// .pipe(build ? reloadTypeScriptNodeModule() : es.through())
|
||||||
.pipe(noDeclarationsFilter)
|
.pipe(noDeclarationsFilter)
|
||||||
.pipe(build ? nls() : es.through())
|
.pipe(build ? nls() : es.through())
|
||||||
.pipe(noDeclarationsFilter.restore)
|
.pipe(noDeclarationsFilter.restore)
|
||||||
@@ -77,14 +75,9 @@ export function compileTask(out: string, build: boolean): () => NodeJS.ReadWrite
|
|||||||
gulp.src('node_modules/typescript/lib/lib.d.ts'),
|
gulp.src('node_modules/typescript/lib/lib.d.ts'),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Do not write .d.ts files to disk, as they are not needed there.
|
|
||||||
const dtsFilter = util.filter(data => !/\.d\.ts$/.test(data.path));
|
|
||||||
|
|
||||||
return src
|
return src
|
||||||
.pipe(compile())
|
.pipe(compile())
|
||||||
.pipe(dtsFilter)
|
|
||||||
.pipe(gulp.dest(out))
|
.pipe(gulp.dest(out))
|
||||||
.pipe(dtsFilter.restore)
|
|
||||||
.pipe(monacodtsTask(out, false));
|
.pipe(monacodtsTask(out, false));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -100,21 +93,61 @@ export function watchTask(out: string, build: boolean): () => NodeJS.ReadWriteSt
|
|||||||
);
|
);
|
||||||
const watchSrc = watch('src/**', { base: 'src' });
|
const watchSrc = watch('src/**', { base: 'src' });
|
||||||
|
|
||||||
// Do not write .d.ts files to disk, as they are not needed there.
|
|
||||||
const dtsFilter = util.filter(data => !/\.d\.ts$/.test(data.path));
|
|
||||||
|
|
||||||
return watchSrc
|
return watchSrc
|
||||||
.pipe(util.incremental(compile, src, true))
|
.pipe(util.incremental(compile, src, true))
|
||||||
.pipe(dtsFilter)
|
|
||||||
.pipe(gulp.dest(out))
|
.pipe(gulp.dest(out))
|
||||||
.pipe(dtsFilter.restore)
|
|
||||||
.pipe(monacodtsTask(out, true));
|
.pipe(monacodtsTask(out, true));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function monacodtsTask(out: string, isWatch: boolean): NodeJS.ReadWriteStream {
|
function reloadTypeScriptNodeModule(): NodeJS.ReadWriteStream {
|
||||||
|
var util = require('gulp-util');
|
||||||
|
function log(message: any, ...rest: any[]): void {
|
||||||
|
util.log(util.colors.cyan('[memory watch dog]'), message, ...rest);
|
||||||
|
}
|
||||||
|
|
||||||
const basePath = path.resolve(process.cwd(), out);
|
function heapUsed(): string {
|
||||||
|
return (process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2) + ' MB';
|
||||||
|
}
|
||||||
|
|
||||||
|
return es.through(function (data) {
|
||||||
|
this.emit('data', data);
|
||||||
|
}, function () {
|
||||||
|
|
||||||
|
log('memory usage after compilation finished: ' + heapUsed());
|
||||||
|
|
||||||
|
// It appears we are running into some variant of
|
||||||
|
// https://bugs.chromium.org/p/v8/issues/detail?id=2073
|
||||||
|
//
|
||||||
|
// Even though all references are dropped, some
|
||||||
|
// optimized methods in the TS compiler end up holding references
|
||||||
|
// to the entire TypeScript language host (>600MB)
|
||||||
|
//
|
||||||
|
// The idea is to force v8 to drop references to these
|
||||||
|
// optimized methods, by "reloading" the typescript node module
|
||||||
|
|
||||||
|
log('Reloading typescript node module...');
|
||||||
|
|
||||||
|
var resolvedName = require.resolve('typescript');
|
||||||
|
|
||||||
|
var originalModule = require.cache[resolvedName];
|
||||||
|
delete require.cache[resolvedName];
|
||||||
|
var newExports = require('typescript');
|
||||||
|
require.cache[resolvedName] = originalModule;
|
||||||
|
|
||||||
|
for (var prop in newExports) {
|
||||||
|
if (newExports.hasOwnProperty(prop)) {
|
||||||
|
originalModule.exports[prop] = newExports[prop];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log('typescript node module reloaded.');
|
||||||
|
|
||||||
|
this.emit('end');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function monacodtsTask(out: string, isWatch: boolean): NodeJS.ReadWriteStream {
|
||||||
|
|
||||||
const neededFiles: { [file: string]: boolean; } = {};
|
const neededFiles: { [file: string]: boolean; } = {};
|
||||||
monacodts.getFilesToWatch(out).forEach(function (filePath) {
|
monacodts.getFilesToWatch(out).forEach(function (filePath) {
|
||||||
@@ -163,7 +196,7 @@ function monacodtsTask(out: string, isWatch: boolean): NodeJS.ReadWriteStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resultStream = es.through(function (data) {
|
resultStream = es.through(function (data) {
|
||||||
const filePath = path.normalize(path.resolve(basePath, data.relative));
|
const filePath = path.normalize(data.path);
|
||||||
if (neededFiles[filePath]) {
|
if (neededFiles[filePath]) {
|
||||||
setInputFile(filePath, data.contents.toString());
|
setInputFile(filePath, data.contents.toString());
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -46,6 +46,10 @@
|
|||||||
"name": "vs/workbench/parts/execution",
|
"name": "vs/workbench/parts/execution",
|
||||||
"project": "vscode-workbench"
|
"project": "vscode-workbench"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "vs/workbench/parts/explorers",
|
||||||
|
"project": "vscode-workbench"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "vs/workbench/parts/extensions",
|
"name": "vs/workbench/parts/extensions",
|
||||||
"project": "vscode-workbench"
|
"project": "vscode-workbench"
|
||||||
@@ -67,11 +71,7 @@
|
|||||||
"project": "vscode-workbench"
|
"project": "vscode-workbench"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "vs/workbench/parts/localizations",
|
"name": "vs/workbench/parts/nps",
|
||||||
"project": "vscode-workbench"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "vs/workbench/parts/logs",
|
|
||||||
"project": "vscode-workbench"
|
"project": "vscode-workbench"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -138,10 +138,6 @@
|
|||||||
"name": "vs/workbench/parts/welcome",
|
"name": "vs/workbench/parts/welcome",
|
||||||
"project": "vscode-workbench"
|
"project": "vscode-workbench"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "vs/workbench/services/actions",
|
|
||||||
"project": "vscode-workbench"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "vs/workbench/services/configuration",
|
"name": "vs/workbench/services/configuration",
|
||||||
"project": "vscode-workbench"
|
"project": "vscode-workbench"
|
||||||
@@ -150,10 +146,6 @@
|
|||||||
"name": "vs/workbench/services/crashReporter",
|
"name": "vs/workbench/services/crashReporter",
|
||||||
"project": "vscode-workbench"
|
"project": "vscode-workbench"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "vs/workbench/services/dialogs",
|
|
||||||
"project": "vscode-workbench"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "vs/workbench/services/editor",
|
"name": "vs/workbench/services/editor",
|
||||||
"project": "vscode-workbench"
|
"project": "vscode-workbench"
|
||||||
@@ -162,10 +154,6 @@
|
|||||||
"name": "vs/workbench/services/extensions",
|
"name": "vs/workbench/services/extensions",
|
||||||
"project": "vscode-workbench"
|
"project": "vscode-workbench"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "vs/workbench/services/jsonschemas",
|
|
||||||
"project": "vscode-workbench"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "vs/workbench/services/files",
|
"name": "vs/workbench/services/files",
|
||||||
"project": "vscode-workbench"
|
"project": "vscode-workbench"
|
||||||
@@ -174,6 +162,10 @@
|
|||||||
"name": "vs/workbench/services/keybinding",
|
"name": "vs/workbench/services/keybinding",
|
||||||
"project": "vscode-workbench"
|
"project": "vscode-workbench"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "vs/workbench/services/message",
|
||||||
|
"project": "vscode-workbench"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "vs/workbench/services/mode",
|
"name": "vs/workbench/services/mode",
|
||||||
"project": "vscode-workbench"
|
"project": "vscode-workbench"
|
||||||
@@ -201,6 +193,10 @@
|
|||||||
{
|
{
|
||||||
"name": "vs/workbench/services/decorations",
|
"name": "vs/workbench/services/decorations",
|
||||||
"project": "vscode-workbench"
|
"project": "vscode-workbench"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "setup_messages",
|
||||||
|
"project": "vscode-workbench"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
1032
build/lib/i18n.ts
1032
build/lib/i18n.ts
File diff suppressed because it is too large
Load Diff
@@ -79,7 +79,7 @@ function isImportNode(node) {
|
|||||||
function fileFrom(file, contents, path) {
|
function fileFrom(file, contents, path) {
|
||||||
if (path === void 0) { path = file.path; }
|
if (path === void 0) { path = file.path; }
|
||||||
return new File({
|
return new File({
|
||||||
contents: Buffer.from(contents),
|
contents: new Buffer(contents),
|
||||||
base: file.base,
|
base: file.base,
|
||||||
cwd: file.cwd,
|
cwd: file.cwd,
|
||||||
path: path
|
path: path
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ module nls {
|
|||||||
|
|
||||||
export function fileFrom(file: File, contents: string, path: string = file.path) {
|
export function fileFrom(file: File, contents: string, path: string = file.path) {
|
||||||
return new File({
|
return new File({
|
||||||
contents: Buffer.from(contents),
|
contents: new Buffer(contents),
|
||||||
base: file.base,
|
base: file.base,
|
||||||
cwd: file.cwd,
|
cwd: file.cwd,
|
||||||
path: path
|
path: path
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ function loader(bundledFileHeader, bundleLoader) {
|
|||||||
this.emit('data', new VinylFile({
|
this.emit('data', new VinylFile({
|
||||||
path: 'fake',
|
path: 'fake',
|
||||||
base: '',
|
base: '',
|
||||||
contents: Buffer.from(bundledFileHeader)
|
contents: new Buffer(bundledFileHeader)
|
||||||
}));
|
}));
|
||||||
this.emit('data', data);
|
this.emit('data', data);
|
||||||
}
|
}
|
||||||
@@ -98,7 +98,7 @@ function toConcatStream(bundledFileHeader, sources, dest) {
|
|||||||
return new VinylFile({
|
return new VinylFile({
|
||||||
path: source.path ? root + '/' + source.path.replace(/\\/g, '/') : 'fake',
|
path: source.path ? root + '/' + source.path.replace(/\\/g, '/') : 'fake',
|
||||||
base: base,
|
base: base,
|
||||||
contents: Buffer.from(source.contents)
|
contents: new Buffer(source.contents)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return es.readArray(treatedSources)
|
return es.readArray(treatedSources)
|
||||||
@@ -141,7 +141,7 @@ function optimizeTask(opts) {
|
|||||||
bundleInfoArray.push(new VinylFile({
|
bundleInfoArray.push(new VinylFile({
|
||||||
path: 'bundleInfo.json',
|
path: 'bundleInfo.json',
|
||||||
base: '.',
|
base: '.',
|
||||||
contents: Buffer.from(JSON.stringify(result.bundleData, null, '\t'))
|
contents: new Buffer(JSON.stringify(result.bundleData, null, '\t'))
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
es.readArray(bundleInfoArray).pipe(bundleInfoStream);
|
es.readArray(bundleInfoArray).pipe(bundleInfoStream);
|
||||||
@@ -174,6 +174,7 @@ function optimizeTask(opts) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
exports.optimizeTask = optimizeTask;
|
exports.optimizeTask = optimizeTask;
|
||||||
|
;
|
||||||
/**
|
/**
|
||||||
* Wrap around uglify and allow the preserveComments function
|
* Wrap around uglify and allow the preserveComments function
|
||||||
* to have a file "context" to include our copyright only once per file.
|
* to have a file "context" to include our copyright only once per file.
|
||||||
@@ -236,3 +237,4 @@ function minifyTask(src, sourceMapBaseUrl) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
exports.minifyTask = minifyTask;
|
exports.minifyTask = minifyTask;
|
||||||
|
;
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ function log(prefix: string, message: string): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
export function loaderConfig(emptyPaths?: string[]) {
|
export function loaderConfig(emptyPaths: string[]) {
|
||||||
const result = {
|
const result = {
|
||||||
paths: {
|
paths: {
|
||||||
'vs': 'out-build/vs',
|
'vs': 'out-build/vs',
|
||||||
@@ -73,7 +73,7 @@ function loader(bundledFileHeader: string, bundleLoader: boolean): NodeJS.ReadWr
|
|||||||
this.emit('data', new VinylFile({
|
this.emit('data', new VinylFile({
|
||||||
path: 'fake',
|
path: 'fake',
|
||||||
base: '',
|
base: '',
|
||||||
contents: Buffer.from(bundledFileHeader)
|
contents: new Buffer(bundledFileHeader)
|
||||||
}));
|
}));
|
||||||
this.emit('data', data);
|
this.emit('data', data);
|
||||||
} else {
|
} else {
|
||||||
@@ -117,7 +117,7 @@ function toConcatStream(bundledFileHeader: string, sources: bundle.IFile[], dest
|
|||||||
return new VinylFile({
|
return new VinylFile({
|
||||||
path: source.path ? root + '/' + source.path.replace(/\\/g, '/') : 'fake',
|
path: source.path ? root + '/' + source.path.replace(/\\/g, '/') : 'fake',
|
||||||
base: base,
|
base: base,
|
||||||
contents: Buffer.from(source.contents)
|
contents: new Buffer(source.contents)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -165,7 +165,7 @@ export interface IOptimizeTaskOpts {
|
|||||||
/**
|
/**
|
||||||
* (languages to process)
|
* (languages to process)
|
||||||
*/
|
*/
|
||||||
languages: i18n.Language[];
|
languages: string[];
|
||||||
}
|
}
|
||||||
export function optimizeTask(opts: IOptimizeTaskOpts): () => NodeJS.ReadWriteStream {
|
export function optimizeTask(opts: IOptimizeTaskOpts): () => NodeJS.ReadWriteStream {
|
||||||
const entryPoints = opts.entryPoints;
|
const entryPoints = opts.entryPoints;
|
||||||
@@ -201,7 +201,7 @@ export function optimizeTask(opts: IOptimizeTaskOpts): () => NodeJS.ReadWriteStr
|
|||||||
bundleInfoArray.push(new VinylFile({
|
bundleInfoArray.push(new VinylFile({
|
||||||
path: 'bundleInfo.json',
|
path: 'bundleInfo.json',
|
||||||
base: '.',
|
base: '.',
|
||||||
contents: Buffer.from(JSON.stringify(result.bundleData, null, '\t'))
|
contents: new Buffer(JSON.stringify(result.bundleData, null, '\t'))
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
es.readArray(bundleInfoArray).pipe(bundleInfoStream);
|
es.readArray(bundleInfoArray).pipe(bundleInfoStream);
|
||||||
@@ -241,7 +241,7 @@ export function optimizeTask(opts: IOptimizeTaskOpts): () => NodeJS.ReadWriteStr
|
|||||||
}))
|
}))
|
||||||
.pipe(gulp.dest(out));
|
.pipe(gulp.dest(out));
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
declare class FileWithCopyright extends VinylFile {
|
declare class FileWithCopyright extends VinylFile {
|
||||||
public __hasOurCopyright: boolean;
|
public __hasOurCopyright: boolean;
|
||||||
@@ -295,7 +295,7 @@ function uglifyWithCopyrights(): NodeJS.ReadWriteStream {
|
|||||||
return es.duplex(input, output);
|
return es.duplex(input, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function minifyTask(src: string, sourceMapBaseUrl?: string): (cb: any) => void {
|
export function minifyTask(src: string, sourceMapBaseUrl: string): (cb: any) => void {
|
||||||
const sourceMappingURL = sourceMapBaseUrl && (f => `${sourceMapBaseUrl}/${f.relative}.map`);
|
const sourceMappingURL = sourceMapBaseUrl && (f => `${sourceMapBaseUrl}/${f.relative}.map`);
|
||||||
|
|
||||||
return cb => {
|
return cb => {
|
||||||
@@ -326,4 +326,4 @@ export function minifyTask(src: string, sourceMapBaseUrl?: string): (cb: any) =>
|
|||||||
cb(err);
|
cb(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|||||||
9
build/lib/typings/event-stream.d.ts
vendored
9
build/lib/typings/event-stream.d.ts
vendored
@@ -1,14 +1,7 @@
|
|||||||
declare module "event-stream" {
|
declare module "event-stream" {
|
||||||
import { Stream } from 'stream';
|
import { Stream } from 'stream';
|
||||||
import { ThroughStream as _ThroughStream} from 'through';
|
import { ThroughStream } from 'through';
|
||||||
import { MapStream } from 'map-stream';
|
import { MapStream } from 'map-stream';
|
||||||
import * as File from 'vinyl';
|
|
||||||
|
|
||||||
export interface ThroughStream extends _ThroughStream {
|
|
||||||
queue(data: File | null);
|
|
||||||
push(data: File | null);
|
|
||||||
paused: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
function merge(streams: Stream[]): ThroughStream;
|
function merge(streams: Stream[]): ThroughStream;
|
||||||
function merge(...streams: Stream[]): ThroughStream;
|
function merge(...streams: Stream[]): ThroughStream;
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ function loadSourcemaps() {
|
|||||||
cb(null, f);
|
cb(null, f);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
f.contents = Buffer.from(contents.replace(/\/\/# sourceMappingURL=(.*)$/g, ''), 'utf8');
|
f.contents = new Buffer(contents.replace(/\/\/# sourceMappingURL=(.*)$/g, ''), 'utf8');
|
||||||
fs.readFile(path.join(path.dirname(f.path), lastMatch[1]), 'utf8', function (err, contents) {
|
fs.readFile(path.join(path.dirname(f.path), lastMatch[1]), 'utf8', function (err, contents) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return cb(err);
|
return cb(err);
|
||||||
@@ -160,7 +160,7 @@ function stripSourceMappingURL() {
|
|||||||
var output = input
|
var output = input
|
||||||
.pipe(es.mapSync(function (f) {
|
.pipe(es.mapSync(function (f) {
|
||||||
var contents = f.contents.toString('utf8');
|
var contents = f.contents.toString('utf8');
|
||||||
f.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, ''), 'utf8');
|
f.contents = new Buffer(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, ''), 'utf8');
|
||||||
return f;
|
return f;
|
||||||
}));
|
}));
|
||||||
return es.duplex(input, output);
|
return es.duplex(input, output);
|
||||||
@@ -173,6 +173,7 @@ function rimraf(dir) {
|
|||||||
if (!err) {
|
if (!err) {
|
||||||
return cb();
|
return cb();
|
||||||
}
|
}
|
||||||
|
;
|
||||||
if (err.code === 'ENOTEMPTY' && ++retries < 5) {
|
if (err.code === 'ENOTEMPTY' && ++retries < 5) {
|
||||||
return setTimeout(function () { return retry(cb); }, 10);
|
return setTimeout(function () { return retry(cb); }, 10);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export interface IStreamProvider {
|
|||||||
(cancellationToken?: ICancellationToken): NodeJS.ReadWriteStream;
|
(cancellationToken?: ICancellationToken): NodeJS.ReadWriteStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function incremental(streamProvider: IStreamProvider, initial: NodeJS.ReadWriteStream, supportsCancellation?: boolean): NodeJS.ReadWriteStream {
|
export function incremental(streamProvider: IStreamProvider, initial: NodeJS.ReadWriteStream, supportsCancellation: boolean): NodeJS.ReadWriteStream {
|
||||||
const input = es.through();
|
const input = es.through();
|
||||||
const output = es.through();
|
const output = es.through();
|
||||||
let state = 'idle';
|
let state = 'idle';
|
||||||
@@ -129,7 +129,7 @@ export function skipDirectories(): NodeJS.ReadWriteStream {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function cleanNodeModule(name: string, excludes: string[], includes?: string[]): NodeJS.ReadWriteStream {
|
export function cleanNodeModule(name: string, excludes: string[], includes: string[]): NodeJS.ReadWriteStream {
|
||||||
const toGlob = (path: string) => '**/node_modules/' + name + (path ? '/' + path : '');
|
const toGlob = (path: string) => '**/node_modules/' + name + (path ? '/' + path : '');
|
||||||
const negate = (str: string) => '!' + str;
|
const negate = (str: string) => '!' + str;
|
||||||
|
|
||||||
@@ -190,7 +190,7 @@ export function loadSourcemaps(): NodeJS.ReadWriteStream {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
f.contents = Buffer.from(contents.replace(/\/\/# sourceMappingURL=(.*)$/g, ''), 'utf8');
|
f.contents = new Buffer(contents.replace(/\/\/# sourceMappingURL=(.*)$/g, ''), 'utf8');
|
||||||
|
|
||||||
fs.readFile(path.join(path.dirname(f.path), lastMatch[1]), 'utf8', (err, contents) => {
|
fs.readFile(path.join(path.dirname(f.path), lastMatch[1]), 'utf8', (err, contents) => {
|
||||||
if (err) { return cb(err); }
|
if (err) { return cb(err); }
|
||||||
@@ -209,7 +209,7 @@ export function stripSourceMappingURL(): NodeJS.ReadWriteStream {
|
|||||||
const output = input
|
const output = input
|
||||||
.pipe(es.mapSync<VinylFile, VinylFile>(f => {
|
.pipe(es.mapSync<VinylFile, VinylFile>(f => {
|
||||||
const contents = (<Buffer>f.contents).toString('utf8');
|
const contents = (<Buffer>f.contents).toString('utf8');
|
||||||
f.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, ''), 'utf8');
|
f.contents = new Buffer(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, ''), 'utf8');
|
||||||
return f;
|
return f;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -223,7 +223,7 @@ export function rimraf(dir: string): (cb: any) => void {
|
|||||||
_rimraf(dir, { maxBusyTries: 1 }, (err: any) => {
|
_rimraf(dir, { maxBusyTries: 1 }, (err: any) => {
|
||||||
if (!err) {
|
if (!err) {
|
||||||
return cb();
|
return cb();
|
||||||
}
|
};
|
||||||
|
|
||||||
if (err.code === 'ENOTEMPTY' && ++retries < 5) {
|
if (err.code === 'ENOTEMPTY' && ++retries < 5) {
|
||||||
return setTimeout(() => retry(cb), 10);
|
return setTimeout(() => retry(cb), 10);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ const es = require('event-stream');
|
|||||||
function handleDeletions() {
|
function handleDeletions() {
|
||||||
return es.mapSync(f => {
|
return es.mapSync(f => {
|
||||||
if (/\.ts$/.test(f.relative) && !f.contents) {
|
if (/\.ts$/.test(f.relative) && !f.contents) {
|
||||||
f.contents = Buffer.from('');
|
f.contents = new Buffer('');
|
||||||
f.stat = { mtime: new Date() };
|
f.stat = { mtime: new Date() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,12 +30,12 @@ function watch(root) {
|
|||||||
path: path,
|
path: path,
|
||||||
base: root
|
base: root
|
||||||
});
|
});
|
||||||
//@ts-ignore
|
|
||||||
file.event = type;
|
file.event = type;
|
||||||
result.emit('data', file);
|
result.emit('data', file);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsfw(root, function (events) {
|
nsfw(root, function(events) {
|
||||||
for (var i = 0; i < events.length; i++) {
|
for (var i = 0; i < events.length; i++) {
|
||||||
var e = events[i];
|
var e = events[i];
|
||||||
var changeType = e.action;
|
var changeType = e.action;
|
||||||
@@ -47,16 +47,16 @@ function watch(root) {
|
|||||||
handleEvent(path.join(e.directory, e.file), toChangeType(changeType));
|
handleEvent(path.join(e.directory, e.file), toChangeType(changeType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).then(function (watcher) {
|
}).then(function(watcher) {
|
||||||
watcher.start();
|
watcher.start();
|
||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
var cache = Object.create(null);
|
var cache = Object.create(null);
|
||||||
|
|
||||||
module.exports = function (pattern, options) {
|
module.exports = function(pattern, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
var cwd = path.normalize(options.cwd || process.cwd());
|
var cwd = path.normalize(options.cwd || process.cwd());
|
||||||
@@ -66,7 +66,7 @@ module.exports = function (pattern, options) {
|
|||||||
watcher = cache[cwd] = watch(cwd);
|
watcher = cache[cwd] = watch(cwd);
|
||||||
}
|
}
|
||||||
|
|
||||||
var rebase = !options.base ? es.through() : es.mapSync(function (f) {
|
var rebase = !options.base ? es.through() : es.mapSync(function(f) {
|
||||||
f.base = options.base;
|
f.base = options.base;
|
||||||
return f;
|
return f;
|
||||||
});
|
});
|
||||||
@@ -74,13 +74,13 @@ module.exports = function (pattern, options) {
|
|||||||
return watcher
|
return watcher
|
||||||
.pipe(filter(['**', '!.git{,/**}'])) // ignore all things git
|
.pipe(filter(['**', '!.git{,/**}'])) // ignore all things git
|
||||||
.pipe(filter(pattern))
|
.pipe(filter(pattern))
|
||||||
.pipe(es.map(function (file, cb) {
|
.pipe(es.map(function(file, cb) {
|
||||||
fs.stat(file.path, function (err, stat) {
|
fs.stat(file.path, function(err, stat) {
|
||||||
if (err && err.code === 'ENOENT') { return cb(null, file); }
|
if (err && err.code === 'ENOENT') { return cb(null, file); }
|
||||||
if (err) { return cb(); }
|
if (err) { return cb(); }
|
||||||
if (!stat.isFile()) { return cb(); }
|
if (!stat.isFile()) { return cb(); }
|
||||||
|
|
||||||
fs.readFile(file.path, function (err, contents) {
|
fs.readFile(file.path, function(err, contents) {
|
||||||
if (err && err.code === 'ENOENT') { return cb(null, file); }
|
if (err && err.code === 'ENOENT') { return cb(null, file); }
|
||||||
if (err) { return cb(); }
|
if (err) { return cb(); }
|
||||||
|
|
||||||
|
|||||||
@@ -24,8 +24,7 @@ function watch(root) {
|
|||||||
var result = es.through();
|
var result = es.through();
|
||||||
var child = cp.spawn(watcherPath, [root]);
|
var child = cp.spawn(watcherPath, [root]);
|
||||||
|
|
||||||
child.stdout.on('data', function (data) {
|
child.stdout.on('data', function(data) {
|
||||||
// @ts-ignore
|
|
||||||
var lines = data.toString('utf8').split('\n');
|
var lines = data.toString('utf8').split('\n');
|
||||||
for (var i = 0; i < lines.length; i++) {
|
for (var i = 0; i < lines.length; i++) {
|
||||||
var line = lines[i].trim();
|
var line = lines[i].trim();
|
||||||
@@ -47,17 +46,17 @@ function watch(root) {
|
|||||||
path: changePathFull,
|
path: changePathFull,
|
||||||
base: root
|
base: root
|
||||||
});
|
});
|
||||||
//@ts-ignore
|
|
||||||
file.event = toChangeType(changeType);
|
file.event = toChangeType(changeType);
|
||||||
result.emit('data', file);
|
result.emit('data', file);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
child.stderr.on('data', function (data) {
|
child.stderr.on('data', function(data) {
|
||||||
result.emit('error', data);
|
result.emit('error', data);
|
||||||
});
|
});
|
||||||
|
|
||||||
child.on('exit', function (code) {
|
child.on('exit', function(code) {
|
||||||
result.emit('error', 'Watcher died with code ' + code);
|
result.emit('error', 'Watcher died with code ' + code);
|
||||||
child = null;
|
child = null;
|
||||||
});
|
});
|
||||||
@@ -71,7 +70,7 @@ function watch(root) {
|
|||||||
|
|
||||||
var cache = Object.create(null);
|
var cache = Object.create(null);
|
||||||
|
|
||||||
module.exports = function (pattern, options) {
|
module.exports = function(pattern, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
var cwd = path.normalize(options.cwd || process.cwd());
|
var cwd = path.normalize(options.cwd || process.cwd());
|
||||||
|
|||||||
@@ -1,21 +1 @@
|
|||||||
The Source EULA
|
See project root directory
|
||||||
|
|
||||||
Copyright (c) 2016 Microsoft Corporation
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
@@ -32,7 +32,7 @@ END OF winjs NOTICES AND INFORMATION
|
|||||||
|
|
||||||
%% string_scorer version 0.1.20 (https://github.com/joshaven/string_score)
|
%% string_scorer version 0.1.20 (https://github.com/joshaven/string_score)
|
||||||
=========================================
|
=========================================
|
||||||
This software is released under the Source EULA:
|
This software is released under the MIT license:
|
||||||
|
|
||||||
Copyright (c) Joshaven Potter
|
Copyright (c) Joshaven Potter
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ END OF string_scorer NOTICES AND INFORMATION
|
|||||||
|
|
||||||
%% chjj-marked NOTICES AND INFORMATION BEGIN HERE
|
%% chjj-marked NOTICES AND INFORMATION BEGIN HERE
|
||||||
=========================================
|
=========================================
|
||||||
The Source EULA
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2011-2014, Christopher Jeffrey (https://github.com/chjj/)
|
Copyright (c) 2011-2014, Christopher Jeffrey (https://github.com/chjj/)
|
||||||
|
|
||||||
|
|||||||
@@ -62,24 +62,19 @@ export interface ICommandHandler {
|
|||||||
#include(vs/editor/standalone/browser/colorizer): IColorizerOptions, IColorizerElementOptions
|
#include(vs/editor/standalone/browser/colorizer): IColorizerOptions, IColorizerElementOptions
|
||||||
#include(vs/base/common/scrollable): ScrollbarVisibility
|
#include(vs/base/common/scrollable): ScrollbarVisibility
|
||||||
#include(vs/platform/theme/common/themeService): ThemeColor
|
#include(vs/platform/theme/common/themeService): ThemeColor
|
||||||
#includeAll(vs/editor/common/model;LanguageIdentifier=>languages.LanguageIdentifier): IScrollEvent
|
#includeAll(vs/editor/common/editorCommon;IMode=>languages.IMode;LanguageIdentifier=>languages.LanguageIdentifier;editorOptions.=>): ISelection, IScrollEvent
|
||||||
#includeAll(vs/editor/common/editorCommon;editorOptions.=>): IScrollEvent
|
|
||||||
#includeAll(vs/editor/common/model/textModelEvents):
|
#includeAll(vs/editor/common/model/textModelEvents):
|
||||||
#includeAll(vs/editor/common/controller/cursorEvents):
|
#includeAll(vs/editor/common/controller/cursorEvents):
|
||||||
#includeAll(vs/editor/common/config/editorOptions):
|
#includeAll(vs/editor/common/config/editorOptions):
|
||||||
#includeAll(vs/editor/browser/editorBrowser;editorCommon.=>;editorOptions.=>):
|
#includeAll(vs/editor/browser/editorBrowser;editorCommon.=>;editorOptions.=>):
|
||||||
#include(vs/editor/common/config/fontInfo): FontInfo, BareFontInfo
|
#include(vs/editor/common/config/fontInfo): FontInfo, BareFontInfo
|
||||||
|
|
||||||
//compatibility:
|
|
||||||
export type IReadOnlyModel = ITextModel;
|
|
||||||
export type IModel = ITextModel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module monaco.languages {
|
declare module monaco.languages {
|
||||||
|
|
||||||
#includeAll(vs/editor/standalone/browser/standaloneLanguages;modes.=>;editorCommon.=>editor.;model.=>editor.;IMarkerData=>editor.IMarkerData):
|
#includeAll(vs/editor/standalone/browser/standaloneLanguages;modes.=>;editorCommon.=>editor.;IMarkerData=>editor.IMarkerData):
|
||||||
#includeAll(vs/editor/common/modes/languageConfiguration):
|
#includeAll(vs/editor/common/modes/languageConfiguration):
|
||||||
#includeAll(vs/editor/common/modes;editorCommon.IRange=>IRange;editorCommon.IPosition=>IPosition;editorCommon.=>editor.;IMarkerData=>editor.IMarkerData;model.=>editor.):
|
#includeAll(vs/editor/common/modes;editorCommon.IRange=>IRange;editorCommon.IPosition=>IPosition;editorCommon.=>editor.;IMarkerData=>editor.IMarkerData):
|
||||||
#include(vs/editor/common/services/modeService): ILanguageExtensionPoint
|
#include(vs/editor/common/services/modeService): ILanguageExtensionPoint
|
||||||
#includeAll(vs/editor/standalone/common/monarch/monarchTypes):
|
#includeAll(vs/editor/standalone/common/monarch/monarchTypes):
|
||||||
|
|
||||||
|
|||||||
@@ -21,21 +21,21 @@ function yarnInstall(location, opts) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// {{SQL CARBON EDIT}}
|
// {{SQL CARBON EDIT}}
|
||||||
|
yarnInstall('dataprotocol-client');
|
||||||
|
yarnInstall('extensions-modules');
|
||||||
yarnInstall('extensions'); // node modules shared by all extensions
|
yarnInstall('extensions'); // node modules shared by all extensions
|
||||||
|
|
||||||
const extensions = [
|
const extensions = [
|
||||||
'vscode-colorize-tests',
|
'vscode-colorize-tests',
|
||||||
'json',
|
'json',
|
||||||
'mssql',
|
'mssql',
|
||||||
'configuration-editing',
|
'configuration-editing',
|
||||||
'extension-editing',
|
'extension-editing',
|
||||||
'markdown',
|
'markdown',
|
||||||
'markdown-basics',
|
|
||||||
'git',
|
'git',
|
||||||
'merge-conflict',
|
'merge-conflict',
|
||||||
'insights-default',
|
'insights-default',
|
||||||
'account-provider-azure',
|
'account-provider-azure'
|
||||||
'agent'
|
|
||||||
];
|
];
|
||||||
|
|
||||||
extensions.forEach(extension => yarnInstall(`extensions/${extension}`));
|
extensions.forEach(extension => yarnInstall(`extensions/${extension}`));
|
||||||
@@ -43,7 +43,6 @@ extensions.forEach(extension => yarnInstall(`extensions/${extension}`));
|
|||||||
function yarnInstallBuildDependencies() {
|
function yarnInstallBuildDependencies() {
|
||||||
// make sure we install the deps of build/lib/watch for the system installed
|
// make sure we install the deps of build/lib/watch for the system installed
|
||||||
// node, since that is the driver of gulp
|
// node, since that is the driver of gulp
|
||||||
//@ts-ignore
|
|
||||||
const env = Object.assign({}, process.env);
|
const env = Object.assign({}, process.env);
|
||||||
const watchPath = path.join(path.dirname(__dirname), 'lib', 'watch');
|
const watchPath = path.join(path.dirname(__dirname), 'lib', 'watch');
|
||||||
const yarnrcPath = path.join(watchPath, '.yarnrc');
|
const yarnrcPath = path.join(watchPath, '.yarnrc');
|
||||||
@@ -61,5 +60,4 @@ runtime "${runtime}"`;
|
|||||||
}
|
}
|
||||||
|
|
||||||
yarnInstall(`build`); // node modules required for build
|
yarnInstall(`build`); // node modules required for build
|
||||||
yarnInstall('test/smoke'); // node modules required for smoketest
|
|
||||||
yarnInstallBuildDependencies(); // node modules for watching, specific to host node version, not electron
|
yarnInstallBuildDependencies(); // node modules for watching, specific to host node version, not electron
|
||||||
@@ -4,11 +4,9 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
const cp = require('child_process');
|
const cp = require('child_process');
|
||||||
const fs = require('fs');
|
const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
function updateGrammar(location) {
|
function updateGrammar(location) {
|
||||||
const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
||||||
const result = cp.spawnSync(npm, ['run', 'update-grammar'], {
|
const result = cp.spawnSync(npm, ['run', 'update-grammar'], {
|
||||||
cwd: location,
|
cwd: location,
|
||||||
stdio: 'inherit'
|
stdio: 'inherit'
|
||||||
@@ -19,17 +17,50 @@ function updateGrammar(location) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const allExtensionFolders = fs.readdirSync('extensions');
|
const extensions = [
|
||||||
const extensions = allExtensionFolders.filter(e => {
|
'bat',
|
||||||
try {
|
'clojure',
|
||||||
let packageJSON = JSON.parse(fs.readFileSync(path.join('extensions', e, 'package.json')).toString());
|
'coffeescript',
|
||||||
return packageJSON && packageJSON.scripts && packageJSON.scripts['update-grammar'];
|
'cpp',
|
||||||
} catch (e) {
|
'csharp',
|
||||||
return false;
|
'css',
|
||||||
}
|
'diff',
|
||||||
});
|
'docker',
|
||||||
|
'fsharp',
|
||||||
console.log(`Updating ${extensions.length} grammars...`);
|
'gitsyntax',
|
||||||
|
'go',
|
||||||
|
'groovy',
|
||||||
|
'handlebars',
|
||||||
|
'hlsl',
|
||||||
|
'html',
|
||||||
|
'ini',
|
||||||
|
'java',
|
||||||
|
// 'javascript', updated through JavaScript
|
||||||
|
'json',
|
||||||
|
'less',
|
||||||
|
'lua',
|
||||||
|
'make',
|
||||||
|
'markdown',
|
||||||
|
'objective-c',
|
||||||
|
'perl',
|
||||||
|
'php',
|
||||||
|
// 'powershell', grammar not ready yet, @daviwil will ping when ready
|
||||||
|
'pug',
|
||||||
|
'python',
|
||||||
|
'r',
|
||||||
|
'razor',
|
||||||
|
'ruby',
|
||||||
|
'rust',
|
||||||
|
'scss',
|
||||||
|
'shaderlab',
|
||||||
|
'shellscript',
|
||||||
|
'sql',
|
||||||
|
'swift',
|
||||||
|
'typescript',
|
||||||
|
'vb',
|
||||||
|
'xml',
|
||||||
|
'yaml'
|
||||||
|
];
|
||||||
|
|
||||||
extensions.forEach(extension => updateGrammar(`extensions/${extension}`));
|
extensions.forEach(extension => updateGrammar(`extensions/${extension}`));
|
||||||
|
|
||||||
@@ -39,5 +70,4 @@ if (process.platform === 'win32') {
|
|||||||
cp.spawn('.\scripts\test-integration.bat', [], { env: process.env, stdio: 'inherit' });
|
cp.spawn('.\scripts\test-integration.bat', [], { env: process.env, stdio: 'inherit' });
|
||||||
} else {
|
} else {
|
||||||
cp.spawn('/bin/bash', ['./scripts/test-integration.sh'], { env: process.env, stdio: 'inherit' });
|
cp.spawn('/bin/bash', ['./scripts/test-integration.sh'], { env: process.env, stdio: 'inherit' });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -14,19 +14,14 @@ var url = require('url');
|
|||||||
|
|
||||||
function getOptions(urlString) {
|
function getOptions(urlString) {
|
||||||
var _url = url.parse(urlString);
|
var _url = url.parse(urlString);
|
||||||
var headers = {
|
|
||||||
'User-Agent': 'VSCode'
|
|
||||||
};
|
|
||||||
var token = process.env['GITHUB_TOKEN'];
|
|
||||||
if (token) {
|
|
||||||
headers['Authorization'] = 'token ' + token
|
|
||||||
}
|
|
||||||
return {
|
return {
|
||||||
protocol: _url.protocol,
|
protocol: _url.protocol,
|
||||||
host: _url.host,
|
host: _url.host,
|
||||||
port: _url.port,
|
port: _url.port,
|
||||||
path: _url.path,
|
path: _url.path,
|
||||||
headers: headers
|
headers: {
|
||||||
|
'User-Agent': 'NodeJS'
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,16 +32,12 @@ function download(url, redirectCount) {
|
|||||||
response.on('data', function (data) {
|
response.on('data', function (data) {
|
||||||
content += data.toString();
|
content += data.toString();
|
||||||
}).on('end', function () {
|
}).on('end', function () {
|
||||||
if (response.statusCode === 403 && response.headers['x-ratelimit-remaining'] === '0') {
|
|
||||||
e('GitHub API rate exceeded. Set GITHUB_TOKEN environment variable to increase rate limit.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let count = redirectCount || 0;
|
let count = redirectCount || 0;
|
||||||
if (count < 5 && response.statusCode >= 300 && response.statusCode <= 303 || response.statusCode === 307) {
|
if (count < 5 && response.statusCode >= 300 && response.statusCode <= 303 || response.statusCode === 307) {
|
||||||
let location = response.headers['location'];
|
let location = response.headers['location'];
|
||||||
if (location) {
|
if (location) {
|
||||||
console.log("Redirected " + url + " to " + location);
|
console.log("Redirected " + url + " to " + location);
|
||||||
download(location, count + 1).then(c, e);
|
download(location, count+1).then(c, e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -68,13 +59,17 @@ function getCommitSha(repoId, repoPath) {
|
|||||||
commitDate: lastCommit.commit.author.date
|
commitDate: lastCommit.commit.author.date
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return Promise.reject(new Error("Failed extracting the SHA: " + content));
|
console.error("Failed extracting the SHA: " + content);
|
||||||
|
return Promise.resolve(null);
|
||||||
}
|
}
|
||||||
|
}, function () {
|
||||||
|
console.error('Failed loading ' + commitInfo);
|
||||||
|
return Promise.resolve(null);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.update = function (repoId, repoPath, dest, modifyGrammar, version = 'master') {
|
exports.update = function (repoId, repoPath, dest, modifyGrammar) {
|
||||||
var contentPath = 'https://raw.githubusercontent.com/' + repoId + `/${version}/` + repoPath;
|
var contentPath = 'https://raw.githubusercontent.com/' + repoId + '/master/' + repoPath;
|
||||||
console.log('Reading from ' + contentPath);
|
console.log('Reading from ' + contentPath);
|
||||||
return download(contentPath).then(function (content) {
|
return download(contentPath).then(function (content) {
|
||||||
var ext = path.extname(repoPath);
|
var ext = path.extname(repoPath);
|
||||||
@@ -86,7 +81,8 @@ exports.update = function (repoId, repoPath, dest, modifyGrammar, version = 'mas
|
|||||||
} else if (ext === '.json') {
|
} else if (ext === '.json') {
|
||||||
grammar = JSON.parse(content);
|
grammar = JSON.parse(content);
|
||||||
} else {
|
} else {
|
||||||
return Promise.reject(new Error('Unknown file extension: ' + ext));
|
console.error('Unknown file extension: ' + ext);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (modifyGrammar) {
|
if (modifyGrammar) {
|
||||||
modifyGrammar(grammar);
|
modifyGrammar(grammar);
|
||||||
@@ -103,10 +99,8 @@ exports.update = function (repoId, repoPath, dest, modifyGrammar, version = 'mas
|
|||||||
if (info) {
|
if (info) {
|
||||||
result.version = 'https://github.com/' + repoId + '/commit/' + info.commitSha;
|
result.version = 'https://github.com/' + repoId + '/commit/' + info.commitSha;
|
||||||
}
|
}
|
||||||
|
for (let key in grammar) {
|
||||||
let keys = ['name', 'scopeName', 'comment', 'injections', 'patterns', 'repository'];
|
if (!result.hasOwnProperty(key)) {
|
||||||
for (let key of keys) {
|
|
||||||
if (grammar.hasOwnProperty(key)) {
|
|
||||||
result[key] = grammar[key];
|
result[key] = grammar[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -119,14 +113,11 @@ exports.update = function (repoId, repoPath, dest, modifyGrammar, version = 'mas
|
|||||||
console.log('Updated ' + path.basename(dest));
|
console.log('Updated ' + path.basename(dest));
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return Promise.reject(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}, console.error).catch(e => {
|
}, console.error);
|
||||||
console.error(e);
|
|
||||||
process.exit(1);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (path.basename(process.argv[1]) === 'update-grammar.js') {
|
if (path.basename(process.argv[1]) === 'update-grammar.js') {
|
||||||
|
|||||||
@@ -1,69 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
||||||
*--------------------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
let i18n = require("../lib/i18n");
|
|
||||||
|
|
||||||
let fs = require("fs");
|
|
||||||
let path = require("path");
|
|
||||||
let vfs = require("vinyl-fs");
|
|
||||||
let rimraf = require('rimraf');
|
|
||||||
|
|
||||||
function update(idOrPath) {
|
|
||||||
if (!idOrPath) {
|
|
||||||
throw new Error('Argument must be the location of the localization extension.');
|
|
||||||
}
|
|
||||||
let locExtFolder = idOrPath;
|
|
||||||
if (/^\w{2}(-\w+)?$/.test(idOrPath)) {
|
|
||||||
locExtFolder = '../vscode-language-pack-' + idOrPath;
|
|
||||||
}
|
|
||||||
let locExtStat = fs.statSync(locExtFolder);
|
|
||||||
if (!locExtStat || !locExtStat.isDirectory) {
|
|
||||||
throw new Error('No directory found at ' + idOrPath);
|
|
||||||
}
|
|
||||||
let packageJSON = JSON.parse(fs.readFileSync(path.join(locExtFolder, 'package.json')).toString());
|
|
||||||
let contributes = packageJSON['contributes'];
|
|
||||||
if (!contributes) {
|
|
||||||
throw new Error('The extension must define a "localizations" contribution in the "package.json"');
|
|
||||||
}
|
|
||||||
let localizations = contributes['localizations'];
|
|
||||||
if (!localizations) {
|
|
||||||
throw new Error('The extension must define a "localizations" contribution of type array in the "package.json"');
|
|
||||||
}
|
|
||||||
|
|
||||||
localizations.forEach(function (localization) {
|
|
||||||
if (!localization.languageId || !localization.languageName || !localization.localizedLanguageName) {
|
|
||||||
throw new Error('Each localization contribution must define "languageId", "languageName" and "localizedLanguageName" properties.');
|
|
||||||
}
|
|
||||||
let server = localization.server || 'www.transifex.com';
|
|
||||||
let userName = localization.userName || 'api';
|
|
||||||
let apiToken = process.env.TRANSIFEX_API_TOKEN;
|
|
||||||
let languageId = localization.transifexId || localization.languageId;
|
|
||||||
let translationDataFolder = path.join(locExtFolder, 'translations');
|
|
||||||
|
|
||||||
if (fs.existsSync(translationDataFolder) && fs.existsSync(path.join(translationDataFolder, 'main.i18n.json'))) {
|
|
||||||
console.log('Clearing \'' + translationDataFolder + '\'...');
|
|
||||||
rimraf.sync(translationDataFolder);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('Downloading translations for \'' + languageId + '\' to \'' + translationDataFolder + '\'...');
|
|
||||||
const translationPaths = [];
|
|
||||||
i18n.pullI18nPackFiles(server, userName, apiToken, { id: languageId }, translationPaths)
|
|
||||||
.pipe(vfs.dest(translationDataFolder)).on('end', function () {
|
|
||||||
localization.translations = [];
|
|
||||||
for (let tp of translationPaths) {
|
|
||||||
localization.translations.push({ id: tp.id, path: `./translations/${tp.resourceName}`});
|
|
||||||
}
|
|
||||||
fs.writeFileSync(path.join(locExtFolder, 'package.json'), JSON.stringify(packageJSON, null, '\t'));
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
if (path.basename(process.argv[1]) === 'update-localization-extension.js') {
|
|
||||||
update(process.argv[2]);
|
|
||||||
}
|
|
||||||
@@ -12,18 +12,17 @@
|
|||||||
"azure-storage": "^2.1.0",
|
"azure-storage": "^2.1.0",
|
||||||
"decompress": "^4.2.0",
|
"decompress": "^4.2.0",
|
||||||
"documentdb": "1.13.0",
|
"documentdb": "1.13.0",
|
||||||
"service-downloader": "github:anthonydresser/service-downloader#0.1.2",
|
"extensions-modules": "file:../extensions-modules",
|
||||||
"fs-extra-promise": "^1.0.1",
|
"fs-extra-promise": "^1.0.1",
|
||||||
"mime": "^1.3.4",
|
"mime": "^1.3.4",
|
||||||
"minimist": "^1.2.0",
|
"minimist": "^1.2.0",
|
||||||
"typescript": "2.6.1",
|
"typescript": "2.6.1",
|
||||||
"vscode": "^1.0.1",
|
"vscode": "^1.0.1",
|
||||||
"xml2js": "^0.4.17"
|
"xml2js": "^0.4.17"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"compile": "tsc -p tsconfig.build.json",
|
"compile": "tsc",
|
||||||
"watch": "tsc -p tsconfig.build.json --watch",
|
"watch": "tsc --watch",
|
||||||
"postinstall": "npm run compile",
|
"postinstall": "npm run compile"
|
||||||
"npmCheckJs": "tsc --noEmit"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,9 +4,9 @@ set -e
|
|||||||
# setup nvm
|
# setup nvm
|
||||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
export NVM_DIR=~/.nvm
|
export NVM_DIR=~/.nvm
|
||||||
source $(brew --prefix nvm)/nvm.sh --no-use
|
source $(brew --prefix nvm)/nvm.sh
|
||||||
else
|
else
|
||||||
source $NVM_DIR/nvm.sh --no-use
|
source $NVM_DIR/nvm.sh
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# install node
|
# install node
|
||||||
|
|||||||
@@ -70,7 +70,6 @@ interface Asset {
|
|||||||
hash: string;
|
hash: string;
|
||||||
sha256hash: string;
|
sha256hash: string;
|
||||||
size: number;
|
size: number;
|
||||||
supportsFastUpdate?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function createOrUpdate(commit: string, quality: string, platform: string, type: string, release: NewDocument, asset: Asset, isUpdate: boolean): Promise<void> {
|
function createOrUpdate(commit: string, quality: string, platform: string, type: string, release: NewDocument, asset: Asset, isUpdate: boolean): Promise<void> {
|
||||||
@@ -204,30 +203,17 @@ async function publish(commit: string, quality: string, platform: string, type:
|
|||||||
// mooncake is fussy and far away, this is needed!
|
// mooncake is fussy and far away, this is needed!
|
||||||
mooncakeBlobService.defaultClientRequestTimeoutInMs = 10 * 60 * 1000;
|
mooncakeBlobService.defaultClientRequestTimeoutInMs = 10 * 60 * 1000;
|
||||||
|
|
||||||
await Promise.all([
|
await assertContainer(mooncakeBlobService, quality);
|
||||||
assertContainer(blobService, quality),
|
|
||||||
assertContainer(mooncakeBlobService, quality)
|
|
||||||
]);
|
|
||||||
|
|
||||||
const [blobExists, moooncakeBlobExists] = await Promise.all([
|
const mooncakeBlobExists = await doesAssetExist(mooncakeBlobService, quality, blobName);
|
||||||
doesAssetExist(blobService, quality, blobName),
|
|
||||||
doesAssetExist(mooncakeBlobService, quality, blobName)
|
|
||||||
]);
|
|
||||||
|
|
||||||
const promises = [];
|
if (!mooncakeBlobExists) {
|
||||||
|
|
||||||
if (!blobExists) {
|
|
||||||
promises.push(uploadBlob(blobService, quality, blobName, file));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!moooncakeBlobExists) {
|
|
||||||
promises.push(uploadBlob(mooncakeBlobService, quality, blobName, file));
|
promises.push(uploadBlob(mooncakeBlobService, quality, blobName, file));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log('Skipping Mooncake publishing.');
|
console.log('Skipping Mooncake publishing.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (promises.length === 0) {
|
if (promises.length === 0) {
|
||||||
console.log(`Blob ${quality}, ${blobName} already exists, not publishing again.`);
|
console.log(`Blob ${quality}, ${blobName} already exists, not publishing again.`);
|
||||||
return;
|
return;
|
||||||
@@ -254,13 +240,6 @@ async function publish(commit: string, quality: string, platform: string, type:
|
|||||||
size
|
size
|
||||||
};
|
};
|
||||||
|
|
||||||
// Remove this if we ever need to rollback fast updates for windows
|
|
||||||
if (/win32/.test(platform)) {
|
|
||||||
asset.supportsFastUpdate = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('Asset:', JSON.stringify(asset, null, ' '));
|
|
||||||
|
|
||||||
const release = {
|
const release = {
|
||||||
id: commit,
|
id: commit,
|
||||||
timestamp: (new Date()).getTime(),
|
timestamp: (new Date()).getTime(),
|
||||||
|
|||||||
@@ -19,9 +19,6 @@ step "Install dependencies" \
|
|||||||
step "Hygiene" \
|
step "Hygiene" \
|
||||||
npm run gulp -- hygiene
|
npm run gulp -- hygiene
|
||||||
|
|
||||||
step "Monaco Editor Check" \
|
|
||||||
./node_modules/.bin/tsc -p ./src/tsconfig.monaco.json --noEmit
|
|
||||||
|
|
||||||
step "Mix in repository from vscode-distro" \
|
step "Mix in repository from vscode-distro" \
|
||||||
npm run gulp -- mixin
|
npm run gulp -- mixin
|
||||||
|
|
||||||
|
|||||||
@@ -22,9 +22,6 @@ step "Install dependencies" \
|
|||||||
step "Hygiene" \
|
step "Hygiene" \
|
||||||
npm run gulp -- hygiene
|
npm run gulp -- hygiene
|
||||||
|
|
||||||
step "Monaco Editor Check" \
|
|
||||||
./node_modules/.bin/tsc -p ./src/tsconfig.monaco.json --noEmit
|
|
||||||
|
|
||||||
step "Mix in repository from vscode-distro" \
|
step "Mix in repository from vscode-distro" \
|
||||||
npm run gulp -- mixin
|
npm run gulp -- mixin
|
||||||
|
|
||||||
|
|||||||
@@ -24,10 +24,6 @@ step "Hygiene" {
|
|||||||
exec { & npm run gulp -- hygiene }
|
exec { & npm run gulp -- hygiene }
|
||||||
}
|
}
|
||||||
|
|
||||||
step "Monaco Editor Check" {
|
|
||||||
exec { & .\node_modules\.bin\tsc -p .\src\tsconfig.monaco.json --noEmit }
|
|
||||||
}
|
|
||||||
|
|
||||||
$env:VSCODE_MIXIN_PASSWORD = $mixinPassword
|
$env:VSCODE_MIXIN_PASSWORD = $mixinPassword
|
||||||
step "Mix in repository from vscode-distro" {
|
step "Mix in repository from vscode-distro" {
|
||||||
exec { & npm run gulp -- mixin }
|
exec { & npm run gulp -- mixin }
|
||||||
@@ -45,10 +41,6 @@ step "Build minified" {
|
|||||||
exec { & npm run gulp -- "vscode-win32-$global:arch-min" }
|
exec { & npm run gulp -- "vscode-win32-$global:arch-min" }
|
||||||
}
|
}
|
||||||
|
|
||||||
step "Copy Inno updater" {
|
|
||||||
exec { & npm run gulp -- "vscode-win32-$global:arch-copy-inno-updater" }
|
|
||||||
}
|
|
||||||
|
|
||||||
# step "Create loader snapshot" {
|
# step "Create loader snapshot" {
|
||||||
# exec { & node build\lib\snapshotLoader.js --arch=$global:arch }
|
# exec { & node build\lib\snapshotLoader.js --arch=$global:arch }
|
||||||
# }
|
# }
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# install node
|
# install node
|
||||||
$env:Path = $env:NVM_HOME + ";" + $env:NVM_SYMLINK + ";" + $env:Path
|
$env:Path = $env:NVM_HOME + ";" + $env:NVM_SYMLINK + ";" + $env:Path
|
||||||
$NodeVersion = "8.9.1"
|
$NodeVersion = "8.9.1"
|
||||||
# nvm install $NodeVersion
|
nvm install $NodeVersion
|
||||||
# nvm use $NodeVersion
|
nvm use $NodeVersion
|
||||||
# npm install -g yarn
|
npm install -g yarn
|
||||||
$env:Path = $env:NVM_HOME + "\v" + $NodeVersion + ";" + $env:Path
|
$env:Path = $env:NVM_HOME + "\v" + $NodeVersion + ";" + $env:Path
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "./tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"allowJs": false,
|
|
||||||
"checkJs": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,12 +7,7 @@
|
|||||||
"preserveConstEnums": true,
|
"preserveConstEnums": true,
|
||||||
"sourceMap": false,
|
"sourceMap": false,
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"newLine": "LF",
|
"newLine": "LF"
|
||||||
// enable JavaScript type checking for the language service
|
|
||||||
// use the tsconfig.build.json for compiling wich disable JavaScript
|
|
||||||
// type checking so that JavaScript file are not transpiled
|
|
||||||
"allowJs": true,
|
|
||||||
"checkJs": true
|
|
||||||
},
|
},
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"node_modules/**"
|
"node_modules/**"
|
||||||
|
|||||||
@@ -9,6 +9,5 @@
|
|||||||
"always"
|
"always"
|
||||||
],
|
],
|
||||||
"triple-equals": true
|
"triple-equals": true
|
||||||
},
|
}
|
||||||
"defaultSeverity": "warning"
|
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -19,7 +19,7 @@ OutputDir={#OutputDir}
|
|||||||
OutputBaseFilename=SqlOpsStudioSetup
|
OutputBaseFilename=SqlOpsStudioSetup
|
||||||
Compression=lzma
|
Compression=lzma
|
||||||
SolidCompression=yes
|
SolidCompression=yes
|
||||||
AppMutex={code:GetAppMutex}
|
AppMutex={#AppMutex}
|
||||||
SetupMutex={#AppMutex}setup
|
SetupMutex={#AppMutex}setup
|
||||||
WizardImageFile={#RepoDir}\resources\win32\inno-big.bmp
|
WizardImageFile={#RepoDir}\resources\win32\inno-big.bmp
|
||||||
WizardSmallImageFile={#RepoDir}\resources\win32\inno-small.bmp
|
WizardSmallImageFile={#RepoDir}\resources\win32\inno-small.bmp
|
||||||
@@ -52,13 +52,8 @@ Type: filesandordirs; Name: "{app}\resources\app\out"; Check: IsNotUpdate
|
|||||||
Type: filesandordirs; Name: "{app}\resources\app\plugins"; Check: IsNotUpdate
|
Type: filesandordirs; Name: "{app}\resources\app\plugins"; Check: IsNotUpdate
|
||||||
Type: filesandordirs; Name: "{app}\resources\app\extensions"; Check: IsNotUpdate
|
Type: filesandordirs; Name: "{app}\resources\app\extensions"; Check: IsNotUpdate
|
||||||
Type: filesandordirs; Name: "{app}\resources\app\node_modules"; Check: IsNotUpdate
|
Type: filesandordirs; Name: "{app}\resources\app\node_modules"; Check: IsNotUpdate
|
||||||
Type: filesandordirs; Name: "{app}\resources\app\node_modules.asar.unpacked"; Check: IsNotUpdate
|
|
||||||
Type: files; Name: "{app}\resources\app\node_modules.asar"; Check: IsNotUpdate
|
|
||||||
Type: files; Name: "{app}\resources\app\Credits_45.0.2454.85.html"; Check: IsNotUpdate
|
Type: files; Name: "{app}\resources\app\Credits_45.0.2454.85.html"; Check: IsNotUpdate
|
||||||
|
|
||||||
[UninstallDelete]
|
|
||||||
Type: filesandordirs; Name: "{app}\_"
|
|
||||||
|
|
||||||
[Tasks]
|
[Tasks]
|
||||||
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1
|
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1
|
||||||
Name: "addtopath"; Description: "{cm:AddToPath}"; GroupDescription: "{cm:Other}"
|
Name: "addtopath"; Description: "{cm:AddToPath}"; GroupDescription: "{cm:Other}"
|
||||||
@@ -143,48 +138,6 @@ begin
|
|||||||
Result := True;
|
Result := True;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function GetAppMutex(Value: string): string;
|
|
||||||
begin
|
|
||||||
if IsBackgroundUpdate() then
|
|
||||||
Result := ''
|
|
||||||
else
|
|
||||||
Result := '{#AppMutex}';
|
|
||||||
end;
|
|
||||||
|
|
||||||
function GetDestDir(Value: string): string;
|
|
||||||
begin
|
|
||||||
if IsBackgroundUpdate() then
|
|
||||||
Result := ExpandConstant('{app}\_')
|
|
||||||
else
|
|
||||||
Result := ExpandConstant('{app}');
|
|
||||||
end;
|
|
||||||
|
|
||||||
function BoolToStr(Value: Boolean): String;
|
|
||||||
begin
|
|
||||||
if Value then
|
|
||||||
Result := 'true'
|
|
||||||
else
|
|
||||||
Result := 'false';
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure CurStepChanged(CurStep: TSetupStep);
|
|
||||||
var
|
|
||||||
UpdateResultCode: Integer;
|
|
||||||
begin
|
|
||||||
if IsBackgroundUpdate() and (CurStep = ssPostInstall) then
|
|
||||||
begin
|
|
||||||
CreateMutex('{#AppMutex}-ready');
|
|
||||||
|
|
||||||
while (CheckForMutexes('{#AppMutex}')) do
|
|
||||||
begin
|
|
||||||
Log('Application is still running, waiting');
|
|
||||||
Sleep(1000);
|
|
||||||
end;
|
|
||||||
|
|
||||||
Exec(ExpandConstant('{app}\tools\inno_updater.exe'), ExpandConstant('"{app}\{#ExeBasename}.exe" ' + BoolToStr(LockFileExists())), '', SW_SHOW, ewWaitUntilTerminated, UpdateResultCode);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
// http://stackoverflow.com/a/23838239/261019
|
// http://stackoverflow.com/a/23838239/261019
|
||||||
procedure Explode(var Dest: TArrayOfString; Text: String; Separator: String);
|
procedure Explode(var Dest: TArrayOfString; Text: String; Separator: String);
|
||||||
var
|
var
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
4370
build/yarn.lock
4370
build/yarn.lock
File diff suppressed because it is too large
Load Diff
3
dataprotocol-client/.gitignore
vendored
Normal file
3
dataprotocol-client/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
lib
|
||||||
|
node_modules
|
||||||
|
npm-debug.log
|
||||||
3
dataprotocol-client/.npmignore
Normal file
3
dataprotocol-client/.npmignore
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
src
|
||||||
|
.gitignore
|
||||||
|
tsfmt.json
|
||||||
25
dataprotocol-client/package.json
Normal file
25
dataprotocol-client/package.json
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"name": "dataprotocol-client",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "SQL Operations Studio studio implementation of vscode-language-client",
|
||||||
|
"main": "lib/main.js",
|
||||||
|
"typings": "./lib/main",
|
||||||
|
"scripts": {
|
||||||
|
"prepare": "node ./node_modules/vscode/bin/install && tsc -p ./src",
|
||||||
|
"compile": "tsc -p ./src",
|
||||||
|
"watch": "tsc -w -p ./src",
|
||||||
|
"update-vscode": "node ./node_modules/vscode/bin/install"
|
||||||
|
},
|
||||||
|
"author": "Microsoft",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"typescript": "2.6.2",
|
||||||
|
"vscode-languageclient": "3.5.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"vscode": "1.1.5"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"vscode": "^1.15"
|
||||||
|
}
|
||||||
|
}
|
||||||
68
dataprotocol-client/src/codeConverter.ts
Normal file
68
dataprotocol-client/src/codeConverter.ts
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
import * as data from 'data';
|
||||||
|
import * as proto from './protocol';
|
||||||
|
import * as types from './types';
|
||||||
|
|
||||||
|
export interface Ic2p {
|
||||||
|
asConnectionParams(connectionUri: string, connectionInfo: data.ConnectionInfo): proto.ConnectParams;
|
||||||
|
asExecutionPlanOptions(planOptions: data.ExecutionPlanOptions): types.ExecutionPlanOptions;
|
||||||
|
asScriptingParams(connectionUri: string, operation: data.ScriptOperation, metadata: data.ObjectMetadata, paramDetails: data.ScriptingParamDetails): types.ScriptingParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
function asConnectionParams(ownerUri: string, connInfo: data.ConnectionInfo): proto.ConnectParams {
|
||||||
|
return {
|
||||||
|
ownerUri,
|
||||||
|
connection: {
|
||||||
|
options: connInfo.options
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function asExecutionPlanOptions(planOptions: data.ExecutionPlanOptions): types.ExecutionPlanOptions {
|
||||||
|
return {
|
||||||
|
includeEstimatedExecutionPlanXml: planOptions ? planOptions.displayEstimatedQueryPlan : undefined,
|
||||||
|
includeActualExecutionPlanXml: planOptions ? planOptions.displayActualQueryPlan : undefined
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function asScriptingParams(ownerURI: string, operation: data.ScriptOperation, metadata: data.ObjectMetadata, paramDetails: data.ScriptingParamDetails): types.ScriptingParams {
|
||||||
|
let scriptingObject: types.ScriptingObject = {
|
||||||
|
type: metadata.metadataTypeName,
|
||||||
|
schema: metadata.schema,
|
||||||
|
name: metadata.name
|
||||||
|
};
|
||||||
|
let targetDatabaseEngineEdition = paramDetails.targetDatabaseEngineEdition;
|
||||||
|
let targetDatabaseEngineType = paramDetails.targetDatabaseEngineType;
|
||||||
|
let scriptCompatibilityOption = paramDetails.scriptCompatibilityOption;
|
||||||
|
let scriptOptions: types.ScriptOptions = {
|
||||||
|
scriptCreateDrop: (operation === types.ScriptOperation.Delete) ? 'ScriptDrop' :
|
||||||
|
(operation === types.ScriptOperation.Select) ? 'ScriptSelect' : 'ScriptCreate',
|
||||||
|
typeOfDataToScript: 'SchemaOnly',
|
||||||
|
scriptStatistics: 'ScriptStatsNone',
|
||||||
|
targetDatabaseEngineEdition: targetDatabaseEngineEdition ? targetDatabaseEngineEdition : 'SqlServerEnterpriseEdition',
|
||||||
|
targetDatabaseEngineType: targetDatabaseEngineType ? targetDatabaseEngineType : 'SingleInstance',
|
||||||
|
scriptCompatibilityOption: scriptCompatibilityOption ? scriptCompatibilityOption : 'Script140Compat'
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
connectionString: null,
|
||||||
|
filePath: paramDetails.filePath,
|
||||||
|
scriptingObjects: [scriptingObject],
|
||||||
|
scriptDestination: 'ToEditor',
|
||||||
|
includeObjectCriteria: null,
|
||||||
|
excludeObjectCriteria: null,
|
||||||
|
includeSchemas: null,
|
||||||
|
excludeSchemas: null,
|
||||||
|
includeTypes: null,
|
||||||
|
excludeTypes: null,
|
||||||
|
scriptOptions,
|
||||||
|
connectionDetails: null,
|
||||||
|
selectScript: null,
|
||||||
|
ownerURI,
|
||||||
|
operation
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const c2p: Ic2p = {
|
||||||
|
asConnectionParams,
|
||||||
|
asExecutionPlanOptions,
|
||||||
|
asScriptingParams
|
||||||
|
};
|
||||||
1312
dataprotocol-client/src/main.ts
Normal file
1312
dataprotocol-client/src/main.ts
Normal file
File diff suppressed because it is too large
Load Diff
633
dataprotocol-client/src/protocol.ts
Normal file
633
dataprotocol-client/src/protocol.ts
Normal file
@@ -0,0 +1,633 @@
|
|||||||
|
import { ClientCapabilities as VSClientCapabilities, RequestType, NotificationType } from 'vscode-languageclient';
|
||||||
|
|
||||||
|
import * as types from './types';
|
||||||
|
import * as data from 'data';
|
||||||
|
|
||||||
|
export interface ConnectionClientCapabilities {
|
||||||
|
connection?: {
|
||||||
|
/**
|
||||||
|
* Whether the connection support dynamic registration
|
||||||
|
*/
|
||||||
|
dynamicRegistration?: boolean;
|
||||||
|
};
|
||||||
|
backup?: {
|
||||||
|
/**
|
||||||
|
* Whether the backup support dynamic registration
|
||||||
|
*/
|
||||||
|
dynamicRegistration?: boolean;
|
||||||
|
};
|
||||||
|
restore?: {
|
||||||
|
/**
|
||||||
|
* Whether the restore support dynamic registration
|
||||||
|
*/
|
||||||
|
dynamicRegistration?: boolean;
|
||||||
|
};
|
||||||
|
query?: {
|
||||||
|
/**
|
||||||
|
* Whether the query support dynamic registration
|
||||||
|
*/
|
||||||
|
dynamicRegistration?: boolean;
|
||||||
|
};
|
||||||
|
objectExplorer?: {
|
||||||
|
/**
|
||||||
|
* Whether the object explorer support dynamic registration
|
||||||
|
*/
|
||||||
|
dynamicRegistration?: boolean;
|
||||||
|
};
|
||||||
|
scripting?: {
|
||||||
|
/**
|
||||||
|
* Whether the scripting support dynamic registration
|
||||||
|
*/
|
||||||
|
dynamicRegistration?: boolean;
|
||||||
|
};
|
||||||
|
taskServices?: {
|
||||||
|
/**
|
||||||
|
* Whether the task services support dynamic registration
|
||||||
|
*/
|
||||||
|
dynamicRegistration?: boolean;
|
||||||
|
};
|
||||||
|
fileBrowser?: {
|
||||||
|
/**
|
||||||
|
* Whether the file browser support dynamic registration
|
||||||
|
*/
|
||||||
|
dynamicRegistration?: boolean;
|
||||||
|
};
|
||||||
|
profiler?: {
|
||||||
|
/**
|
||||||
|
* Whether the profiler support dynamic registration
|
||||||
|
*/
|
||||||
|
dynamicRegistration?: boolean;
|
||||||
|
};
|
||||||
|
capabilities?: {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
dynamicRegistration?: boolean;
|
||||||
|
};
|
||||||
|
metadata?: {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
dynamicRegistration?: boolean;
|
||||||
|
};
|
||||||
|
adminServices?: {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
dynamicRegistration?: boolean;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ClientCapabilities extends VSClientCapabilities {
|
||||||
|
connection?: ConnectionClientCapabilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- Refresh IntelliSense ----------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notification sent when the an IntelliSense cache invalidation is requested
|
||||||
|
*/
|
||||||
|
export namespace RebuildIntelliSenseNotification {
|
||||||
|
export const type = new NotificationType<RebuildIntelliSenseParams, void>('textDocument/rebuildIntelliSense');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rebuild IntelliSense notification parameters
|
||||||
|
*/
|
||||||
|
export class RebuildIntelliSenseParams {
|
||||||
|
/**
|
||||||
|
* URI identifying the text document
|
||||||
|
*/
|
||||||
|
public ownerUri: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------- < Connect Request > ----------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connection request message format
|
||||||
|
*/
|
||||||
|
export interface ConnectParams {
|
||||||
|
/**
|
||||||
|
* URI identifying the owner of the connection
|
||||||
|
*/
|
||||||
|
ownerUri: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Details for creating the connection
|
||||||
|
*/
|
||||||
|
connection: types.ConnectionDetails;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Connection request message callback declaration
|
||||||
|
export namespace ConnectionRequest {
|
||||||
|
export const type = new RequestType<ConnectParams, boolean, void, void>('connection/connect');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < Connection Complete Event > ------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
export namespace ConnectionCompleteNotification {
|
||||||
|
export const type = new NotificationType<types.ConnectionCompleteParams, void>('connection/complete');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < Connection Changed Event > -------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameters for the ConnectionChanged notification.
|
||||||
|
*/
|
||||||
|
export class ConnectionChangedParams {
|
||||||
|
/**
|
||||||
|
* Owner URI of the connection that changed.
|
||||||
|
*/
|
||||||
|
public ownerUri: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Summary of details containing any connection changes.
|
||||||
|
*/
|
||||||
|
public connection: types.ConnectionSummary;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connection changed event callback declaration.
|
||||||
|
*/
|
||||||
|
export namespace ConnectionChangedNotification {
|
||||||
|
export const type = new NotificationType<ConnectionChangedParams, void>('connection/connectionchanged');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < Disconnect Request > -------------------------------------------
|
||||||
|
|
||||||
|
// Disconnect request message format
|
||||||
|
export class DisconnectParams {
|
||||||
|
// URI identifying the owner of the connection
|
||||||
|
public ownerUri: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disconnect response format
|
||||||
|
export type DisconnectResult = boolean;
|
||||||
|
|
||||||
|
// Disconnect request message callback declaration
|
||||||
|
export namespace DisconnectRequest {
|
||||||
|
export const type = new RequestType<DisconnectParams, DisconnectResult, void, void>('connection/disconnect');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < Cancel Connect Request > ---------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
// Cancel connect request message format
|
||||||
|
export class CancelConnectParams {
|
||||||
|
/**
|
||||||
|
* URI identifying the owner of the connection
|
||||||
|
*/
|
||||||
|
public ownerUri: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cancel connect response format.
|
||||||
|
export type CancelConnectResult = boolean;
|
||||||
|
|
||||||
|
// Cancel connect request message callback declaration
|
||||||
|
export namespace CancelConnectRequest {
|
||||||
|
export const type = new RequestType<CancelConnectParams, CancelConnectResult, void, void>('connection/cancelconnect');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < Change Database Request > -------------------------------------
|
||||||
|
|
||||||
|
export class ChangeDatabaseParams {
|
||||||
|
public ownerUri: string;
|
||||||
|
public newDatabase: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace ChangeDatabaseRequest {
|
||||||
|
export const type = new RequestType<ChangeDatabaseParams, boolean, void, void>('connection/changedatabase');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < List Databases Request > ---------------------------------------
|
||||||
|
|
||||||
|
// List databases request format
|
||||||
|
export class ListDatabasesParams {
|
||||||
|
// Connection information to use for querying master
|
||||||
|
public ownerUri: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// List databases request callback declaration
|
||||||
|
export namespace ListDatabasesRequest {
|
||||||
|
export const type = new RequestType<ListDatabasesParams, data.ListDatabasesResult, void, void>('connection/listdatabases');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Language Flavor Changed ================================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameters to provide when sending a language flavor changed notification
|
||||||
|
*/
|
||||||
|
export interface DidChangeLanguageFlavorParams {
|
||||||
|
uri: string;
|
||||||
|
language: string;
|
||||||
|
flavor: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < Language Flavor Changed Notification > ---------------------------------------
|
||||||
|
export namespace LanguageFlavorChangedNotification {
|
||||||
|
export const type = new NotificationType<DidChangeLanguageFlavorParams, void>('connection/languageflavorchanged');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < Table Metadata Request > ---------------------------------------
|
||||||
|
|
||||||
|
// Table metadata request format
|
||||||
|
export class TableMetadataParams {
|
||||||
|
// Connection information to use for querying master
|
||||||
|
public ownerUri: string;
|
||||||
|
|
||||||
|
public schema: string;
|
||||||
|
|
||||||
|
public objectName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Table metadata response format
|
||||||
|
export class TableMetadataResult {
|
||||||
|
public columns: data.ColumnMetadata[];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Table metadata request callback declaration
|
||||||
|
export namespace TableMetadataRequest {
|
||||||
|
export const type = new RequestType<TableMetadataParams, TableMetadataResult, void, void>('metadata/table');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < View Metadata Request > ---------------------------------------
|
||||||
|
|
||||||
|
// Table metadata request callback declaration
|
||||||
|
export namespace ViewMetadataRequest {
|
||||||
|
export const type = new RequestType<TableMetadataParams, TableMetadataResult, void, void>('metadata/view');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event sent when the language service is finished updating after a connection
|
||||||
|
*/
|
||||||
|
export namespace IntelliSenseReadyNotification {
|
||||||
|
export const type = new NotificationType<types.IntelliSenseReadyParams, void>('textDocument/intelliSenseReady');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < Capabilties Discovery Event > ------------------------------------
|
||||||
|
|
||||||
|
export class CapabiltiesDiscoveryParams {
|
||||||
|
public hostName: string;
|
||||||
|
|
||||||
|
public hostVersion: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace CapabiltiesDiscoveryRequest {
|
||||||
|
export const type = new RequestType<CapabiltiesDiscoveryParams, types.CapabiltiesDiscoveryResult, void, void>('capabilities/list');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query Execution ================================================================================
|
||||||
|
// ------------------------------- < Query Cancellation Request > ------------------------------------
|
||||||
|
export namespace QueryCancelRequest {
|
||||||
|
export const type = new RequestType<QueryCancelParams, data.QueryCancelResult, void, void>('query/cancel');
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface QueryCancelParams {
|
||||||
|
ownerUri: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < Query Dispose Request > ------------------------------------
|
||||||
|
|
||||||
|
export namespace QueryDisposeRequest {
|
||||||
|
export const type = new RequestType<QueryDisposeParams, QueryDisposeResult, void, void>('query/dispose');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameters to provide when disposing of a query
|
||||||
|
*/
|
||||||
|
export interface QueryDisposeParams {
|
||||||
|
ownerUri: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Result received upon successful disposal of a query
|
||||||
|
*/
|
||||||
|
export interface QueryDisposeResult {
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < Query Execution Complete Notification > ------------------------------------
|
||||||
|
export namespace QueryExecuteCompleteNotification {
|
||||||
|
export const type = new NotificationType<data.QueryExecuteCompleteNotificationResult, void>('query/complete');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < Query Batch Start Notification > ------------------------------------
|
||||||
|
export namespace QueryExecuteBatchStartNotification {
|
||||||
|
export const type = new NotificationType<data.QueryExecuteBatchNotificationParams, void>('query/batchStart');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < Query Batch Complete Notification > ------------------------------------
|
||||||
|
export namespace QueryExecuteBatchCompleteNotification {
|
||||||
|
export const type = new NotificationType<data.QueryExecuteBatchNotificationParams, void>('query/batchComplete');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < Query ResultSet Complete Notification > ------------------------------------
|
||||||
|
export namespace QueryExecuteResultSetCompleteNotification {
|
||||||
|
export const type = new NotificationType<data.QueryExecuteResultSetCompleteNotificationParams, void>('query/resultSetComplete');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < Query Message Notification > ------------------------------------
|
||||||
|
export namespace QueryExecuteMessageNotification {
|
||||||
|
export const type = new NotificationType<data.QueryExecuteMessageParams, void>('query/message');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < Query Execution Request > ------------------------------------
|
||||||
|
export namespace QueryExecuteRequest {
|
||||||
|
export const type = new RequestType<types.QueryExecuteParams, QueryExecuteResult, void, void>('query/executeDocumentSelection');
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface QueryExecuteResult { }
|
||||||
|
|
||||||
|
// ------------------------------- < Query Results Request > ------------------------------------
|
||||||
|
export namespace QueryExecuteSubsetRequest {
|
||||||
|
export const type = new RequestType<data.QueryExecuteSubsetParams, data.QueryExecuteSubsetResult, void, void>('query/subset');
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ResultSetSubset {
|
||||||
|
rowCount: number;
|
||||||
|
rows: data.DbCellValue[][];
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < Execute Statement > ------------------------------------
|
||||||
|
export interface QueryExecuteStatementParams {
|
||||||
|
ownerUri: string;
|
||||||
|
line: number;
|
||||||
|
column: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace QueryExecuteStatementRequest {
|
||||||
|
export const type = new RequestType<QueryExecuteStatementParams, QueryExecuteResult, void, void>('query/executedocumentstatement');
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------------- < Save Results as CSV Request > ------------------------------------------
|
||||||
|
|
||||||
|
// save results in csv format
|
||||||
|
export namespace SaveResultsAsCsvRequest {
|
||||||
|
export const type = new RequestType<data.SaveResultsRequestParams, data.SaveResultRequestResult, void, void>('query/saveCsv');
|
||||||
|
}
|
||||||
|
// --------------------------------- </ Save Results as CSV Request > ------------------------------------------
|
||||||
|
|
||||||
|
// --------------------------------- < Save Results as JSON Request > ------------------------------------------
|
||||||
|
// save results in json format
|
||||||
|
export namespace SaveResultsAsJsonRequest {
|
||||||
|
export const type = new RequestType<data.SaveResultsRequestParams, data.SaveResultRequestResult, void, void>('query/saveJson');
|
||||||
|
}
|
||||||
|
// --------------------------------- </ Save Results as JSON Request > ------------------------------------------
|
||||||
|
|
||||||
|
// --------------------------------- < Save Results as Excel Request > ------------------------------------------
|
||||||
|
// save results in Excel format
|
||||||
|
export namespace SaveResultsAsExcelRequest {
|
||||||
|
export const type = new RequestType<data.SaveResultsRequestParams, data.SaveResultRequestResult, void, void>('query/saveExcel');
|
||||||
|
}
|
||||||
|
// --------------------------------- </ Save Results as Excel Request > ------------------------------------------
|
||||||
|
|
||||||
|
// ------------------------------- < Execute and Return > -----------------------------------
|
||||||
|
|
||||||
|
export namespace SimpleExecuteRequest {
|
||||||
|
export const type = new RequestType<data.SimpleExecuteParams, data.SimpleExecuteResult, void, void>('query/simpleexecute');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < Execute String > ------------------------------------
|
||||||
|
export interface QueryExecuteStringParams {
|
||||||
|
query: string;
|
||||||
|
ownerUri: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace QueryExecuteStringRequest {
|
||||||
|
export const type = new RequestType<QueryExecuteStringParams, QueryExecuteResult, void, void>('query/executeString');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < Metadata Events > ------------------------------------
|
||||||
|
|
||||||
|
export namespace MetadataQueryRequest {
|
||||||
|
export const type = new RequestType<types.MetadataQueryParams, types.MetadataQueryResult, void, void>('metadata/list');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < Scripting Events > ------------------------------------
|
||||||
|
|
||||||
|
export namespace ScriptingRequest {
|
||||||
|
export const type = new RequestType<types.ScriptingParams, data.ScriptingResult, void, void>('scripting/script');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < Scripting Complete Event > ------------------------------------
|
||||||
|
|
||||||
|
export namespace ScriptingCompleteNotification {
|
||||||
|
export const type = new NotificationType<types.ScriptingCompleteParams, void>('scripting/scriptComplete');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Edit Data ======================================================================================
|
||||||
|
// Shared Interfaces --------------------------------------------------------------------------
|
||||||
|
export interface EditSessionOperationParams {
|
||||||
|
ownerUri: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EditRowOperationParams extends EditSessionOperationParams {
|
||||||
|
rowId: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EditCellResult {
|
||||||
|
cell: data.EditCell;
|
||||||
|
isRowDirty: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
// edit/commit --------------------------------------------------------------------------------
|
||||||
|
export namespace EditCommitRequest {
|
||||||
|
export const type = new RequestType<data.EditCommitParams, EditCommitResult, void, void>('edit/commit');
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EditCommitResult { }
|
||||||
|
|
||||||
|
// edit/createRow -----------------------------------------------------------------------------
|
||||||
|
export namespace EditCreateRowRequest {
|
||||||
|
export const type = new RequestType<data.EditCreateRowParams, data.EditCreateRowResult, void, void>('edit/createRow');
|
||||||
|
}
|
||||||
|
|
||||||
|
// edit/deleteRow -----------------------------------------------------------------------------
|
||||||
|
export namespace EditDeleteRowRequest {
|
||||||
|
export const type = new RequestType<data.EditDeleteRowParams, EditDeleteRowResult, void, void>('edit/deleteRow');
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EditDeleteRowResult { }
|
||||||
|
|
||||||
|
// edit/dispose -------------------------------------------------------------------------------
|
||||||
|
export namespace EditDisposeRequest {
|
||||||
|
export const type = new RequestType<data.EditDisposeParams, EditDisposeResult, void, void>('edit/dispose');
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EditDisposeResult { }
|
||||||
|
|
||||||
|
// edit/initialize ----------------------------------------------------------------------------
|
||||||
|
export namespace EditInitializeRequest {
|
||||||
|
export const type = new RequestType<data.EditInitializeParams, EditInitializeResult, void, void>('edit/initialize');
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EditInitializeResult { }
|
||||||
|
|
||||||
|
// edit/revertCell --------------------------------------------------------------------------------
|
||||||
|
export namespace EditRevertCellRequest {
|
||||||
|
export const type = new RequestType<data.EditRevertCellParams, data.EditRevertCellResult, void, void>('edit/revertCell');
|
||||||
|
}
|
||||||
|
|
||||||
|
// edit/revertRow -----------------------------------------------------------------------------
|
||||||
|
export namespace EditRevertRowRequest {
|
||||||
|
export const type = new RequestType<data.EditRevertRowParams, EditRevertRowResult, void, void>('edit/revertRow');
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EditRevertRowResult { }
|
||||||
|
|
||||||
|
// edit/sessionReady Event --------------------------------------------------------------------
|
||||||
|
export namespace EditSessionReadyNotification {
|
||||||
|
export const type = new NotificationType<data.EditSessionReadyParams, void>('edit/sessionReady');
|
||||||
|
}
|
||||||
|
|
||||||
|
// edit/updateCell ----------------------------------------------------------------------------
|
||||||
|
export namespace EditUpdateCellRequest {
|
||||||
|
export const type = new RequestType<data.EditUpdateCellParams, data.EditUpdateCellResult, void, void>('edit/updateCell');
|
||||||
|
}
|
||||||
|
|
||||||
|
// edit/subset ------------------------------------------------------------------------------------
|
||||||
|
export namespace EditSubsetRequest {
|
||||||
|
export const type = new RequestType<data.EditSubsetParams, data.EditSubsetResult, void, void>('edit/subset');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < Object Explorer Events > ------------------------------------
|
||||||
|
|
||||||
|
export namespace ObjectExplorerCreateSessionRequest {
|
||||||
|
export const type = new RequestType<types.ConnectionDetails, types.CreateSessionResponse, void, void>('objectexplorer/createsession');
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace ObjectExplorerExpandRequest {
|
||||||
|
export const type = new RequestType<types.ExpandParams, boolean, void, void>('objectexplorer/expand');
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace ObjectExplorerRefreshRequest {
|
||||||
|
export const type = new RequestType<types.ExpandParams, boolean, void, void>('objectexplorer/refresh');
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace ObjectExplorerCloseSessionRequest {
|
||||||
|
export const type = new RequestType<types.CloseSessionParams, types.CloseSessionResponse, void, void>('objectexplorer/closesession');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < Object Explorer Events > ------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
export namespace ObjectExplorerCreateSessionCompleteNotification {
|
||||||
|
export const type = new NotificationType<types.SessionCreatedParameters, void>('objectexplorer/sessioncreated');
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace ObjectExplorerExpandCompleteNotification {
|
||||||
|
export const type = new NotificationType<types.ExpandResponse, void>('objectexplorer/expandCompleted');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < Task Service Events > ------------------------------------
|
||||||
|
|
||||||
|
export namespace ListTasksRequest {
|
||||||
|
export const type = new RequestType<data.ListTasksParams, data.ListTasksResponse, void, void>('tasks/listtasks');
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace CancelTaskRequest {
|
||||||
|
export const type = new RequestType<data.CancelTaskParams, boolean, void, void>('tasks/canceltask');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < Task Service Events > ------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
export namespace TaskStatusChangedNotification {
|
||||||
|
export const type = new NotificationType<data.TaskProgressInfo, void>('tasks/statuschanged');
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace TaskCreatedNotification {
|
||||||
|
export const type = new NotificationType<data.TaskInfo, void>('tasks/newtaskcreated');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < Admin Service Events > ------------------------------------
|
||||||
|
|
||||||
|
export namespace CreateDatabaseRequest {
|
||||||
|
export const type = new RequestType<types.CreateDatabaseParams, data.CreateDatabaseResponse, void, void>('admin/createdatabase');
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace DefaultDatabaseInfoRequest {
|
||||||
|
export const type = new RequestType<types.DefaultDatabaseInfoParams, types.DefaultDatabaseInfoResponse, void, void>('admin/defaultdatabaseinfo');
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace CreateLoginRequest {
|
||||||
|
export const type = new RequestType<types.CreateLoginParams, data.CreateLoginResponse, void, void>('admin/createlogin');
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace GetDatabaseInfoRequest {
|
||||||
|
export const type = new RequestType<types.GetDatabaseInfoParams, types.GetDatabaseInfoResponse, void, void>('admin/getdatabaseinfo');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < Disaster Recovery Events > ------------------------------------
|
||||||
|
|
||||||
|
export namespace BackupRequest {
|
||||||
|
export const type = new RequestType<types.BackupParams, data.BackupResponse, void, void>('backup/backup');
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace BackupConfigInfoRequest {
|
||||||
|
export const type = new RequestType<types.DefaultDatabaseInfoParams, types.BackupConfigInfoResponse, void, void>('backup/backupconfiginfo');
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace RestoreRequest {
|
||||||
|
export const type = new RequestType<types.RestoreParams, data.RestoreResponse, void, void>('restore/restore');
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace RestorePlanRequest {
|
||||||
|
export const type = new RequestType<types.RestoreParams, data.RestorePlanResponse, void, void>('restore/restoreplan');
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace CancelRestorePlanRequest {
|
||||||
|
export const type = new RequestType<types.RestoreParams, boolean, void, void>('restore/cancelrestoreplan');
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace RestoreConfigInfoRequest {
|
||||||
|
export const type = new RequestType<types.RestoreConfigInfoRequestParams, types.RestoreConfigInfoResponse, void, void>('restore/restoreconfiginfo');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- < File Browser Events > ------------------------------------
|
||||||
|
|
||||||
|
export namespace FileBrowserOpenRequest {
|
||||||
|
export const type = new RequestType<types.FileBrowserOpenParams, boolean, void, void>('filebrowser/open');
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace FileBrowserOpenedNotification {
|
||||||
|
export const type = new NotificationType<data.FileBrowserOpenedParams, void>('filebrowser/opencomplete');
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace FileBrowserExpandRequest {
|
||||||
|
export const type = new RequestType<types.FileBrowserExpandParams, boolean, void, void>('filebrowser/expand');
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace FileBrowserExpandedNotification {
|
||||||
|
export const type = new NotificationType<data.FileBrowserExpandedParams, void>('filebrowser/expandcomplete');
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace FileBrowserValidateRequest {
|
||||||
|
export const type = new RequestType<types.FileBrowserValidateParams, boolean, void, void>('filebrowser/validate');
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace FileBrowserValidatedNotification {
|
||||||
|
export const type = new NotificationType<data.FileBrowserValidatedParams, void>('filebrowser/validatecomplete');
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace FileBrowserCloseRequest {
|
||||||
|
export const type = new RequestType<types.FileBrowserCloseParams, data.FileBrowserCloseResponse, void, void>('filebrowser/close');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------- < Profiler Events > ------------------------------------
|
||||||
|
|
||||||
|
export namespace StartProfilingRequest {
|
||||||
|
export const type = new RequestType<types.StartProfilingParams, types.StartProfilingResponse, void, void>('profiler/start');
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace StopProfilingRequest {
|
||||||
|
export const type = new RequestType<types.StopProfilingParams, types.StopProfilingResponse, void, void>('profiler/stop');
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace ProfilerEventsAvailableNotification {
|
||||||
|
export const type = new NotificationType<types.ProfilerEventsAvailableParams, void>('profiler/eventsavailable');
|
||||||
|
}
|
||||||
198
dataprotocol-client/src/protocolConverter.ts
Normal file
198
dataprotocol-client/src/protocolConverter.ts
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
import * as data from 'data';
|
||||||
|
import * as types from './types';
|
||||||
|
|
||||||
|
export interface Ip2c {
|
||||||
|
asProviderMetadata(params: types.MetadataQueryResult): data.ProviderMetadata;
|
||||||
|
|
||||||
|
asServerCapabilities(result: types.CapabiltiesDiscoveryResult): data.DataProtocolServerCapabilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
function asProviderMetadata(params: types.MetadataQueryResult): data.ProviderMetadata {
|
||||||
|
let objectMetadata: data.ObjectMetadata[] = [];
|
||||||
|
|
||||||
|
if (!params.metadata || !params.metadata.length) {
|
||||||
|
return {
|
||||||
|
objectMetadata
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < params.metadata.length; ++i) {
|
||||||
|
let metadata: data.ObjectMetadata = params.metadata[i];
|
||||||
|
|
||||||
|
let metadataTypeName: string;
|
||||||
|
if (metadata.metadataTypeName) {
|
||||||
|
// Read from the provider since it's defined
|
||||||
|
metadataTypeName = metadata.metadataTypeName;
|
||||||
|
} else if (metadata.metadataType === types.MetadataType.View) {
|
||||||
|
metadataTypeName = 'View';
|
||||||
|
} else if (metadata.metadataType === types.MetadataType.SProc) {
|
||||||
|
metadataTypeName = 'StoredProcedure';
|
||||||
|
} else if (metadata.metadataType === types.MetadataType.Function) {
|
||||||
|
metadataTypeName = 'Function';
|
||||||
|
} else {
|
||||||
|
metadataTypeName = 'Table';
|
||||||
|
}
|
||||||
|
|
||||||
|
objectMetadata.push({
|
||||||
|
metadataTypeName,
|
||||||
|
metadataType: metadata.metadataType,
|
||||||
|
name: metadata.name,
|
||||||
|
schema: metadata.schema,
|
||||||
|
urn: metadata.urn
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return <data.ProviderMetadata>{
|
||||||
|
objectMetadata
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function asServiceOptionType(val: string): data.ServiceOptionType {
|
||||||
|
if (val === 'string') {
|
||||||
|
return data.ServiceOptionType.string;
|
||||||
|
} else if (val === 'multistring') {
|
||||||
|
return data.ServiceOptionType.multistring;
|
||||||
|
} else if (val === 'password') {
|
||||||
|
return data.ServiceOptionType.password;
|
||||||
|
} else if (val === 'number') {
|
||||||
|
return data.ServiceOptionType.number;
|
||||||
|
} else if (val === 'boolean') {
|
||||||
|
return data.ServiceOptionType.boolean;
|
||||||
|
} else if (val === 'category') {
|
||||||
|
return data.ServiceOptionType.category;
|
||||||
|
} else if (val === 'object') {
|
||||||
|
return data.ServiceOptionType.object;
|
||||||
|
}
|
||||||
|
|
||||||
|
// assume string for unknown value types
|
||||||
|
return data.ServiceOptionType.string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function buildServiceOption(srcOption: types.ServiceOption): data.ServiceOption {
|
||||||
|
return {
|
||||||
|
name: srcOption.name,
|
||||||
|
displayName: srcOption.displayName ? srcOption.displayName : srcOption.name,
|
||||||
|
description: srcOption.description,
|
||||||
|
groupName: srcOption.groupName,
|
||||||
|
defaultValue: srcOption.defaultValue,
|
||||||
|
categoryValues: srcOption.categoryValues,
|
||||||
|
isRequired: srcOption.isRequired,
|
||||||
|
isArray: srcOption.isArray,
|
||||||
|
objectType: srcOption.objectType,
|
||||||
|
valueType: asServiceOptionType(srcOption.valueType),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function asServerCapabilities(result: types.CapabiltiesDiscoveryResult): data.DataProtocolServerCapabilities {
|
||||||
|
let capabilities: data.DataProtocolServerCapabilities = {
|
||||||
|
protocolVersion: result.capabilities.protocolVersion,
|
||||||
|
providerName: result.capabilities.providerName,
|
||||||
|
providerDisplayName: result.capabilities.providerDisplayName,
|
||||||
|
connectionProvider: undefined,
|
||||||
|
adminServicesProvider: undefined,
|
||||||
|
features: []
|
||||||
|
};
|
||||||
|
|
||||||
|
if (result.capabilities.adminServicesProvider) {
|
||||||
|
capabilities.adminServicesProvider = <data.AdminServicesOptions>{
|
||||||
|
databaseInfoOptions: new Array<data.ServiceOption>(),
|
||||||
|
databaseFileInfoOptions: new Array<data.ServiceOption>(),
|
||||||
|
fileGroupInfoOptions: new Array<data.ServiceOption>()
|
||||||
|
};
|
||||||
|
|
||||||
|
if (result.capabilities.adminServicesProvider.databaseInfoOptions
|
||||||
|
&& result.capabilities.adminServicesProvider.databaseInfoOptions.length > 0) {
|
||||||
|
for (let i = 0; i < result.capabilities.adminServicesProvider.databaseInfoOptions.length; ++i) {
|
||||||
|
let srcOption: any = result.capabilities.adminServicesProvider.databaseInfoOptions[i];
|
||||||
|
let descOption: data.ServiceOption = buildServiceOption(srcOption);
|
||||||
|
capabilities.adminServicesProvider.databaseInfoOptions.push(descOption);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.capabilities.adminServicesProvider.databaseFileInfoOptions
|
||||||
|
&& result.capabilities.adminServicesProvider.databaseFileInfoOptions.length > 0) {
|
||||||
|
for (let i = 0; i < result.capabilities.adminServicesProvider.databaseFileInfoOptions.length; ++i) {
|
||||||
|
//let srcOption: types.ServiceOption = result.capabilities.adminServicesProvider.databaseFileInfoOptions[i];
|
||||||
|
let srcOption: any = result.capabilities.adminServicesProvider.databaseFileInfoOptions[i];
|
||||||
|
let descOption: data.ServiceOption = buildServiceOption(srcOption);
|
||||||
|
capabilities.adminServicesProvider.databaseFileInfoOptions.push(descOption);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.capabilities.adminServicesProvider.fileGroupInfoOptions
|
||||||
|
&& result.capabilities.adminServicesProvider.fileGroupInfoOptions.length > 0) {
|
||||||
|
for (let i = 0; i < result.capabilities.adminServicesProvider.fileGroupInfoOptions.length; ++i) {
|
||||||
|
//let srcOption: types.ServiceOption = result.capabilities.adminServicesProvider.fileGroupInfoOptions[i];
|
||||||
|
let srcOption: any = result.capabilities.adminServicesProvider.fileGroupInfoOptions[i];
|
||||||
|
let descOption: data.ServiceOption = buildServiceOption(srcOption);
|
||||||
|
capabilities.adminServicesProvider.fileGroupInfoOptions.push(descOption);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.capabilities.connectionProvider
|
||||||
|
&& result.capabilities.connectionProvider.options
|
||||||
|
&& result.capabilities.connectionProvider.options.length > 0) {
|
||||||
|
capabilities.connectionProvider = <data.ConnectionProviderOptions>{
|
||||||
|
options: new Array<data.ConnectionOption>()
|
||||||
|
};
|
||||||
|
for (let i = 0; i < result.capabilities.connectionProvider.options.length; ++i) {
|
||||||
|
let srcOption: any = result.capabilities.connectionProvider.options[i];
|
||||||
|
let descOption: data.ConnectionOption = {
|
||||||
|
name: srcOption.name,
|
||||||
|
displayName: srcOption.displayName ? srcOption.displayName : srcOption.name,
|
||||||
|
description: srcOption.description,
|
||||||
|
groupName: srcOption.groupName,
|
||||||
|
defaultValue: srcOption.defaultValue,
|
||||||
|
categoryValues: srcOption.categoryValues,
|
||||||
|
isIdentity: srcOption.isIdentity,
|
||||||
|
isRequired: srcOption.isRequired,
|
||||||
|
valueType: asServiceOptionType(srcOption.valueType),
|
||||||
|
specialValueType: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
if (srcOption.specialValueType === 'serverName') {
|
||||||
|
descOption.specialValueType = data.ConnectionOptionSpecialType.serverName;
|
||||||
|
} else if (srcOption.specialValueType === 'databaseName') {
|
||||||
|
descOption.specialValueType = data.ConnectionOptionSpecialType.databaseName;
|
||||||
|
} else if (srcOption.specialValueType === 'authType') {
|
||||||
|
descOption.specialValueType = data.ConnectionOptionSpecialType.authType;
|
||||||
|
} else if (srcOption.specialValueType === 'userName') {
|
||||||
|
descOption.specialValueType = data.ConnectionOptionSpecialType.userName;
|
||||||
|
} else if (srcOption.specialValueType === 'password') {
|
||||||
|
descOption.specialValueType = data.ConnectionOptionSpecialType.password;
|
||||||
|
} else if (srcOption.specialValueType === 'appName') {
|
||||||
|
descOption.specialValueType = data.ConnectionOptionSpecialType.appName;
|
||||||
|
}
|
||||||
|
|
||||||
|
capabilities.connectionProvider.options.push(descOption);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.capabilities.features
|
||||||
|
&& result.capabilities.features.length > 0) {
|
||||||
|
result.capabilities.features.forEach(feature => {
|
||||||
|
let descFeature: data.FeatureMetadataProvider = {
|
||||||
|
enabled: feature.enabled,
|
||||||
|
featureName: feature.featureName,
|
||||||
|
optionsMetadata: []
|
||||||
|
};
|
||||||
|
capabilities.features.push(descFeature);
|
||||||
|
if (feature.optionsMetadata) {
|
||||||
|
feature.optionsMetadata.forEach(srcOption => {
|
||||||
|
descFeature.optionsMetadata.push(buildServiceOption(<any>srcOption));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return capabilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const p2c: Ip2c = {
|
||||||
|
asProviderMetadata,
|
||||||
|
asServerCapabilities
|
||||||
|
};
|
||||||
12
dataprotocol-client/src/tsconfig.json
Normal file
12
dataprotocol-client/src/tsconfig.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es6",
|
||||||
|
"module": "commonjs",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"sourceMap": false,
|
||||||
|
"inlineSources": false,
|
||||||
|
"declaration": true,
|
||||||
|
"stripInternal": true,
|
||||||
|
"outDir": "../lib"
|
||||||
|
}
|
||||||
|
}
|
||||||
939
dataprotocol-client/src/types.ts
Normal file
939
dataprotocol-client/src/types.ts
Normal file
@@ -0,0 +1,939 @@
|
|||||||
|
import * as data from 'data';
|
||||||
|
|
||||||
|
export interface CreateSessionResponse {
|
||||||
|
sessionId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SessionCreatedParameters {
|
||||||
|
success: boolean;
|
||||||
|
sessionId: string;
|
||||||
|
rootNode: NodeInfo;
|
||||||
|
errorMessage: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ExpandResponse {
|
||||||
|
nodePath: string;
|
||||||
|
sessionId: string;
|
||||||
|
nodes: NodeInfo[];
|
||||||
|
errorMessage: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface NodeInfo {
|
||||||
|
nodePath: string;
|
||||||
|
nodeType: string;
|
||||||
|
nodeSubType: string;
|
||||||
|
nodeStatus: string;
|
||||||
|
label: string;
|
||||||
|
isLeaf: boolean;
|
||||||
|
metadata: data.ObjectMetadata;
|
||||||
|
errorMessage: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ExpandParams {
|
||||||
|
sessionId: string;
|
||||||
|
nodePath: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CloseSessionParams {
|
||||||
|
sessionId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CloseSessionResponse {
|
||||||
|
success: boolean;
|
||||||
|
sessionId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CategoryValue {
|
||||||
|
displayName: string;
|
||||||
|
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ServiceOption {
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
displayName: string;
|
||||||
|
|
||||||
|
description: string;
|
||||||
|
|
||||||
|
groupName: string;
|
||||||
|
|
||||||
|
valueType: string;
|
||||||
|
|
||||||
|
defaultValue: string;
|
||||||
|
|
||||||
|
objectType: string;
|
||||||
|
|
||||||
|
categoryValues: CategoryValue[];
|
||||||
|
|
||||||
|
isRequired: boolean;
|
||||||
|
|
||||||
|
isArray: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ConnectionOption {
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
displayName: string;
|
||||||
|
|
||||||
|
description: string;
|
||||||
|
|
||||||
|
groupName: string;
|
||||||
|
|
||||||
|
valueType: string;
|
||||||
|
|
||||||
|
defaultValue: string;
|
||||||
|
|
||||||
|
objectType: string;
|
||||||
|
|
||||||
|
categoryValues: CategoryValue[];
|
||||||
|
|
||||||
|
specialValueType: string;
|
||||||
|
|
||||||
|
isIdentity: boolean;
|
||||||
|
|
||||||
|
isRequired: boolean;
|
||||||
|
|
||||||
|
isArray: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ConnectionProviderOptions {
|
||||||
|
options: ConnectionOption[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AdminServicesProviderOptions {
|
||||||
|
databaseInfoOptions: ServiceOption[];
|
||||||
|
|
||||||
|
databaseFileInfoOptions: ServiceOption[];
|
||||||
|
|
||||||
|
fileGroupInfoOptions: ServiceOption[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FeatureMetadataProvider {
|
||||||
|
enabled: boolean;
|
||||||
|
featureName: string;
|
||||||
|
optionsMetadata: ServiceOption[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameters to initialize a connection to a database
|
||||||
|
*/
|
||||||
|
export interface ConnectionDetails {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* connection options
|
||||||
|
*/
|
||||||
|
options: {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Summary that identifies a unique database connection.
|
||||||
|
*/
|
||||||
|
export class ConnectionSummary {
|
||||||
|
/**
|
||||||
|
* server name
|
||||||
|
*/
|
||||||
|
public serverName: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* database name
|
||||||
|
*/
|
||||||
|
public databaseName: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* user name
|
||||||
|
*/
|
||||||
|
public userName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connection response format.
|
||||||
|
*/
|
||||||
|
export class ConnectionCompleteParams {
|
||||||
|
/**
|
||||||
|
* URI identifying the owner of the connection
|
||||||
|
*/
|
||||||
|
public ownerUri: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* connection id returned from service host.
|
||||||
|
*/
|
||||||
|
public connectionId: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* any diagnostic messages return from the service host.
|
||||||
|
*/
|
||||||
|
public messages: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error message returned from the engine, if any.
|
||||||
|
*/
|
||||||
|
public errorMessage: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error number returned from the engine, if any.
|
||||||
|
*/
|
||||||
|
public errorNumber: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information about the connected server.
|
||||||
|
*/
|
||||||
|
public serverInfo: ServerInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* information about the actual connection established
|
||||||
|
*/
|
||||||
|
public connectionSummary: ConnectionSummary;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update event parameters
|
||||||
|
*/
|
||||||
|
export class IntelliSenseReadyParams {
|
||||||
|
/**
|
||||||
|
* URI identifying the text document
|
||||||
|
*/
|
||||||
|
public ownerUri: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information about a SQL Server instance.
|
||||||
|
*/
|
||||||
|
export class ServerInfo {
|
||||||
|
/**
|
||||||
|
* The major version of the SQL Server instance.
|
||||||
|
*/
|
||||||
|
public serverMajorVersion: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The minor version of the SQL Server instance.
|
||||||
|
*/
|
||||||
|
public serverMinorVersion: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The build of the SQL Server instance.
|
||||||
|
*/
|
||||||
|
public serverReleaseVersion: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ID of the engine edition of the SQL Server instance.
|
||||||
|
*/
|
||||||
|
public engineEditionId: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String containing the full server version text.
|
||||||
|
*/
|
||||||
|
public serverVersion: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String describing the product level of the server.
|
||||||
|
*/
|
||||||
|
public serverLevel: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The edition of the SQL Server instance.
|
||||||
|
*/
|
||||||
|
public serverEdition: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the SQL Server instance is running in the cloud (Azure) or not.
|
||||||
|
*/
|
||||||
|
public isCloud: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The version of Azure that the SQL Server instance is running on, if applicable.
|
||||||
|
*/
|
||||||
|
public azureVersion: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Operating System version string of the machine running the SQL Server instance.
|
||||||
|
*/
|
||||||
|
public osVersion: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CapabiltiesDiscoveryResult {
|
||||||
|
public capabilities: data.DataProtocolServerCapabilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Task Services types
|
||||||
|
|
||||||
|
export enum TaskStatus {
|
||||||
|
notStarted = 0,
|
||||||
|
inProgress = 1,
|
||||||
|
succeeded = 2,
|
||||||
|
succeededWithWarning = 3,
|
||||||
|
failed = 4,
|
||||||
|
canceled = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
// Admin Services types
|
||||||
|
|
||||||
|
export interface CreateDatabaseParams {
|
||||||
|
ownerUri: string;
|
||||||
|
|
||||||
|
databaseInfo: data.DatabaseInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DefaultDatabaseInfoParams {
|
||||||
|
ownerUri: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DefaultDatabaseInfoResponse {
|
||||||
|
defaultDatabaseInfo: data.DatabaseInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GetDatabaseInfoResponse {
|
||||||
|
databaseInfo: data.DatabaseInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GetDatabaseInfoParams {
|
||||||
|
ownerUri: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BackupConfigInfoResponse {
|
||||||
|
backupConfigInfo: data.BackupConfigInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CreateLoginParams {
|
||||||
|
ownerUri: string;
|
||||||
|
|
||||||
|
loginInfo: data.LoginInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disaster Recovery types
|
||||||
|
|
||||||
|
export interface BackupInfo {
|
||||||
|
ownerUri: string;
|
||||||
|
|
||||||
|
databaseName: string;
|
||||||
|
|
||||||
|
backupType: number;
|
||||||
|
|
||||||
|
backupComponent: number;
|
||||||
|
|
||||||
|
backupDeviceType: number;
|
||||||
|
|
||||||
|
selectedFiles: string;
|
||||||
|
|
||||||
|
backupsetName: string;
|
||||||
|
|
||||||
|
selectedFileGroup: { [path: string]: string };
|
||||||
|
|
||||||
|
// List of {key: backup path, value: device type}
|
||||||
|
backupPathDevices: { [path: string]: number };
|
||||||
|
|
||||||
|
backupPathList: [string];
|
||||||
|
|
||||||
|
isCopyOnly: boolean;
|
||||||
|
|
||||||
|
formatMedia: boolean;
|
||||||
|
|
||||||
|
initialize: boolean;
|
||||||
|
|
||||||
|
skipTapeHeader: boolean;
|
||||||
|
|
||||||
|
mediaName: string;
|
||||||
|
|
||||||
|
mediaDescription: string;
|
||||||
|
|
||||||
|
checksum: boolean;
|
||||||
|
|
||||||
|
continueAfterError: boolean;
|
||||||
|
|
||||||
|
logTruncation: boolean;
|
||||||
|
|
||||||
|
tailLogBackup: boolean;
|
||||||
|
|
||||||
|
retainDays: number;
|
||||||
|
|
||||||
|
compressionOption: number;
|
||||||
|
|
||||||
|
verifyBackupRequired: boolean;
|
||||||
|
|
||||||
|
encryptionAlgorithm: number;
|
||||||
|
|
||||||
|
encryptorType: number;
|
||||||
|
|
||||||
|
encryptorName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BackupParams {
|
||||||
|
ownerUri: string;
|
||||||
|
|
||||||
|
backupInfo: BackupInfo;
|
||||||
|
|
||||||
|
taskExecutionMode: data.TaskExecutionMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RestoreParams {
|
||||||
|
ownerUri: string;
|
||||||
|
options: {};
|
||||||
|
taskExecutionMode: data.TaskExecutionMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RestoreConfigInfoRequestParams {
|
||||||
|
ownerUri: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RestoreConfigInfoResponse {
|
||||||
|
configInfo: { [key: string]: any };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RestoreDatabaseFileInfo {
|
||||||
|
fileType: string;
|
||||||
|
|
||||||
|
logicalFileName: string;
|
||||||
|
|
||||||
|
originalFileName: string;
|
||||||
|
|
||||||
|
restoreAsFileName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FileBrowserOpenParams {
|
||||||
|
ownerUri: string;
|
||||||
|
expandPath: string;
|
||||||
|
fileFilters: string[];
|
||||||
|
changeFilter: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FileTreeNode {
|
||||||
|
children: FileTreeNode[];
|
||||||
|
isExpanded: boolean;
|
||||||
|
isFile: boolean;
|
||||||
|
name: string;
|
||||||
|
fullPath: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FileTree {
|
||||||
|
rootNode: FileTreeNode;
|
||||||
|
selectedNode: FileTreeNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FileBrowserExpandParams {
|
||||||
|
ownerUri: string;
|
||||||
|
expandPath: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FileBrowserValidateParams {
|
||||||
|
ownerUri: string;
|
||||||
|
serviceType: string;
|
||||||
|
selectedFiles: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FileBrowserCloseParams {
|
||||||
|
ownerUri: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DatabaseFileInfo {
|
||||||
|
properties: LocalizedPropertyInfo[];
|
||||||
|
id: string;
|
||||||
|
isSelected: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LocalizedPropertyInfo {
|
||||||
|
propertyName: string;
|
||||||
|
propertyValue: string;
|
||||||
|
propertyDisplayName: string;
|
||||||
|
propertyValueDisplayName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RestorePlanDetailInfo {
|
||||||
|
name: string;
|
||||||
|
currentValue: any;
|
||||||
|
isReadOnly: boolean;
|
||||||
|
isVisible: boolean;
|
||||||
|
defaultValue: any;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query Execution types
|
||||||
|
export interface ResultSetSummary {
|
||||||
|
id: number;
|
||||||
|
batchId: number;
|
||||||
|
rowCount: number;
|
||||||
|
columnInfo: IDbColumn[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BatchSummary {
|
||||||
|
hasError: boolean;
|
||||||
|
id: number;
|
||||||
|
selection: data.ISelectionData;
|
||||||
|
resultSetSummaries: ResultSetSummary[];
|
||||||
|
executionElapsed: string;
|
||||||
|
executionEnd: string;
|
||||||
|
executionStart: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IDbColumn {
|
||||||
|
allowDBNull?: boolean;
|
||||||
|
baseCatalogName: string;
|
||||||
|
baseColumnName: string;
|
||||||
|
baseSchemaName: string;
|
||||||
|
baseServerName: string;
|
||||||
|
baseTableName: string;
|
||||||
|
columnName: string;
|
||||||
|
columnOrdinal?: number;
|
||||||
|
columnSize?: number;
|
||||||
|
isAliased?: boolean;
|
||||||
|
isAutoIncrement?: boolean;
|
||||||
|
isExpression?: boolean;
|
||||||
|
isHidden?: boolean;
|
||||||
|
isIdentity?: boolean;
|
||||||
|
isKey?: boolean;
|
||||||
|
isBytes?: boolean;
|
||||||
|
isChars?: boolean;
|
||||||
|
isSqlVariant?: boolean;
|
||||||
|
isUdt?: boolean;
|
||||||
|
dataType: string;
|
||||||
|
isXml?: boolean;
|
||||||
|
isJson?: boolean;
|
||||||
|
isLong?: boolean;
|
||||||
|
isReadOnly?: boolean;
|
||||||
|
isUnique?: boolean;
|
||||||
|
numericPrecision?: number;
|
||||||
|
numericScale?: number;
|
||||||
|
udtAssemblyQualifiedName: string;
|
||||||
|
dataTypeName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IGridResultSet {
|
||||||
|
columns: IDbColumn[];
|
||||||
|
rowsUri: string;
|
||||||
|
numberOfRows: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IResultMessage {
|
||||||
|
batchId?: number;
|
||||||
|
isError: boolean;
|
||||||
|
time: string;
|
||||||
|
message: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ExecutionPlanOptions {
|
||||||
|
includeEstimatedExecutionPlanXml?: boolean;
|
||||||
|
includeActualExecutionPlanXml?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface QueryExecuteParams {
|
||||||
|
ownerUri: string;
|
||||||
|
querySelection: data.ISelectionData;
|
||||||
|
executionPlanOptions?: ExecutionPlanOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum EditRowState {
|
||||||
|
clean = 0,
|
||||||
|
dirtyInsert = 1,
|
||||||
|
dirtyDelete = 2,
|
||||||
|
dirtyUpdate = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EditRow {
|
||||||
|
cells: data.DbCellValue[];
|
||||||
|
id: number;
|
||||||
|
isDirty: boolean;
|
||||||
|
state: EditRowState;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class MetadataQueryParams {
|
||||||
|
/**
|
||||||
|
* Owner URI of the connection that changed.
|
||||||
|
*/
|
||||||
|
public ownerUri: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used as value version of data.MetadataType THESE SHOULD MIRROR
|
||||||
|
*/
|
||||||
|
export enum MetadataType {
|
||||||
|
Table = 0,
|
||||||
|
View = 1,
|
||||||
|
SProc = 2,
|
||||||
|
Function = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
export class MetadataQueryResult {
|
||||||
|
public metadata: data.ObjectMetadata[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ScriptOptions {
|
||||||
|
/**
|
||||||
|
* Generate ANSI padding statements
|
||||||
|
*/
|
||||||
|
scriptANSIPadding?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append the generated script to a file
|
||||||
|
*/
|
||||||
|
appendToFile?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Continue to script if an error occurs. Otherwise, stop.
|
||||||
|
*/
|
||||||
|
continueScriptingOnError?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert user-defined data types to base types.
|
||||||
|
*/
|
||||||
|
convertUDDTToBaseType?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate script for dependent objects for each object scripted.
|
||||||
|
*/
|
||||||
|
generateScriptForDependentObjects?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include descriptive headers for each object generated.
|
||||||
|
*/
|
||||||
|
includeDescriptiveHeaders?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check that an object with the given name exists before dropping or altering or that an object with the given name does not exist before creating.
|
||||||
|
*/
|
||||||
|
includeIfNotExists?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Script options to set vardecimal storage format.
|
||||||
|
*/
|
||||||
|
includeVarDecimal?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include system generated constraint names to enforce declarative referential integrity.
|
||||||
|
*/
|
||||||
|
scriptDRIIncludeSystemNames?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include statements in the script that are not supported on the specified SQL Server database engine type.
|
||||||
|
*/
|
||||||
|
includeUnsupportedStatements?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prefix object names with the object schema.
|
||||||
|
*/
|
||||||
|
schemaQualify?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Script options to set bindings option.
|
||||||
|
*/
|
||||||
|
bindings?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Script the objects that use collation.
|
||||||
|
*/
|
||||||
|
collation?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Script the default values.
|
||||||
|
*/
|
||||||
|
default?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Script Object CREATE/DROP statements.
|
||||||
|
*/
|
||||||
|
scriptCreateDrop: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Script the Extended Properties for each object scripted.
|
||||||
|
*/
|
||||||
|
scriptExtendedProperties?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Script only features compatible with the specified version of SQL Server.
|
||||||
|
*/
|
||||||
|
scriptCompatibilityOption: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Script only features compatible with the specified SQL Server database engine type.
|
||||||
|
*/
|
||||||
|
targetDatabaseEngineType: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Script only features compatible with the specified SQL Server database engine edition.
|
||||||
|
*/
|
||||||
|
targetDatabaseEngineEdition: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Script all logins available on the server. Passwords will not be scripted.
|
||||||
|
*/
|
||||||
|
scriptLogins?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate object-level permissions.
|
||||||
|
*/
|
||||||
|
scriptObjectLevelPermissions?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Script owner for the objects.
|
||||||
|
*/
|
||||||
|
scriptOwner?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Script statistics, and optionally include histograms, for each selected table or view.
|
||||||
|
*/
|
||||||
|
scriptStatistics: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate USE DATABASE statement.
|
||||||
|
*/
|
||||||
|
scripUseDatabase?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate script that contains schema only or schema and data.
|
||||||
|
*/
|
||||||
|
typeOfDataToScript: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scripts the change tracking information.
|
||||||
|
*/
|
||||||
|
scriptChangeTracking?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Script the check constraints for each table or view scripted.
|
||||||
|
*/
|
||||||
|
scriptCheckConstraints?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scripts the data compression information.
|
||||||
|
*/
|
||||||
|
scriptDataCompressionOptions?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Script the foreign keys for each table scripted.
|
||||||
|
*/
|
||||||
|
scriptForeignKeys?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Script the full-text indexes for each table or indexed view scripted.
|
||||||
|
*/
|
||||||
|
scriptFullTextIndexes?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Script the indexes (including XML and clustered indexes) for each table or indexed view scripted.
|
||||||
|
*/
|
||||||
|
scriptIndexes?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Script the primary keys for each table or view scripted
|
||||||
|
*/
|
||||||
|
scriptPrimaryKeys?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Script the triggers for each table or view scripted
|
||||||
|
*/
|
||||||
|
scriptTriggers?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Script the unique keys for each table or view scripted.
|
||||||
|
*/
|
||||||
|
uniqueKeys?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ScriptingObject {
|
||||||
|
/**
|
||||||
|
* The database object type
|
||||||
|
*/
|
||||||
|
type: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The schema of the database object
|
||||||
|
*/
|
||||||
|
schema: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The database object name
|
||||||
|
*/
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ScriptingParams {
|
||||||
|
/**
|
||||||
|
* File path used when writing out the script.
|
||||||
|
*/
|
||||||
|
filePath: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether scripting to a single file or file per object.
|
||||||
|
*/
|
||||||
|
scriptDestination: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connection string of the target database the scripting operation will run against.
|
||||||
|
*/
|
||||||
|
connectionString: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of scripting objects to script
|
||||||
|
*/
|
||||||
|
scriptingObjects: ScriptingObject[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of scripting object which specify the include criteria of objects to script.
|
||||||
|
*/
|
||||||
|
includeObjectCriteria: ScriptingObject[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of scripting object which specify the exclude criteria of objects to not script.
|
||||||
|
*/
|
||||||
|
excludeObjectCriteria: ScriptingObject[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of schema name of objects to script.
|
||||||
|
*/
|
||||||
|
includeSchemas: string[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of schema name of objects to not script.
|
||||||
|
*/
|
||||||
|
excludeSchemas: string[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of type name of objects to script.
|
||||||
|
*/
|
||||||
|
includeTypes: string[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of type name of objects to not script.
|
||||||
|
*/
|
||||||
|
excludeTypes: string[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scripting options for the ScriptingParams
|
||||||
|
*/
|
||||||
|
scriptOptions: ScriptOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connection details for the ScriptingParams
|
||||||
|
*/
|
||||||
|
connectionDetails: ConnectionDetails;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Owner URI of the connection
|
||||||
|
*/
|
||||||
|
ownerURI: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the scripting operation is for
|
||||||
|
* select script statements
|
||||||
|
*/
|
||||||
|
selectScript: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Operation associated with the script request
|
||||||
|
*/
|
||||||
|
operation: data.ScriptOperation;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ScriptingCompleteParams {
|
||||||
|
/**
|
||||||
|
* The error details for an error that occurred during the scripting operation.
|
||||||
|
*/
|
||||||
|
errorDetails: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The error message for an error that occurred during the scripting operation.
|
||||||
|
*/
|
||||||
|
errorMessage: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A value to indicate an error occurred during the scripting operation.
|
||||||
|
*/
|
||||||
|
hasError: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A value to indicate the scripting operation was canceled.
|
||||||
|
*/
|
||||||
|
canceled: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A value to indicate the scripting operation successfully completed.
|
||||||
|
*/
|
||||||
|
success: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TableMetadata {
|
||||||
|
|
||||||
|
columns: data.ColumnMetadata[];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameters to start a profiler session
|
||||||
|
*/
|
||||||
|
export interface StartProfilingParams {
|
||||||
|
/**
|
||||||
|
* Session Owner URI
|
||||||
|
*/
|
||||||
|
ownerUri: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Session options
|
||||||
|
*/
|
||||||
|
options: {};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StartProfilingResponse {
|
||||||
|
succeeded: string;
|
||||||
|
errorMessage: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameters to start a profiler session
|
||||||
|
*/
|
||||||
|
export interface StopProfilingParams {
|
||||||
|
/**
|
||||||
|
* Session Owner URI
|
||||||
|
*/
|
||||||
|
ownerUri: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StopProfilingResponse {
|
||||||
|
succeeded: string;
|
||||||
|
errorMessage: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Profiler Event
|
||||||
|
*/
|
||||||
|
export interface ProfilerEvent {
|
||||||
|
/**
|
||||||
|
* Event class name
|
||||||
|
*/
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event timestamp
|
||||||
|
*/
|
||||||
|
timestamp: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event values
|
||||||
|
*/
|
||||||
|
values: {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Profiler events available notification parameters
|
||||||
|
*/
|
||||||
|
export interface ProfilerEventsAvailableParams {
|
||||||
|
/**
|
||||||
|
* Session owner URI
|
||||||
|
*/
|
||||||
|
ownerUri: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New profiler events available
|
||||||
|
*/
|
||||||
|
events: ProfilerEvent[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used as value version of data.ScriptOperation THESE SHOULD BE THE SAME
|
||||||
|
*/
|
||||||
|
export enum ScriptOperation {
|
||||||
|
Select = 0,
|
||||||
|
Create = 1,
|
||||||
|
Insert = 2,
|
||||||
|
Update = 3,
|
||||||
|
Delete = 4,
|
||||||
|
Execute = 5,
|
||||||
|
Alter = 6
|
||||||
|
}
|
||||||
2
dataprotocol-client/src/typings/ref.d.ts
vendored
Normal file
2
dataprotocol-client/src/typings/ref.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
/// <reference path='../../../src/sql/data.d.ts'/>
|
||||||
17
dataprotocol-client/tsfmt.json
Normal file
17
dataprotocol-client/tsfmt.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"tabSize": 4,
|
||||||
|
"indentSize": 4,
|
||||||
|
"newLineCharacter": "\n",
|
||||||
|
"convertTabsToSpaces": false,
|
||||||
|
"insertSpaceAfterCommaDelimiter": true,
|
||||||
|
"insertSpaceAfterSemicolonInForStatements": true,
|
||||||
|
"insertSpaceBeforeAndAfterBinaryOperators": true,
|
||||||
|
"insertSpaceAfterKeywordsInControlFlowStatements": true,
|
||||||
|
"insertSpaceAfterFunctionKeywordForAnonymousFunctions": true,
|
||||||
|
"insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false,
|
||||||
|
"insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false,
|
||||||
|
"insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false,
|
||||||
|
"insertSpaceBeforeFunctionParenthesis": false,
|
||||||
|
"placeOpenBraceOnNewLineForFunctions": false,
|
||||||
|
"placeOpenBraceOnNewLineForControlBlocks": false
|
||||||
|
}
|
||||||
1748
dataprotocol-client/yarn.lock
Normal file
1748
dataprotocol-client/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
3
extensions-modules/.gitignore
vendored
Normal file
3
extensions-modules/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
lib/
|
||||||
|
node_modules
|
||||||
|
*.log
|
||||||
9
extensions-modules/.npmignore
Normal file
9
extensions-modules/.npmignore
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
.vscode/
|
||||||
|
lib/test/
|
||||||
|
lib/**/*.map
|
||||||
|
src/
|
||||||
|
test/
|
||||||
|
.eslintrc
|
||||||
|
.gitignore
|
||||||
|
gulpfile.js
|
||||||
|
tsd.json
|
||||||
28
extensions-modules/package.json
Normal file
28
extensions-modules/package.json
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"name": "extensions-modules",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"description": "Shared modules for Carbon extensions",
|
||||||
|
"dependencies": {
|
||||||
|
"dataprotocol-client": "file:../dataprotocol-client",
|
||||||
|
"decompress": "^4.2.0",
|
||||||
|
"fs-extra-promise": "^1.0.1",
|
||||||
|
"http-proxy-agent": "^2.0.0",
|
||||||
|
"https-proxy-agent": "^2.1.0",
|
||||||
|
"opener": "^1.4.3",
|
||||||
|
"tmp": "0.0.33",
|
||||||
|
"vscode-extension-telemetry": "0.0.8",
|
||||||
|
"vscode-languageclient": "^3.5.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^6.0.61",
|
||||||
|
"vscode": "1.0.1"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"prepare": "tsc -p ./src",
|
||||||
|
"compile": "tsc -p ./src",
|
||||||
|
"watch": "tsc -w -p ./src",
|
||||||
|
"update-vscode": "node ./node_modules/vscode/bin/install"
|
||||||
|
},
|
||||||
|
"main": "./lib/main.js",
|
||||||
|
"typings": "./lib/main"
|
||||||
|
}
|
||||||
89
extensions-modules/src/configurations/config.ts
Normal file
89
extensions-modules/src/configurations/config.ts
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
const fs = require('fs');
|
||||||
|
import * as path from 'path';
|
||||||
|
import { IConfig } from '../languageservice/interfaces';
|
||||||
|
import { Constants } from '../models/constants';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Config class handles getting values from config.json.
|
||||||
|
*/
|
||||||
|
export default class Config implements IConfig {
|
||||||
|
private _configJsonContent: any = undefined;
|
||||||
|
|
||||||
|
private _extensionConfigSectionName: string = undefined;
|
||||||
|
private _fromBuild: boolean = undefined;
|
||||||
|
|
||||||
|
constructor(extensionConfigSectionName: string, private path: string, fromBuild?: boolean) {
|
||||||
|
this._extensionConfigSectionName = extensionConfigSectionName;
|
||||||
|
this._fromBuild = fromBuild;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get configJsonContent(): any {
|
||||||
|
if (this._configJsonContent === undefined) {
|
||||||
|
this._configJsonContent = this.loadConfig();
|
||||||
|
}
|
||||||
|
return this._configJsonContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getDownloadUrl(): string {
|
||||||
|
return this.getConfigValue(Constants.downloadUrlConfigKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getInstallDirectory(): string {
|
||||||
|
return this.getConfigValue(Constants.installDirConfigKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getExecutableFiles(): string[] {
|
||||||
|
return this.getConfigValue(Constants.executableFilesConfigKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getPackageVersion(): string {
|
||||||
|
return this.getConfigValue(Constants.versionConfigKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getConfigValue(configKey: string): any {
|
||||||
|
let json = this.configJsonContent;
|
||||||
|
let toolsConfig = json[Constants.serviceConfigKey];
|
||||||
|
let configValue: string = undefined;
|
||||||
|
if (toolsConfig !== undefined) {
|
||||||
|
configValue = toolsConfig[configKey];
|
||||||
|
}
|
||||||
|
return configValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getExtensionConfig(key: string, defaultValue?: any): any {
|
||||||
|
let json = this.configJsonContent;
|
||||||
|
let extensionConfig = json[this._extensionConfigSectionName];
|
||||||
|
let configValue = extensionConfig[key];
|
||||||
|
if (!configValue) {
|
||||||
|
configValue = defaultValue;
|
||||||
|
}
|
||||||
|
return configValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getWorkspaceConfig(key: string, defaultValue?: any): any {
|
||||||
|
let json = this.configJsonContent;
|
||||||
|
let configValue = json[key];
|
||||||
|
if (!configValue) {
|
||||||
|
configValue = defaultValue;
|
||||||
|
}
|
||||||
|
return configValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public loadConfig(): any {
|
||||||
|
let configContent = undefined;
|
||||||
|
if (this._fromBuild) {
|
||||||
|
let remainingPath = '../../../extensions/' + this._extensionConfigSectionName + '/client/out/config.json';
|
||||||
|
configContent = fs.readFileSync(path.join(__dirname, remainingPath));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
configContent = fs.readFileSync(this.path);
|
||||||
|
}
|
||||||
|
return JSON.parse(configContent);
|
||||||
|
}
|
||||||
|
}
|
||||||
76
extensions-modules/src/configurations/extConfig.ts
Normal file
76
extensions-modules/src/configurations/extConfig.ts
Normal file
@@ -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.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import Config from './config';
|
||||||
|
import { workspace, WorkspaceConfiguration } from 'vscode';
|
||||||
|
import { IConfig } from '../languageservice/interfaces';
|
||||||
|
import { Constants } from '../models/constants';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ExtConfig class handles getting values from workspace config or config.json.
|
||||||
|
*/
|
||||||
|
export default class ExtConfig implements IConfig {
|
||||||
|
|
||||||
|
constructor(private _extensionConfigSectionName: string, private _config?: IConfig,
|
||||||
|
path?: string,
|
||||||
|
private _extensionConfig?: WorkspaceConfiguration,
|
||||||
|
private _workspaceConfig?: WorkspaceConfiguration) {
|
||||||
|
if (this._config === undefined) {
|
||||||
|
this._config = new Config(_extensionConfigSectionName, path);
|
||||||
|
}
|
||||||
|
if (this._extensionConfig === undefined) {
|
||||||
|
this._extensionConfig = workspace.getConfiguration(_extensionConfigSectionName);
|
||||||
|
}
|
||||||
|
if (this._workspaceConfig === undefined) {
|
||||||
|
this._workspaceConfig = workspace.getConfiguration();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public getDownloadUrl(): string {
|
||||||
|
return this.getConfigValue(Constants.downloadUrlConfigKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getInstallDirectory(): string {
|
||||||
|
return this.getConfigValue(Constants.installDirConfigKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getExecutableFiles(): string[] {
|
||||||
|
return this.getConfigValue(Constants.executableFilesConfigKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getPackageVersion(): string {
|
||||||
|
return this.getConfigValue(Constants.versionConfigKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getConfigValue(configKey: string): any {
|
||||||
|
let configValue: string = <string>this.getExtensionConfig(`${Constants.serviceConfigKey}.${configKey}`);
|
||||||
|
if (!configValue) {
|
||||||
|
configValue = this._config.getConfigValue(configKey);
|
||||||
|
}
|
||||||
|
return configValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getExtensionConfig(key: string, defaultValue?: any): any {
|
||||||
|
let configValue = this._extensionConfig.get(key);
|
||||||
|
if (configValue === undefined) {
|
||||||
|
configValue = defaultValue;
|
||||||
|
}
|
||||||
|
return configValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getWorkspaceConfig(key: string, defaultValue?: any): any {
|
||||||
|
let configValue = this._workspaceConfig.get(key);
|
||||||
|
if (configValue === undefined) {
|
||||||
|
configValue = defaultValue;
|
||||||
|
}
|
||||||
|
return configValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public updateWorkspaceConfig(configKey: string, configValue: any) {
|
||||||
|
this._workspaceConfig.update(configKey, configValue, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
278
extensions-modules/src/controllers/vscodeWrapper.ts
Normal file
278
extensions-modules/src/controllers/vscodeWrapper.ts
Normal file
@@ -0,0 +1,278 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import vscode = require('vscode');
|
||||||
|
import { IExtensionConstants } from '../models/contracts/contracts';
|
||||||
|
|
||||||
|
export class VscodeWrapper {
|
||||||
|
private _extensionConstants: IExtensionConstants;
|
||||||
|
/**
|
||||||
|
* Output channel for logging. Shared among all instances.
|
||||||
|
*/
|
||||||
|
private static _outputChannel: vscode.OutputChannel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor.
|
||||||
|
*/
|
||||||
|
public constructor(constants: IExtensionConstants) {
|
||||||
|
this._extensionConstants = constants;
|
||||||
|
if (typeof VscodeWrapper._outputChannel === 'undefined') {
|
||||||
|
VscodeWrapper._outputChannel = this.createOutputChannel(this._extensionConstants.outputChannelName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current active text editor
|
||||||
|
*/
|
||||||
|
public get activeTextEditor(): vscode.TextEditor {
|
||||||
|
return vscode.window.activeTextEditor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the current textDocument; any that are open?
|
||||||
|
*/
|
||||||
|
public get textDocuments(): vscode.TextDocument[] {
|
||||||
|
return vscode.workspace.textDocuments;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse uri
|
||||||
|
*/
|
||||||
|
public parseUri(uri: string): vscode.Uri {
|
||||||
|
return vscode.Uri.parse(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the URI string for the current active text editor
|
||||||
|
*/
|
||||||
|
public get activeTextEditorUri(): string {
|
||||||
|
if (typeof vscode.window.activeTextEditor !== 'undefined' &&
|
||||||
|
typeof vscode.window.activeTextEditor.document !== 'undefined') {
|
||||||
|
return vscode.window.activeTextEditor.document.uri.toString();
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get constants(): IExtensionConstants {
|
||||||
|
return this._extensionConstants;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an output channel in vscode.
|
||||||
|
*/
|
||||||
|
public createOutputChannel(channelName: string): vscode.OutputChannel {
|
||||||
|
return vscode.window.createOutputChannel(channelName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the command denoted by the given command identifier.
|
||||||
|
*
|
||||||
|
* When executing an editor command not all types are allowed to
|
||||||
|
* be passed as arguments. Allowed are the primitive types `string`, `boolean`,
|
||||||
|
* `number`, `undefined`, and `null`, as well as classes defined in this API.
|
||||||
|
* There are no restrictions when executing commands that have been contributed
|
||||||
|
* by extensions.
|
||||||
|
*
|
||||||
|
* @param command Identifier of the command to execute.
|
||||||
|
* @param rest Parameters passed to the command function.
|
||||||
|
* @return A thenable that resolves to the returned value of the given command. `undefined` when
|
||||||
|
* the command handler function doesn't return anything.
|
||||||
|
* @see vscode.commands.executeCommand
|
||||||
|
*/
|
||||||
|
public executeCommand<T>(command: string, ...rest: any[]): Thenable<T> {
|
||||||
|
return vscode.commands.executeCommand<T>(command, ...rest);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the configuration for a extensionName; NOT YET IMPLEMENTED
|
||||||
|
* @param extensionName The string name of the extension to get the configuration for
|
||||||
|
*/
|
||||||
|
public getConfiguration(extensionName: string): vscode.WorkspaceConfiguration {
|
||||||
|
return vscode.workspace.getConfiguration(extensionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return 'true' if the active editor window has a .sql file, false otherwise
|
||||||
|
*/
|
||||||
|
public get isEditingSqlFile(): boolean {
|
||||||
|
let sqlFile = false;
|
||||||
|
let editor = this.activeTextEditor;
|
||||||
|
if (editor) {
|
||||||
|
if (editor.document.languageId === this._extensionConstants.languageId) {
|
||||||
|
sqlFile = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sqlFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An event that is emitted when a [text document](#TextDocument) is disposed.
|
||||||
|
*/
|
||||||
|
public get onDidCloseTextDocument(): vscode.Event<vscode.TextDocument> {
|
||||||
|
return vscode.workspace.onDidCloseTextDocument;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An event that is emitted when a [text document](#TextDocument) is opened.
|
||||||
|
*/
|
||||||
|
public get onDidOpenTextDocument(): vscode.Event<vscode.TextDocument> {
|
||||||
|
return vscode.workspace.onDidOpenTextDocument;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An event that is emitted when a [text document](#TextDocument) is saved to disk.
|
||||||
|
*/
|
||||||
|
public get onDidSaveTextDocument(): vscode.Event<vscode.TextDocument> {
|
||||||
|
return vscode.workspace.onDidSaveTextDocument;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the denoted document from disk. Will return early if the
|
||||||
|
* document is already open, otherwise the document is loaded and the
|
||||||
|
* [open document](#workspace.onDidOpenTextDocument)-event fires.
|
||||||
|
* The document to open is denoted by the [uri](#Uri). Two schemes are supported:
|
||||||
|
*
|
||||||
|
* file: A file on disk, will be rejected if the file does not exist or cannot be loaded, e.g. `file:///Users/frodo/r.ini`.
|
||||||
|
* untitled: A new file that should be saved on disk, e.g. `untitled:c:\frodo\new.js`. The language will be derived from the file name.
|
||||||
|
*
|
||||||
|
* Uris with other schemes will make this method return a rejected promise.
|
||||||
|
*
|
||||||
|
* @param uri Identifies the resource to open.
|
||||||
|
* @return A promise that resolves to a [document](#TextDocument).
|
||||||
|
* @see vscode.workspace.openTextDocument
|
||||||
|
*/
|
||||||
|
public openTextDocument(uri: vscode.Uri): Thenable<vscode.TextDocument> {
|
||||||
|
return vscode.workspace.openTextDocument(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to log messages to output channel.
|
||||||
|
*/
|
||||||
|
public logToOutputChannel(msg: any): void {
|
||||||
|
let date: Date = new Date();
|
||||||
|
if (msg instanceof Array) {
|
||||||
|
msg.forEach(element => {
|
||||||
|
VscodeWrapper._outputChannel.appendLine('[' + date.toLocaleTimeString() + '] ' + element.toString());
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
VscodeWrapper._outputChannel.appendLine('[' + date.toLocaleTimeString() + '] ' + msg.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a vscode.Range object
|
||||||
|
* @param start The start position for the range
|
||||||
|
* @param end The end position for the range
|
||||||
|
*/
|
||||||
|
public range(start: vscode.Position, end: vscode.Position): vscode.Range {
|
||||||
|
return new vscode.Range(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a vscode.Position object
|
||||||
|
* @param line The line for the position
|
||||||
|
* @param column The column for the position
|
||||||
|
*/
|
||||||
|
public position(line: number, column: number): vscode.Position {
|
||||||
|
return new vscode.Position(line, column);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a vscode.Selection object
|
||||||
|
* @param start The start postion of the selection
|
||||||
|
* @param end The end position of the selection
|
||||||
|
*/
|
||||||
|
public selection(start: vscode.Position, end: vscode.Position): vscode.Selection {
|
||||||
|
return new vscode.Selection(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats and shows a vscode error message
|
||||||
|
*/
|
||||||
|
public showErrorMessage(msg: string, ...items: string[]): Thenable<string> {
|
||||||
|
return vscode.window.showErrorMessage(this._extensionConstants.extensionName + ': ' + msg, ...items);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats and shows a vscode information message
|
||||||
|
*/
|
||||||
|
public showInformationMessage(msg: string, ...items: string[]): Thenable<string> {
|
||||||
|
return vscode.window.showInformationMessage(this._extensionConstants.extensionName + ': ' + msg, ...items);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a selection list.
|
||||||
|
*
|
||||||
|
* @param items An array of items, or a promise that resolves to an array of items.
|
||||||
|
* @param options Configures the behavior of the selection list.
|
||||||
|
* @return A promise that resolves to the selected item or undefined.
|
||||||
|
*/
|
||||||
|
public showQuickPick<T extends vscode.QuickPickItem>(items: T[] | Thenable<T[]>, options?: vscode.QuickPickOptions): Thenable<T> {
|
||||||
|
return vscode.window.showQuickPick<T>(items, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the given document in a text editor. A [column](#ViewColumn) can be provided
|
||||||
|
* to control where the editor is being shown. Might change the [active editor](#window.activeTextEditor).
|
||||||
|
*
|
||||||
|
* @param document A text document to be shown.
|
||||||
|
* @param column A view column in which the editor should be shown. The default is the [one](#ViewColumn.One), other values
|
||||||
|
* are adjusted to be __Min(column, columnCount + 1)__.
|
||||||
|
* @param preserveFocus When `true` the editor will not take focus.
|
||||||
|
* @return A promise that resolves to an [editor](#TextEditor).
|
||||||
|
*/
|
||||||
|
public showTextDocument(document: vscode.TextDocument, column?: vscode.ViewColumn, preserveFocus?: boolean): Thenable<vscode.TextEditor> {
|
||||||
|
return vscode.window.showTextDocument(document, column, preserveFocus);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats and shows a vscode warning message
|
||||||
|
*/
|
||||||
|
public showWarningMessage(msg: string): Thenable<string> {
|
||||||
|
return vscode.window.showWarningMessage(this._extensionConstants.extensionName + ': ' + msg );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a array of the text editors currently visible in the window
|
||||||
|
*/
|
||||||
|
public get visibleEditors(): vscode.TextEditor[] {
|
||||||
|
return vscode.window.visibleTextEditors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an URI from a file system path. The [scheme](#Uri.scheme)
|
||||||
|
* will be `file`.
|
||||||
|
*
|
||||||
|
* @param path A file system or UNC path.
|
||||||
|
* @return A new Uri instance.
|
||||||
|
* @see vscode.Uri.file
|
||||||
|
*/
|
||||||
|
public uriFile(path: string): vscode.Uri {
|
||||||
|
return vscode.Uri.file(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an URI from a string. Will throw if the given value is not
|
||||||
|
* valid.
|
||||||
|
*
|
||||||
|
* @param value The string value of an Uri.
|
||||||
|
* @return A new Uri instance.
|
||||||
|
* @see vscode.Uri.parse
|
||||||
|
*/
|
||||||
|
public uriParse(value: string): vscode.Uri {
|
||||||
|
return vscode.Uri.parse(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The folder that is open in VS Code. `undefined` when no folder
|
||||||
|
* has been opened.
|
||||||
|
*
|
||||||
|
* @readonly
|
||||||
|
* @see vscode.workspace.rootPath
|
||||||
|
*/
|
||||||
|
public get workspaceRootPath(): string {
|
||||||
|
return vscode.workspace.rootPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
24
extensions-modules/src/languageservice/decompressProvider.ts
Normal file
24
extensions-modules/src/languageservice/decompressProvider.ts
Normal file
@@ -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.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import { IDecompressProvider, IPackage } from './interfaces';
|
||||||
|
import { ILogger } from '../models/interfaces';
|
||||||
|
const decompress = require('decompress');
|
||||||
|
|
||||||
|
export default class DecompressProvider implements IDecompressProvider {
|
||||||
|
public decompress(pkg: IPackage, logger: ILogger): Promise<void> {
|
||||||
|
return new Promise<void>((resolve, reject) => {
|
||||||
|
decompress(pkg.tmpFile.name, pkg.installPath).then(files => {
|
||||||
|
logger.appendLine(`Done! ${files.length} files unpacked.\n`);
|
||||||
|
resolve();
|
||||||
|
}).catch(decompressErr => {
|
||||||
|
logger.appendLine(`[ERROR] ${decompressErr}`);
|
||||||
|
reject(decompressErr);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
146
extensions-modules/src/languageservice/httpClient.ts
Normal file
146
extensions-modules/src/languageservice/httpClient.ts
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* 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 { IPackage, IStatusView, PackageError, IHttpClient } from './interfaces';
|
||||||
|
import { ILogger } from '../models/interfaces';
|
||||||
|
import { parse as parseUrl, Url } from 'url';
|
||||||
|
import * as https from 'https';
|
||||||
|
import * as http from 'http';
|
||||||
|
import { getProxyAgent } from './proxy';
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Http client class to handle downloading files using http or https urls
|
||||||
|
*/
|
||||||
|
export default class HttpClient implements IHttpClient {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Downloads a file and stores the result in the temp file inside the package object
|
||||||
|
*/
|
||||||
|
public downloadFile(urlString: string, pkg: IPackage, logger: ILogger, statusView: IStatusView, proxy?: string, strictSSL?: boolean): Promise<void> {
|
||||||
|
const url = parseUrl(urlString);
|
||||||
|
let options = this.getHttpClientOptions(url, proxy, strictSSL);
|
||||||
|
let clientRequest = url.protocol === 'http:' ? http.request : https.request;
|
||||||
|
|
||||||
|
return new Promise<void>((resolve, reject) => {
|
||||||
|
if (!pkg.tmpFile || pkg.tmpFile.fd === 0) {
|
||||||
|
return reject(new PackageError('Temporary package file unavailable', pkg));
|
||||||
|
}
|
||||||
|
|
||||||
|
let request = clientRequest(options, response => {
|
||||||
|
if (response.statusCode === 301 || response.statusCode === 302) {
|
||||||
|
// Redirect - download from new location
|
||||||
|
return resolve(this.downloadFile(response.headers.location, pkg, logger, statusView, proxy, strictSSL));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.statusCode !== 200) {
|
||||||
|
// Download failed - print error message
|
||||||
|
logger.appendLine(`failed (error code '${response.statusCode}')`);
|
||||||
|
return reject(new PackageError(response.statusCode.toString(), pkg));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If status code is 200
|
||||||
|
this.handleSuccessfulResponse(pkg, response, logger, statusView).then(_ => {
|
||||||
|
resolve();
|
||||||
|
}).catch(err => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
request.on('error', error => {
|
||||||
|
// reject(new PackageError(`Request error: ${error.code || 'NONE'}`, pkg, error));
|
||||||
|
reject(new PackageError(`Request error: ${error.name || 'NONE'}`, pkg, error));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Execute the request
|
||||||
|
request.end();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private getHttpClientOptions(url: Url, proxy?: string, strictSSL?: boolean): any {
|
||||||
|
const agent = getProxyAgent(url, proxy, strictSSL);
|
||||||
|
|
||||||
|
let options: http.RequestOptions = {
|
||||||
|
host: url.hostname,
|
||||||
|
path: url.path,
|
||||||
|
agent: agent,
|
||||||
|
port: +url.port
|
||||||
|
};
|
||||||
|
|
||||||
|
if (url.protocol === 'https:') {
|
||||||
|
let httpsOptions: https.RequestOptions = {
|
||||||
|
host: url.hostname,
|
||||||
|
path: url.path,
|
||||||
|
agent: agent,
|
||||||
|
port: +url.port
|
||||||
|
};
|
||||||
|
options = httpsOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate the download percentage and stores in the progress object
|
||||||
|
*/
|
||||||
|
public handleDataReceivedEvent(progress: IDownloadProgress, data: any, logger: ILogger, statusView: IStatusView): void {
|
||||||
|
progress.downloadedBytes += data.length;
|
||||||
|
|
||||||
|
// Update status bar item with percentage
|
||||||
|
if (progress.packageSize > 0) {
|
||||||
|
let newPercentage = Math.ceil(100 * (progress.downloadedBytes / progress.packageSize));
|
||||||
|
if (newPercentage !== progress.downloadPercentage) {
|
||||||
|
statusView.updateServiceDownloadingProgress(progress.downloadPercentage);
|
||||||
|
progress.downloadPercentage = newPercentage;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update dots after package name in output console
|
||||||
|
let newDots = Math.ceil(progress.downloadPercentage / 5);
|
||||||
|
if (newDots > progress.dots) {
|
||||||
|
logger.append('.'.repeat(newDots - progress.dots));
|
||||||
|
progress.dots = newDots;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleSuccessfulResponse(pkg: IPackage, response: http.IncomingMessage, logger: ILogger, statusView: IStatusView): Promise<void> {
|
||||||
|
return new Promise<void>((resolve, reject) => {
|
||||||
|
let progress: IDownloadProgress = {
|
||||||
|
packageSize: parseInt(response.headers['content-length'], 10),
|
||||||
|
dots: 0,
|
||||||
|
downloadedBytes: 0,
|
||||||
|
downloadPercentage: 0
|
||||||
|
};
|
||||||
|
logger.append(`(${Math.ceil(progress.packageSize / 1024)} KB) `);
|
||||||
|
response.on('data', data => {
|
||||||
|
this.handleDataReceivedEvent(progress, data, logger, statusView);
|
||||||
|
});
|
||||||
|
let tmpFile = fs.createWriteStream(undefined, { fd: pkg.tmpFile.fd });
|
||||||
|
response.on('end', () => {
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
response.on('error', err => {
|
||||||
|
reject(new PackageError(`Response error: ${err.name || 'NONE'}`, pkg, err));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Begin piping data from the response to the package file
|
||||||
|
response.pipe(tmpFile, { end: false });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interface to store the values needed to calculate download percentage
|
||||||
|
*/
|
||||||
|
export interface IDownloadProgress {
|
||||||
|
packageSize: number;
|
||||||
|
downloadedBytes: number;
|
||||||
|
downloadPercentage: number;
|
||||||
|
dots: number;
|
||||||
|
}
|
||||||
46
extensions-modules/src/languageservice/interfaces.ts
Normal file
46
extensions-modules/src/languageservice/interfaces.ts
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
import * as tmp from 'tmp';
|
||||||
|
import { ILogger } from '../models/interfaces';
|
||||||
|
|
||||||
|
export interface IStatusView {
|
||||||
|
installingService(): void;
|
||||||
|
serviceInstalled(): void;
|
||||||
|
serviceInstallationFailed(): void;
|
||||||
|
updateServiceDownloadingProgress(downloadPercentage: number): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IConfig {
|
||||||
|
getDownloadUrl(): string;
|
||||||
|
getInstallDirectory(): string;
|
||||||
|
getExecutableFiles(): string[];
|
||||||
|
getPackageVersion(): string;
|
||||||
|
getExtensionConfig(key: string, defaultValue?: any): any;
|
||||||
|
getWorkspaceConfig(key: string, defaultValue?: any): any;
|
||||||
|
getConfigValue(configKey: string): any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IPackage {
|
||||||
|
url: string;
|
||||||
|
installPath?: string;
|
||||||
|
tmpFile: tmp.SynchronousResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PackageError extends Error {
|
||||||
|
// Do not put PII (personally identifiable information) in the 'message' field as it will be logged to telemetry
|
||||||
|
constructor(public message: string,
|
||||||
|
public pkg: IPackage = undefined,
|
||||||
|
public innerError: any = undefined) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IHttpClient {
|
||||||
|
downloadFile(urlString: string, pkg: IPackage, logger: ILogger, statusView: IStatusView, proxy: string, strictSSL: boolean): Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IDecompressProvider {
|
||||||
|
decompress(pkg: IPackage, logger: ILogger): Promise<void>;
|
||||||
|
}
|
||||||
48
extensions-modules/src/languageservice/proxy.ts
Normal file
48
extensions-modules/src/languageservice/proxy.ts
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* 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 { Url, parse as parseUrl } from 'url';
|
||||||
|
const HttpProxyAgent = require('http-proxy-agent');
|
||||||
|
const HttpsProxyAgent = require('https-proxy-agent');
|
||||||
|
|
||||||
|
function getSystemProxyURL(requestURL: Url): string {
|
||||||
|
if (requestURL.protocol === 'http:') {
|
||||||
|
return process.env.HTTP_PROXY || process.env.http_proxy || undefined;
|
||||||
|
} else if (requestURL.protocol === 'https:') {
|
||||||
|
return process.env.HTTPS_PROXY || process.env.https_proxy || process.env.HTTP_PROXY || process.env.http_proxy || undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the proxy agent using the proxy url in the parameters or the system proxy. Returns null if no proxy found
|
||||||
|
*/
|
||||||
|
export function getProxyAgent(requestURL: Url, proxy?: string, strictSSL?: boolean): any {
|
||||||
|
const proxyURL = proxy || getSystemProxyURL(requestURL);
|
||||||
|
|
||||||
|
if (!proxyURL) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const proxyEndpoint = parseUrl(proxyURL);
|
||||||
|
|
||||||
|
if (!/^https?:$/.test(proxyEndpoint.protocol)) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
strictSSL = strictSSL || true;
|
||||||
|
|
||||||
|
const opts = {
|
||||||
|
host: proxyEndpoint.hostname,
|
||||||
|
port: Number(proxyEndpoint.port),
|
||||||
|
auth: proxyEndpoint.auth,
|
||||||
|
rejectUnauthorized: strictSSL
|
||||||
|
};
|
||||||
|
|
||||||
|
return requestURL.protocol === 'http:' ? new HttpProxyAgent(opts) : new HttpsProxyAgent(opts);
|
||||||
|
}
|
||||||
112
extensions-modules/src/languageservice/server.ts
Normal file
112
extensions-modules/src/languageservice/server.ts
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* 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 * as path from 'path';
|
||||||
|
import { Runtime } from '../models/platform';
|
||||||
|
import ServiceDownloadProvider from './serviceDownloadProvider';
|
||||||
|
import { IConfig, IStatusView } from './interfaces';
|
||||||
|
const fs = require('fs-extra-promise');
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Service Provider class finds the SQL tools service executable file or downloads it if doesn't exist.
|
||||||
|
*/
|
||||||
|
export default class ServerProvider {
|
||||||
|
|
||||||
|
constructor(private _downloadProvider: ServiceDownloadProvider,
|
||||||
|
private _config: IConfig,
|
||||||
|
private _statusView: IStatusView,
|
||||||
|
private _extensionConfigSectionName: string) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public get method for downloadProvider
|
||||||
|
*/
|
||||||
|
public get downloadProvider(): ServiceDownloadProvider {
|
||||||
|
return this._downloadProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a file path, returns the path to the SQL Tools service file.
|
||||||
|
*/
|
||||||
|
public findServerPath(filePath: string, executableFiles: string[] = undefined): Promise<string> {
|
||||||
|
return fs.lstatAsync(filePath).then(stats => {
|
||||||
|
// If a file path was passed, assume its the launch file.
|
||||||
|
if (stats.isFile()) {
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, search the specified folder.
|
||||||
|
let candidate: string;
|
||||||
|
|
||||||
|
if (executableFiles === undefined && this._config !== undefined) {
|
||||||
|
executableFiles = this._config.getExecutableFiles();
|
||||||
|
}
|
||||||
|
if (executableFiles !== undefined) {
|
||||||
|
executableFiles.forEach(element => {
|
||||||
|
let executableFile = path.join(filePath, element);
|
||||||
|
if (candidate === undefined && fs.existsSync(executableFile)) {
|
||||||
|
candidate = executableFile;
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return candidate;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Download the service if doesn't exist and returns the file path.
|
||||||
|
*/
|
||||||
|
public getOrDownloadServer(runtime: Runtime): Promise<string> {
|
||||||
|
// Attempt to find launch file path first from options, and then from the default install location.
|
||||||
|
// If SQL tools service can't be found, download it.
|
||||||
|
|
||||||
|
return new Promise<string>((resolve, reject) => {
|
||||||
|
return this.getServerPath(runtime).then(result => {
|
||||||
|
if (result === undefined) {
|
||||||
|
return this.downloadServerFiles(runtime).then ( downloadResult => {
|
||||||
|
resolve(downloadResult);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return resolve(result);
|
||||||
|
}
|
||||||
|
}).catch(err => {
|
||||||
|
return reject(err);
|
||||||
|
});
|
||||||
|
}).catch(err => {
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the path of the installed service
|
||||||
|
*/
|
||||||
|
public getServerPath(runtime: Runtime): Promise<string> {
|
||||||
|
const installDirectory = this._downloadProvider.getInstallDirectory(runtime, this._extensionConfigSectionName);
|
||||||
|
return this.findServerPath(installDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Downloads the service and returns the path of the installed service
|
||||||
|
*/
|
||||||
|
public downloadServerFiles(runtime: Runtime): Promise<string> {
|
||||||
|
return new Promise<string>((resolve, reject) => {
|
||||||
|
const installDirectory = this._downloadProvider.getInstallDirectory(runtime, this._extensionConfigSectionName);
|
||||||
|
return this._downloadProvider.installService(runtime).then( _ => {
|
||||||
|
return this.findServerPath(installDirectory).then ( result => {
|
||||||
|
return resolve(result);
|
||||||
|
});
|
||||||
|
}).catch(err => {
|
||||||
|
this._statusView.serviceInstallationFailed();
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
125
extensions-modules/src/languageservice/serverStatus.ts
Normal file
125
extensions-modules/src/languageservice/serverStatus.ts
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* 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 { IStatusView } from './interfaces';
|
||||||
|
import vscode = require('vscode');
|
||||||
|
import { IExtensionConstants } from '../models/contracts/contracts';
|
||||||
|
import { Constants } from '../models/constants';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The status class which includes the service initialization result.
|
||||||
|
*/
|
||||||
|
export class ServerInitializationResult {
|
||||||
|
|
||||||
|
public constructor(
|
||||||
|
public installedBeforeInitializing: Boolean = false,
|
||||||
|
public isRunning: Boolean = false,
|
||||||
|
public serverPath: string = undefined
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Clone(): ServerInitializationResult {
|
||||||
|
return new ServerInitializationResult(this.installedBeforeInitializing, this.isRunning, this.serverPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WithRunning(isRunning: Boolean): ServerInitializationResult {
|
||||||
|
return new ServerInitializationResult(this.installedBeforeInitializing, isRunning, this.serverPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The status class shows service installing progress in UI
|
||||||
|
*/
|
||||||
|
export class ServerStatusView implements IStatusView, vscode.Disposable {
|
||||||
|
private _numberOfSecondsBeforeHidingMessage = 5000;
|
||||||
|
private _statusBarItem: vscode.StatusBarItem = undefined;
|
||||||
|
private _progressTimerId: NodeJS.Timer;
|
||||||
|
private _constants: IExtensionConstants;
|
||||||
|
|
||||||
|
constructor(constants: IExtensionConstants) {
|
||||||
|
this._statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right);
|
||||||
|
vscode.window.onDidChangeActiveTextEditor((params) => this.onDidChangeActiveTextEditor(params));
|
||||||
|
vscode.workspace.onDidCloseTextDocument((params) => this.onDidCloseTextDocument(params));
|
||||||
|
this._constants = constants;
|
||||||
|
}
|
||||||
|
|
||||||
|
public installingService(): void {
|
||||||
|
this._statusBarItem.command = undefined;
|
||||||
|
this._statusBarItem.show();
|
||||||
|
|
||||||
|
this.showProgress('$(desktop-download) ' + Constants.serviceInstalling);
|
||||||
|
}
|
||||||
|
|
||||||
|
public updateServiceDownloadingProgress(downloadPercentage: number): void {
|
||||||
|
this._statusBarItem.text = '$(cloud-download) ' + `${Constants.serviceDownloading} ... ${downloadPercentage}%`;
|
||||||
|
this._statusBarItem.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public serviceInstalled(): void {
|
||||||
|
|
||||||
|
this._statusBarItem.command = undefined;
|
||||||
|
this._statusBarItem.text = this._constants.serviceInstalled;
|
||||||
|
this._statusBarItem.show();
|
||||||
|
// Cleat the status bar after 2 seconds
|
||||||
|
setTimeout(() => {
|
||||||
|
this._statusBarItem.hide();
|
||||||
|
}, this._numberOfSecondsBeforeHidingMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public serviceInstallationFailed(): void {
|
||||||
|
this._statusBarItem.command = undefined;
|
||||||
|
this._statusBarItem.text = this._constants.serviceInstallationFailed;
|
||||||
|
this._statusBarItem.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private showProgress(statusText: string): void {
|
||||||
|
let index = 0;
|
||||||
|
let progressTicks = [ '|', '/', '-', '\\'];
|
||||||
|
|
||||||
|
|
||||||
|
this._progressTimerId = setInterval(() => {
|
||||||
|
index++;
|
||||||
|
if (index > 3) {
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
let progressTick = progressTicks[index];
|
||||||
|
if (this._statusBarItem.text !== this._constants.serviceInstalled) {
|
||||||
|
this._statusBarItem.text = statusText + ' ' + progressTick;
|
||||||
|
this._statusBarItem.show();
|
||||||
|
}
|
||||||
|
}, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
dispose(): void {
|
||||||
|
this.destroyStatusBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
private hideLastShownStatusBar(): void {
|
||||||
|
if (typeof this._statusBarItem !== 'undefined') {
|
||||||
|
this._statusBarItem.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private onDidChangeActiveTextEditor(editor: vscode.TextEditor): void {
|
||||||
|
// Hide the most recently shown status bar
|
||||||
|
this.hideLastShownStatusBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
private onDidCloseTextDocument(doc: vscode.TextDocument): void {
|
||||||
|
// Remove the status bar associated with the document
|
||||||
|
this.destroyStatusBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
private destroyStatusBar(): void {
|
||||||
|
if (typeof this._statusBarItem !== 'undefined') {
|
||||||
|
this._statusBarItem.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
503
extensions-modules/src/languageservice/serviceClient.ts
Normal file
503
extensions-modules/src/languageservice/serviceClient.ts
Normal file
@@ -0,0 +1,503 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* 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 { ExtensionContext, workspace, window, OutputChannel, languages } from 'vscode';
|
||||||
|
import { SqlOpsDataClient, LanguageClientOptions } from 'dataprotocol-client';
|
||||||
|
import { CloseAction, ErrorAction, ServerOptions, NotificationHandler, NotificationType, RequestType, TransportKind } from 'vscode-languageclient';
|
||||||
|
|
||||||
|
import { VscodeWrapper } from '../controllers/vscodeWrapper';
|
||||||
|
import { Telemetry } from '../models/telemetry';
|
||||||
|
import { Utils } from '../models/utils';
|
||||||
|
import { VersionRequest, IExtensionConstants } from '../models/contracts/contracts';
|
||||||
|
import { Logger } from '../models/logger';
|
||||||
|
import ServerProvider from './server';
|
||||||
|
import ServiceDownloadProvider from './serviceDownloadProvider';
|
||||||
|
import DecompressProvider from './decompressProvider';
|
||||||
|
import HttpClient from './httpClient';
|
||||||
|
import ExtConfig from '../configurations/extConfig';
|
||||||
|
import { PlatformInformation, Runtime } from '../models/platform';
|
||||||
|
import { ServerInitializationResult, ServerStatusView } from './serverStatus';
|
||||||
|
import StatusView from '../views/statusView';
|
||||||
|
import * as LanguageServiceContracts from '../models/contracts/languageService';
|
||||||
|
import { Constants } from '../models/constants';
|
||||||
|
import ServiceStatus from './serviceStatus';
|
||||||
|
|
||||||
|
const opener = require('opener');
|
||||||
|
const path = require('path');
|
||||||
|
let _channel: OutputChannel = undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @interface IMessage
|
||||||
|
*/
|
||||||
|
interface IMessage {
|
||||||
|
jsonrpc: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle Language Service client errors
|
||||||
|
* @class LanguageClientErrorHandler
|
||||||
|
*/
|
||||||
|
class LanguageClientErrorHandler {
|
||||||
|
|
||||||
|
private vscodeWrapper: VscodeWrapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an instance of LanguageClientErrorHandler.
|
||||||
|
* @memberOf LanguageClientErrorHandler
|
||||||
|
*/
|
||||||
|
constructor(constants: IExtensionConstants) {
|
||||||
|
if (!this.vscodeWrapper) {
|
||||||
|
this.vscodeWrapper = new VscodeWrapper(constants);
|
||||||
|
}
|
||||||
|
Telemetry.getRuntimeId = this.vscodeWrapper.constants.getRuntimeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show an error message prompt with a link to known issues wiki page
|
||||||
|
* @memberOf LanguageClientErrorHandler
|
||||||
|
*/
|
||||||
|
showOnErrorPrompt(): void {
|
||||||
|
let extensionConstants = this.vscodeWrapper.constants;
|
||||||
|
Telemetry.sendTelemetryEvent(extensionConstants.serviceName + 'Crash');
|
||||||
|
this.vscodeWrapper.showErrorMessage(
|
||||||
|
extensionConstants.serviceCrashMessage,
|
||||||
|
Constants.serviceCrashButton).then(action => {
|
||||||
|
if (action && action === Constants.serviceCrashButton) {
|
||||||
|
opener(extensionConstants.serviceCrashLink);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for language service client error
|
||||||
|
*
|
||||||
|
* @param {Error} error
|
||||||
|
* @param {Message} message
|
||||||
|
* @param {number} count
|
||||||
|
* @returns {ErrorAction}
|
||||||
|
*
|
||||||
|
* @memberOf LanguageClientErrorHandler
|
||||||
|
*/
|
||||||
|
error(error: Error, message: IMessage, count: number): ErrorAction {
|
||||||
|
this.showOnErrorPrompt();
|
||||||
|
|
||||||
|
// we don't retry running the service since crashes leave the extension
|
||||||
|
// in a bad, unrecovered state
|
||||||
|
return ErrorAction.Shutdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for language service client closed
|
||||||
|
*
|
||||||
|
* @returns {CloseAction}
|
||||||
|
*
|
||||||
|
* @memberOf LanguageClientErrorHandler
|
||||||
|
*/
|
||||||
|
closed(): CloseAction {
|
||||||
|
this.showOnErrorPrompt();
|
||||||
|
|
||||||
|
// we don't retry running the service since crashes leave the extension
|
||||||
|
// in a bad, unrecovered state
|
||||||
|
return CloseAction.DoNotRestart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The Service Client class handles communication with the VS Code LanguageClient
|
||||||
|
export class SqlToolsServiceClient {
|
||||||
|
// singleton instance
|
||||||
|
private static _instance: SqlToolsServiceClient = undefined;
|
||||||
|
|
||||||
|
private static _constants: IExtensionConstants = undefined;
|
||||||
|
|
||||||
|
public static get constants(): IExtensionConstants {
|
||||||
|
return this._constants;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static set constants(constantsObject: IExtensionConstants) {
|
||||||
|
this._constants = constantsObject;
|
||||||
|
Telemetry.getRuntimeId = this._constants.getRuntimeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static _helper: LanguageServiceContracts.ILanguageClientHelper = undefined;
|
||||||
|
|
||||||
|
public static get helper(): LanguageServiceContracts.ILanguageClientHelper {
|
||||||
|
return this._helper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static set helper(helperObject: LanguageServiceContracts.ILanguageClientHelper) {
|
||||||
|
this._helper = helperObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
// VS Code Language Client
|
||||||
|
private _client: SqlOpsDataClient = undefined;
|
||||||
|
|
||||||
|
// getter method for the Language Client
|
||||||
|
private get client(): SqlOpsDataClient {
|
||||||
|
return this._client;
|
||||||
|
}
|
||||||
|
|
||||||
|
private set client(client: SqlOpsDataClient) {
|
||||||
|
this._client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public installDirectory: string;
|
||||||
|
private _downloadProvider: ServiceDownloadProvider;
|
||||||
|
private _vscodeWrapper: VscodeWrapper;
|
||||||
|
|
||||||
|
private _serviceStatus: ServiceStatus;
|
||||||
|
|
||||||
|
private _languageClientStartTime: number = undefined;
|
||||||
|
private _installationTime: number = undefined;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private _server: ServerProvider,
|
||||||
|
private _logger: Logger,
|
||||||
|
private _statusView: StatusView,
|
||||||
|
private _config: ExtConfig) {
|
||||||
|
this._downloadProvider = _server.downloadProvider;
|
||||||
|
if (!this._vscodeWrapper) {
|
||||||
|
this._vscodeWrapper = new VscodeWrapper(SqlToolsServiceClient.constants);
|
||||||
|
}
|
||||||
|
this._serviceStatus = new ServiceStatus(SqlToolsServiceClient._constants.serviceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// gets or creates the singleton service client instance
|
||||||
|
public static getInstance(path: string): SqlToolsServiceClient {
|
||||||
|
if (this._instance === undefined) {
|
||||||
|
let constants = this._constants;
|
||||||
|
let config = new ExtConfig(constants.extensionConfigSectionName, undefined, path);
|
||||||
|
_channel = window.createOutputChannel(constants.serviceInitializingOutputChannelName);
|
||||||
|
let logger = new Logger(text => _channel.append(text), constants);
|
||||||
|
let serverStatusView = new ServerStatusView(constants);
|
||||||
|
let httpClient = new HttpClient();
|
||||||
|
let decompressProvider = new DecompressProvider();
|
||||||
|
let downloadProvider = new ServiceDownloadProvider(config, logger, serverStatusView, httpClient,
|
||||||
|
decompressProvider, constants, false);
|
||||||
|
let serviceProvider = new ServerProvider(downloadProvider, config, serverStatusView, constants.extensionConfigSectionName);
|
||||||
|
let statusView = new StatusView();
|
||||||
|
this._instance = new SqlToolsServiceClient(serviceProvider, logger, statusView, config);
|
||||||
|
}
|
||||||
|
return this._instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize the Service Client instance by launching
|
||||||
|
// out-of-proc server through the LanguageClient
|
||||||
|
public initialize(context: ExtensionContext): Promise<any> {
|
||||||
|
this._logger.appendLine(SqlToolsServiceClient._constants.serviceInitializing);
|
||||||
|
this._languageClientStartTime = Date.now();
|
||||||
|
return PlatformInformation.getCurrent(SqlToolsServiceClient._constants.getRuntimeId, SqlToolsServiceClient._constants.extensionName).then(platformInfo => {
|
||||||
|
return this.initializeForPlatform(platformInfo, context);
|
||||||
|
}).catch(err => {
|
||||||
|
this._vscodeWrapper.showErrorMessage(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public initializeForPlatform(platformInfo: PlatformInformation, context: ExtensionContext): Promise<ServerInitializationResult> {
|
||||||
|
return new Promise<ServerInitializationResult>((resolve, reject) => {
|
||||||
|
this._logger.appendLine(SqlToolsServiceClient._constants.commandsNotAvailableWhileInstallingTheService);
|
||||||
|
this._logger.appendLine();
|
||||||
|
this._logger.append(`Platform: ${platformInfo.toString()}`);
|
||||||
|
|
||||||
|
if (!platformInfo.isValidRuntime()) {
|
||||||
|
// if it's an unknown Linux distro then try generic Linux x64 and give a warning to the user
|
||||||
|
if (platformInfo.isLinux()) {
|
||||||
|
this._logger.appendLine(Constants.usingDefaultPlatformMessage);
|
||||||
|
platformInfo.runtimeId = Runtime.Linux_64;
|
||||||
|
}
|
||||||
|
|
||||||
|
let ignoreWarning: boolean = this._config.getWorkspaceConfig(Constants.ignorePlatformWarning, false);
|
||||||
|
if (!ignoreWarning) {
|
||||||
|
this._vscodeWrapper.showErrorMessage(
|
||||||
|
Constants.unsupportedPlatformErrorMessage,
|
||||||
|
Constants.neverShowAgain)
|
||||||
|
.then(action => {
|
||||||
|
if (action === Constants.neverShowAgain) {
|
||||||
|
this._config.updateWorkspaceConfig(Constants.ignorePlatformWarning, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Telemetry.sendTelemetryEvent('UnsupportedPlatform', { platform: platformInfo.toString() });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (platformInfo.runtimeId) {
|
||||||
|
this._logger.appendLine(` (${platformInfo.getRuntimeDisplayName()})`);
|
||||||
|
} else {
|
||||||
|
this._logger.appendLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
this._logger.appendLine();
|
||||||
|
|
||||||
|
this._server.getServerPath(platformInfo.runtimeId).then(serverPath => {
|
||||||
|
if (serverPath === undefined) {
|
||||||
|
// Check if the service already installed and if not open the output channel to show the logs
|
||||||
|
if (_channel !== undefined) {
|
||||||
|
_channel.show();
|
||||||
|
}
|
||||||
|
let installationStartTime = Date.now();
|
||||||
|
this._server.downloadServerFiles(platformInfo.runtimeId).then(installedServerPath => {
|
||||||
|
this._installationTime = Date.now() - installationStartTime;
|
||||||
|
this.initializeLanguageClient(installedServerPath, context, platformInfo.runtimeId);
|
||||||
|
resolve(new ServerInitializationResult(true, true, installedServerPath));
|
||||||
|
}).catch(downloadErr => {
|
||||||
|
reject(downloadErr);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.initializeLanguageClient(serverPath, context, platformInfo.runtimeId);
|
||||||
|
resolve(new ServerInitializationResult(false, true, serverPath));
|
||||||
|
}
|
||||||
|
}).catch(err => {
|
||||||
|
Utils.logDebug(SqlToolsServiceClient._constants.serviceLoadingFailed + ' ' + err, SqlToolsServiceClient._constants.extensionConfigSectionName);
|
||||||
|
Utils.showErrorMsg(SqlToolsServiceClient._constants.serviceLoadingFailed, SqlToolsServiceClient._constants.extensionName);
|
||||||
|
Telemetry.sendTelemetryEvent('ServiceInitializingFailed');
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the SQL language configuration
|
||||||
|
*
|
||||||
|
* @memberOf SqlToolsServiceClient
|
||||||
|
*/
|
||||||
|
private initializeLanguageConfiguration(): void {
|
||||||
|
languages.setLanguageConfiguration('sql', {
|
||||||
|
comments: {
|
||||||
|
lineComment: '--',
|
||||||
|
blockComment: ['/*', '*/']
|
||||||
|
},
|
||||||
|
|
||||||
|
brackets: [
|
||||||
|
['{', '}'],
|
||||||
|
['[', ']'],
|
||||||
|
['(', ')']
|
||||||
|
],
|
||||||
|
|
||||||
|
__characterPairSupport: {
|
||||||
|
autoClosingPairs: [
|
||||||
|
{ open: '{', close: '}' },
|
||||||
|
{ open: '[', close: ']' },
|
||||||
|
{ open: '(', close: ')' },
|
||||||
|
{ open: '"', close: '"', notIn: ['string'] },
|
||||||
|
{ open: '\'', close: '\'', notIn: ['string', 'comment'] }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private initializeLanguageClient(serverPath: string, context: ExtensionContext, runtimeId: Runtime): void {
|
||||||
|
if (serverPath === undefined) {
|
||||||
|
Utils.logDebug(SqlToolsServiceClient._constants.invalidServiceFilePath, SqlToolsServiceClient._constants.extensionConfigSectionName);
|
||||||
|
throw new Error(SqlToolsServiceClient._constants.invalidServiceFilePath);
|
||||||
|
} else {
|
||||||
|
let self = this;
|
||||||
|
|
||||||
|
if (SqlToolsServiceClient._constants.languageId === 'sql') {
|
||||||
|
self.initializeLanguageConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use default createServerOptions if one isn't specified
|
||||||
|
let serverOptions: ServerOptions = SqlToolsServiceClient._helper ?
|
||||||
|
SqlToolsServiceClient._helper.createServerOptions(serverPath, runtimeId) : self.createServerOptions(serverPath);
|
||||||
|
this.client = this.createLanguageClient(serverOptions);
|
||||||
|
this.installDirectory = this._downloadProvider.getInstallDirectory(runtimeId, SqlToolsServiceClient._constants.extensionConfigSectionName);
|
||||||
|
|
||||||
|
if (context !== undefined) {
|
||||||
|
// Create the language client and start the client.
|
||||||
|
let disposable = this.client.start();
|
||||||
|
|
||||||
|
// Push the disposable to the context's subscriptions so that the
|
||||||
|
// client can be deactivated on extension deactivation
|
||||||
|
|
||||||
|
context.subscriptions.push(disposable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public createClient(context: ExtensionContext, runtimeId: Runtime, languageClientHelper: LanguageServiceContracts.ILanguageClientHelper, executableFiles: string[]): Promise<SqlOpsDataClient> {
|
||||||
|
return new Promise<SqlOpsDataClient>((resolve, reject) => {
|
||||||
|
let client: SqlOpsDataClient;
|
||||||
|
this._server.findServerPath(this.installDirectory, executableFiles).then(serverPath => {
|
||||||
|
if (serverPath === undefined) {
|
||||||
|
reject(new Error(SqlToolsServiceClient._constants.invalidServiceFilePath));
|
||||||
|
} else {
|
||||||
|
|
||||||
|
let serverOptions: ServerOptions = languageClientHelper ?
|
||||||
|
languageClientHelper.createServerOptions(serverPath, runtimeId) : this.createServerOptions(serverPath);
|
||||||
|
|
||||||
|
// Options to control the language client
|
||||||
|
let clientOptions: LanguageClientOptions = {
|
||||||
|
documentSelector: [SqlToolsServiceClient._constants.languageId],
|
||||||
|
providerId: '',
|
||||||
|
synchronize: {
|
||||||
|
configurationSection: SqlToolsServiceClient._constants.extensionConfigSectionName
|
||||||
|
},
|
||||||
|
errorHandler: new LanguageClientErrorHandler(SqlToolsServiceClient._constants),
|
||||||
|
serverConnectionMetadata: this._config.getConfigValue(Constants.serverConnectionMetadata),
|
||||||
|
outputChannel: {
|
||||||
|
append: () => {
|
||||||
|
},
|
||||||
|
appendLine: () => {
|
||||||
|
},
|
||||||
|
dispose: () => {
|
||||||
|
},
|
||||||
|
clear: () => {
|
||||||
|
},
|
||||||
|
hide: () => {
|
||||||
|
},
|
||||||
|
name: '',
|
||||||
|
show: () => {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this._serviceStatus.showServiceLoading();
|
||||||
|
// cache the client instance for later use
|
||||||
|
client = new SqlOpsDataClient(SqlToolsServiceClient._constants.serviceName, serverOptions, clientOptions);
|
||||||
|
|
||||||
|
if (context !== undefined) {
|
||||||
|
// Create the language client and start the client.
|
||||||
|
let disposable = client.start();
|
||||||
|
|
||||||
|
// Push the disposable to the context's subscriptions so that the
|
||||||
|
// client can be deactivated on extension deactivation
|
||||||
|
|
||||||
|
context.subscriptions.push(disposable);
|
||||||
|
}
|
||||||
|
client.onReady().then(this._serviceStatus.showServiceLoaded);
|
||||||
|
|
||||||
|
resolve(client);
|
||||||
|
}
|
||||||
|
}, error => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private createServerOptions(servicePath): ServerOptions {
|
||||||
|
let serverArgs = [];
|
||||||
|
let serverCommand: string = servicePath;
|
||||||
|
if (servicePath.endsWith('.dll')) {
|
||||||
|
serverArgs = [servicePath];
|
||||||
|
serverCommand = 'dotnet';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable diagnostic logging in the service if it is configured
|
||||||
|
let config = workspace.getConfiguration(SqlToolsServiceClient._constants.extensionConfigSectionName);
|
||||||
|
if (config) {
|
||||||
|
let logDebugInfo = config[Constants.configLogDebugInfo];
|
||||||
|
if (logDebugInfo) {
|
||||||
|
serverArgs.push('--enable-logging');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
serverArgs.push('--log-dir');
|
||||||
|
let logFileLocation = path.join(Utils.getDefaultLogLocation(), SqlToolsServiceClient.constants.extensionName);
|
||||||
|
serverArgs.push(logFileLocation);
|
||||||
|
|
||||||
|
// run the service host using dotnet.exe from the path
|
||||||
|
let serverOptions: ServerOptions = { command: serverCommand, args: serverArgs, transport: TransportKind.stdio };
|
||||||
|
return serverOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private createLanguageClient(serverOptions: ServerOptions): SqlOpsDataClient {
|
||||||
|
// Options to control the language client
|
||||||
|
let clientOptions: LanguageClientOptions = {
|
||||||
|
documentSelector: [SqlToolsServiceClient._constants.languageId],
|
||||||
|
providerId: SqlToolsServiceClient._constants.providerId,
|
||||||
|
synchronize: {
|
||||||
|
configurationSection: SqlToolsServiceClient._constants.extensionConfigSectionName
|
||||||
|
},
|
||||||
|
errorHandler: new LanguageClientErrorHandler(SqlToolsServiceClient._constants),
|
||||||
|
serverConnectionMetadata: this._config.getConfigValue(Constants.serverConnectionMetadata)
|
||||||
|
};
|
||||||
|
|
||||||
|
this._serviceStatus.showServiceLoading();
|
||||||
|
// cache the client instance for later use
|
||||||
|
let client = new SqlOpsDataClient(SqlToolsServiceClient._constants.serviceName, serverOptions, clientOptions);
|
||||||
|
client.onReady().then(() => {
|
||||||
|
this.checkServiceCompatibility();
|
||||||
|
this._serviceStatus.showServiceLoaded();
|
||||||
|
client.onNotification(LanguageServiceContracts.TelemetryNotification.type, this.handleLanguageServiceTelemetryNotification());
|
||||||
|
client.onNotification(LanguageServiceContracts.StatusChangedNotification.type, this.handleLanguageServiceStatusNotification());
|
||||||
|
|
||||||
|
// Report the language client startup time
|
||||||
|
let endTime = Date.now();
|
||||||
|
let installationTime = this._installationTime || 0;
|
||||||
|
let totalTime = endTime - this._languageClientStartTime;
|
||||||
|
let processStartupTime = totalTime - installationTime;
|
||||||
|
Telemetry.sendTelemetryEvent('startup/LanguageClientStarted', {
|
||||||
|
installationTime: String(installationTime),
|
||||||
|
processStartupTime: String(processStartupTime),
|
||||||
|
totalTime: String(totalTime),
|
||||||
|
beginningTimestamp: String(this._languageClientStartTime)
|
||||||
|
});
|
||||||
|
this._languageClientStartTime = undefined;
|
||||||
|
this._installationTime = undefined;
|
||||||
|
});
|
||||||
|
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleLanguageServiceTelemetryNotification(): NotificationHandler<LanguageServiceContracts.TelemetryParams> {
|
||||||
|
return (event: LanguageServiceContracts.TelemetryParams): void => {
|
||||||
|
Telemetry.sendTelemetryEvent(event.params.eventName, event.params.properties, event.params.measures);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public for testing purposes only.
|
||||||
|
*/
|
||||||
|
public handleLanguageServiceStatusNotification(): NotificationHandler<LanguageServiceContracts.StatusChangeParams> {
|
||||||
|
return (event: LanguageServiceContracts.StatusChangeParams): void => {
|
||||||
|
this._statusView.languageServiceStatusChanged(event.ownerUri, event.status);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a request to the service client
|
||||||
|
* @param type The of the request to make
|
||||||
|
* @param params The params to pass with the request
|
||||||
|
* @returns A thenable object for when the request receives a response
|
||||||
|
*/
|
||||||
|
public sendRequest<P, R, E, RO>(type: RequestType<P, R, E, RO>, params?: P, client: SqlOpsDataClient = undefined): Thenable<R> {
|
||||||
|
if (client === undefined) {
|
||||||
|
client = this._client;
|
||||||
|
}
|
||||||
|
if (client !== undefined) {
|
||||||
|
return client.sendRequest(type, params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a handler for a notification type
|
||||||
|
* @param type The notification type to register the handler for
|
||||||
|
* @param handler The handler to register
|
||||||
|
*/
|
||||||
|
public onNotification<P, RO>(type: NotificationType<P, RO>, handler: NotificationHandler<P>, client: SqlOpsDataClient = undefined): void {
|
||||||
|
if (client === undefined) {
|
||||||
|
client = this._client;
|
||||||
|
}
|
||||||
|
if (client !== undefined) {
|
||||||
|
return client.onNotification(type, handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public checkServiceCompatibility(): Promise<boolean> {
|
||||||
|
return new Promise<boolean>((resolve, reject) => {
|
||||||
|
this._client.sendRequest(VersionRequest.type, undefined).then((result) => {
|
||||||
|
Utils.logDebug(SqlToolsServiceClient._constants.extensionName + ' service client version: ' + result, SqlToolsServiceClient._constants.extensionConfigSectionName);
|
||||||
|
|
||||||
|
if (result === undefined || !result.startsWith(SqlToolsServiceClient._constants.serviceCompatibleVersion)) {
|
||||||
|
Utils.showErrorMsg(Constants.serviceNotCompatibleError, SqlToolsServiceClient._constants.extensionName);
|
||||||
|
Utils.logDebug(Constants.serviceNotCompatibleError, SqlToolsServiceClient._constants.extensionConfigSectionName);
|
||||||
|
resolve(false);
|
||||||
|
} else {
|
||||||
|
resolve(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,186 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* 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 { Runtime, getRuntimeDisplayName } from '../models/platform';
|
||||||
|
import * as path from 'path';
|
||||||
|
import { IConfig, IStatusView, IPackage, PackageError, IHttpClient, IDecompressProvider } from './interfaces';
|
||||||
|
import { ILogger } from '../models/interfaces';
|
||||||
|
import { Constants } from '../models/constants';
|
||||||
|
import * as tmp from 'tmp';
|
||||||
|
import { IExtensionConstants } from '../models/contracts/contracts';
|
||||||
|
|
||||||
|
const fse = require('fs-extra');
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Service Download Provider class which handles downloading the SQL Tools service.
|
||||||
|
*/
|
||||||
|
export default class ServiceDownloadProvider {
|
||||||
|
|
||||||
|
constructor(private _config: IConfig,
|
||||||
|
private _logger: ILogger,
|
||||||
|
private _statusView: IStatusView,
|
||||||
|
private _httpClient: IHttpClient,
|
||||||
|
private _decompressProvider: IDecompressProvider,
|
||||||
|
private _extensionConstants: IExtensionConstants,
|
||||||
|
private _fromBuild: boolean) {
|
||||||
|
// Ensure our temp files get cleaned up in case of error.
|
||||||
|
tmp.setGracefulCleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the download url for given platform
|
||||||
|
*/
|
||||||
|
public getDownloadFileName(platform: Runtime): string {
|
||||||
|
let fileNamesJson = this._config.getConfigValue('downloadFileNames');
|
||||||
|
console.info('Platform: ', platform.toString());
|
||||||
|
|
||||||
|
let fileName = fileNamesJson[platform.toString()];
|
||||||
|
console.info('Filename: ', fileName);
|
||||||
|
|
||||||
|
if (fileName === undefined) {
|
||||||
|
if (process.platform === 'linux') {
|
||||||
|
throw new Error('Unsupported linux distribution');
|
||||||
|
} else {
|
||||||
|
throw new Error(`Unsupported platform: ${process.platform}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns SQL tools service installed folder.
|
||||||
|
*/
|
||||||
|
public getInstallDirectory(platform: Runtime, extensionConfigSectionName: string): string {
|
||||||
|
let basePath = this.getInstallDirectoryRoot(platform, extensionConfigSectionName);
|
||||||
|
let versionFromConfig = this._config.getPackageVersion();
|
||||||
|
basePath = basePath.replace('{#version#}', versionFromConfig);
|
||||||
|
basePath = basePath.replace('{#platform#}', getRuntimeDisplayName(platform));
|
||||||
|
if (!fse.existsSync(basePath)) {
|
||||||
|
fse.mkdirsSync(basePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return basePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getLocalUserFolderPath(platform: Runtime): string {
|
||||||
|
if (platform) {
|
||||||
|
switch (platform) {
|
||||||
|
case Runtime.Windows_64:
|
||||||
|
case Runtime.Windows_86:
|
||||||
|
return process.env.APPDATA;
|
||||||
|
case Runtime.OSX:
|
||||||
|
return process.env.HOME + '/Library/Preferences';
|
||||||
|
default:
|
||||||
|
return process.env.HOME;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns SQL tools service installed folder root.
|
||||||
|
*/
|
||||||
|
public getInstallDirectoryRoot(platform: Runtime, extensionConfigSectionName: string): string {
|
||||||
|
let installDirFromConfig : string;
|
||||||
|
installDirFromConfig = this._config.getInstallDirectory();
|
||||||
|
if (!installDirFromConfig || installDirFromConfig === '') {
|
||||||
|
let rootFolderName: string = '.sqlops';
|
||||||
|
if (platform === Runtime.Windows_64 || platform === Runtime.Windows_86) {
|
||||||
|
rootFolderName = 'sqlops';
|
||||||
|
}
|
||||||
|
installDirFromConfig = path.join(this.getLocalUserFolderPath(platform), `/${rootFolderName}/${this._extensionConstants.installFolderName}/{#version#}/{#platform#}`);
|
||||||
|
}
|
||||||
|
let basePath: string;
|
||||||
|
if (path.isAbsolute(installDirFromConfig)) {
|
||||||
|
basePath = installDirFromConfig;
|
||||||
|
} else if (this._fromBuild) {
|
||||||
|
basePath = path.join(__dirname, '../../../extensions/' + extensionConfigSectionName + '/' + installDirFromConfig);
|
||||||
|
} else {
|
||||||
|
// The path from config is relative to the out folder
|
||||||
|
basePath = path.join(__dirname, '../../../../' + extensionConfigSectionName + '/' + installDirFromConfig);
|
||||||
|
}
|
||||||
|
return basePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getGetDownloadUrl(fileName: string): string {
|
||||||
|
let baseDownloadUrl = this._config.getDownloadUrl();
|
||||||
|
let version = this._config.getPackageVersion();
|
||||||
|
baseDownloadUrl = baseDownloadUrl.replace('{#version#}', version);
|
||||||
|
baseDownloadUrl = baseDownloadUrl.replace('{#fileName#}', fileName);
|
||||||
|
return baseDownloadUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Downloads the service and decompress it in the install folder.
|
||||||
|
*/
|
||||||
|
public installService(platform: Runtime): Promise<boolean> {
|
||||||
|
const proxy = <string>this._config.getWorkspaceConfig('http.proxy');
|
||||||
|
const strictSSL = this._config.getWorkspaceConfig('http.proxyStrictSSL', true);
|
||||||
|
|
||||||
|
return new Promise<boolean>((resolve, reject) => {
|
||||||
|
const fileName = this.getDownloadFileName(platform);
|
||||||
|
const installDirectory = this.getInstallDirectory(platform, this._extensionConstants.extensionConfigSectionName);
|
||||||
|
|
||||||
|
this._logger.appendLine(`${this._extensionConstants.serviceInstallingTo} ${installDirectory}.`);
|
||||||
|
const urlString = this.getGetDownloadUrl(fileName);
|
||||||
|
|
||||||
|
this._logger.appendLine(`${Constants.serviceDownloading} ${urlString}`);
|
||||||
|
let pkg: IPackage = {
|
||||||
|
installPath: installDirectory,
|
||||||
|
url: urlString,
|
||||||
|
tmpFile: undefined
|
||||||
|
};
|
||||||
|
this.createTempFile(pkg).then(tmpResult => {
|
||||||
|
pkg.tmpFile = tmpResult;
|
||||||
|
|
||||||
|
this._httpClient.downloadFile(pkg.url, pkg, this._logger, this._statusView, proxy, strictSSL).then(_ => {
|
||||||
|
|
||||||
|
this._logger.logDebug(`Downloaded to ${pkg.tmpFile.name}...`);
|
||||||
|
this._logger.appendLine(' Done!');
|
||||||
|
this.install(pkg).then(result => {
|
||||||
|
resolve(true);
|
||||||
|
}).catch(installError => {
|
||||||
|
reject(installError);
|
||||||
|
});
|
||||||
|
}).catch(downloadError => {
|
||||||
|
this._logger.appendLine(`[ERROR] ${downloadError}`);
|
||||||
|
reject(downloadError);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private createTempFile(pkg: IPackage): Promise<tmp.SynchronousResult> {
|
||||||
|
return new Promise<tmp.SynchronousResult>((resolve, reject) => {
|
||||||
|
tmp.file({ prefix: 'package-' }, (err, path, fd, cleanupCallback) => {
|
||||||
|
if (err) {
|
||||||
|
return reject(new PackageError('Error from tmp.file', pkg, err));
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(<tmp.SynchronousResult>{ name: path, fd: fd, removeCallback: cleanupCallback });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private install(pkg: IPackage): Promise<void> {
|
||||||
|
this._logger.appendLine('Installing ...');
|
||||||
|
this._statusView.installingService();
|
||||||
|
|
||||||
|
return new Promise<void>((resolve, reject) => {
|
||||||
|
this._decompressProvider.decompress(pkg, this._logger).then(_ => {
|
||||||
|
this._statusView.serviceInstalled();
|
||||||
|
resolve();
|
||||||
|
}).catch(err => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
130
extensions-modules/src/languageservice/serviceInstallerUtil.ts
Normal file
130
extensions-modules/src/languageservice/serviceInstallerUtil.ts
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { Runtime, PlatformInformation } from '../models/platform';
|
||||||
|
import Config from '../configurations/config';
|
||||||
|
import ServiceDownloadProvider from './serviceDownloadProvider';
|
||||||
|
import DecompressProvider from './decompressProvider';
|
||||||
|
import HttpClient from './httpClient';
|
||||||
|
import ServerProvider from './server';
|
||||||
|
import { IStatusView } from './interfaces';
|
||||||
|
import { ILogger } from '../models/interfaces';
|
||||||
|
import { IExtensionConstants } from '../models/contracts/contracts';
|
||||||
|
|
||||||
|
class StubStatusView implements IStatusView {
|
||||||
|
installingService(): void {
|
||||||
|
console.log('...');
|
||||||
|
}
|
||||||
|
serviceInstalled(): void {
|
||||||
|
console.log('Service installed');
|
||||||
|
}
|
||||||
|
serviceInstallationFailed(): void {
|
||||||
|
console.log('Service installation failed');
|
||||||
|
}
|
||||||
|
updateServiceDownloadingProgress(downloadPercentage: number): void {
|
||||||
|
if (downloadPercentage === 100) {
|
||||||
|
process.stdout.write('100%');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class StubLogger implements ILogger {
|
||||||
|
logDebug(message: string): void {
|
||||||
|
console.log(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
increaseIndent(): void {
|
||||||
|
console.log('increaseIndent');
|
||||||
|
}
|
||||||
|
|
||||||
|
decreaseIndent(): void {
|
||||||
|
console.log('decreaseIndent');
|
||||||
|
}
|
||||||
|
|
||||||
|
append(message?: string): void {
|
||||||
|
process.stdout.write(message);
|
||||||
|
}
|
||||||
|
appendLine(message?: string): void {
|
||||||
|
console.log(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ServiceInstaller {
|
||||||
|
private _config = undefined;
|
||||||
|
private _logger = new StubLogger();
|
||||||
|
private _statusView = new StubStatusView();
|
||||||
|
private _httpClient = new HttpClient();
|
||||||
|
private _decompressProvider = new DecompressProvider();
|
||||||
|
private _downloadProvider = undefined;
|
||||||
|
private _serverProvider = undefined;
|
||||||
|
private _extensionConstants = undefined;
|
||||||
|
|
||||||
|
constructor(extensionConstants: IExtensionConstants, path?: string) {
|
||||||
|
this._extensionConstants = extensionConstants;
|
||||||
|
this._config = new Config(extensionConstants.extensionConfigSectionName, path, true);
|
||||||
|
this._downloadProvider = new ServiceDownloadProvider(this._config, this._logger, this._statusView, this._httpClient, this._decompressProvider, extensionConstants, true);
|
||||||
|
this._serverProvider = new ServerProvider(this._downloadProvider, this._config, this._statusView, extensionConstants.extensionConfigSectionName);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Installs the service for the given platform if it's not already installed.
|
||||||
|
*/
|
||||||
|
public installService(): Promise<String> {
|
||||||
|
return PlatformInformation.getCurrent(this._extensionConstants.getRuntimeId, this._extensionConstants.extensionName).then(platformInfo => {
|
||||||
|
if (platformInfo.isValidRuntime()) {
|
||||||
|
return this._serverProvider.getOrDownloadServer(platformInfo.runtimeId);
|
||||||
|
} else {
|
||||||
|
throw new Error('unsupported runtime');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the install folder path for given platform.
|
||||||
|
*/
|
||||||
|
public getServiceInstallDirectory(runtime: Runtime): Promise<string> {
|
||||||
|
return new Promise<string>((resolve, reject) => {
|
||||||
|
if (runtime === undefined) {
|
||||||
|
PlatformInformation.getCurrent(this._extensionConstants.getRuntimeId, this._extensionConstants.extensionName).then(platformInfo => {
|
||||||
|
if (platformInfo.isValidRuntime()) {
|
||||||
|
resolve(this._downloadProvider.getInstallDirectory(platformInfo.runtimeId));
|
||||||
|
} else {
|
||||||
|
reject('unsupported runtime');
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
resolve(this._downloadProvider.getInstallDirectory(runtime));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the path to the root folder of service install location.
|
||||||
|
*/
|
||||||
|
public getServiceInstallDirectoryRoot(runtime: Runtime): Promise<string> {
|
||||||
|
return new Promise<string>((resolve, reject) => {
|
||||||
|
if (runtime === undefined) {
|
||||||
|
PlatformInformation.getCurrent(this._extensionConstants.getRuntimeId, this._extensionConstants.extensionName).then(platformInfo => {
|
||||||
|
if (platformInfo.isValidRuntime()) {
|
||||||
|
let directoryPath: string = this._downloadProvider.getInstallDirectoryRoot(platformInfo, this._extensionConstants.extensionName);
|
||||||
|
directoryPath = directoryPath.replace('\\{#version#}', '');
|
||||||
|
directoryPath = directoryPath.replace('\\{#platform#}', '');
|
||||||
|
directoryPath = directoryPath.replace('/{#platform#}', '');
|
||||||
|
directoryPath = directoryPath.replace('/{#version#}', '');
|
||||||
|
resolve(directoryPath);
|
||||||
|
} else {
|
||||||
|
reject('unsupported runtime');
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
resolve(this._downloadProvider.getInstallDirectory(runtime));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
80
extensions-modules/src/languageservice/serviceStatus.ts
Normal file
80
extensions-modules/src/languageservice/serviceStatus.ts
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* 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 vscode = require('vscode');
|
||||||
|
|
||||||
|
export default class ServiceStatus implements vscode.Disposable {
|
||||||
|
|
||||||
|
private _progressTimerId: NodeJS.Timer;
|
||||||
|
|
||||||
|
private _statusBarItem: vscode.StatusBarItem = undefined;
|
||||||
|
|
||||||
|
private durationStatusInMs: number = 1500;
|
||||||
|
|
||||||
|
// These need localization
|
||||||
|
private _serviceStartingMessage: string = `Starting ${this._serviceName}`;
|
||||||
|
private _serviceStartedMessage: string = `${this._serviceName} started`;
|
||||||
|
|
||||||
|
constructor(private _serviceName: string) {
|
||||||
|
this._statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
|
||||||
|
}
|
||||||
|
|
||||||
|
public showServiceLoading(): Promise<void> {
|
||||||
|
return this === undefined ?
|
||||||
|
Promise.resolve() :
|
||||||
|
Promise.resolve(this.updateStatusView(this._serviceStartingMessage, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
public showServiceLoaded(): Promise<void> {
|
||||||
|
return this === undefined ?
|
||||||
|
Promise.resolve() :
|
||||||
|
Promise.resolve(this.updateStatusView(this._serviceStartedMessage, false, this.durationStatusInMs));
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: This can be merged with the serverStatus code
|
||||||
|
private showProgress(statusText: string): void {
|
||||||
|
let index: number = 0;
|
||||||
|
let progressTicks: string[] = ['.', '..', '...', '....'];
|
||||||
|
|
||||||
|
this._progressTimerId = setInterval(() => {
|
||||||
|
index = (index + 1) % progressTicks.length;
|
||||||
|
let progressTick = progressTicks[index];
|
||||||
|
if (this._statusBarItem.text !== this._serviceStartedMessage) {
|
||||||
|
this._statusBarItem.text = statusText + ' ' + progressTick;
|
||||||
|
this._statusBarItem.show();
|
||||||
|
}
|
||||||
|
}, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateStatusView(message: string, showAsProgress: boolean = false, disposeAfter: number = -1): Promise<void> {
|
||||||
|
return new Promise<void>((resolve, reject) => {
|
||||||
|
if (showAsProgress) {
|
||||||
|
this.showProgress(message);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this._statusBarItem.text = message;
|
||||||
|
this._statusBarItem.show();
|
||||||
|
if (this._progressTimerId !== undefined) {
|
||||||
|
clearInterval(this._progressTimerId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (disposeAfter !== -1) {
|
||||||
|
setInterval(() => {
|
||||||
|
this._statusBarItem.hide();
|
||||||
|
}, disposeAfter);
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
dispose(): void {
|
||||||
|
if (this._progressTimerId !== undefined) {
|
||||||
|
clearInterval(this._progressTimerId);
|
||||||
|
}
|
||||||
|
this._statusBarItem.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
15
extensions-modules/src/main.ts
Normal file
15
extensions-modules/src/main.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
export * from './controllers/vscodeWrapper';
|
||||||
|
export * from './models/constants';
|
||||||
|
export * from './models/utils';
|
||||||
|
|
||||||
|
export { SqlToolsServiceClient } from './languageservice/serviceClient';
|
||||||
|
export { IExtensionConstants } from './models/contracts/contracts';
|
||||||
|
export { ILanguageClientHelper } from './models/contracts/languageService';
|
||||||
|
export { Runtime, PlatformInformation } from './models/platform';
|
||||||
|
export { Telemetry } from './models/telemetry';
|
||||||
|
export { LinuxDistribution } from './models/platform';
|
||||||
|
export { ServiceInstaller } from './languageservice/serviceInstallerUtil';
|
||||||
25
extensions-modules/src/models/constants.ts
Normal file
25
extensions-modules/src/models/constants.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
export namespace Constants {
|
||||||
|
//constants
|
||||||
|
export const configLogDebugInfo: string = 'logDebugInfo';
|
||||||
|
export const serviceNotCompatibleError: string = 'Client is not compatible with the service layer';
|
||||||
|
export const serviceDownloading: string = 'Downloading';
|
||||||
|
export const serviceInstalling: string = 'Installing';
|
||||||
|
export const unsupportedPlatformErrorMessage: string = 'This platform is unsupported and application services may not function correctly';
|
||||||
|
export const serviceConfigKey = 'service';
|
||||||
|
export const executableFilesConfigKey = 'executableFiles';
|
||||||
|
export const versionConfigKey = 'version';
|
||||||
|
export const downloadUrlConfigKey = 'downloadUrl';
|
||||||
|
export const installDirConfigKey = 'installDir';
|
||||||
|
export const serviceCrashButton = 'View Known Issues';
|
||||||
|
export const neverShowAgain = 'Do not show again';
|
||||||
|
export const ignorePlatformWarning = 'ignorePlatformWarning';
|
||||||
|
export const usingDefaultPlatformMessage = 'Unknown platform detected, defaulting to Linux_x64 platform';
|
||||||
|
export const serverConnectionMetadata = 'serverConnectionMetadata';
|
||||||
|
export const extensionDeactivated: string = 'de-activated.';
|
||||||
|
export const extensionActivated: string = 'activated.';
|
||||||
|
}
|
||||||
50
extensions-modules/src/models/contracts/contracts.ts
Normal file
50
extensions-modules/src/models/contracts/contracts.ts
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* 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 { RequestType } from 'vscode-languageclient';
|
||||||
|
import { Runtime, LinuxDistribution } from '../platform';
|
||||||
|
|
||||||
|
// --------------------------------- < Version Request > -------------------------------------------------
|
||||||
|
|
||||||
|
// Version request message callback declaration
|
||||||
|
export namespace VersionRequest {
|
||||||
|
export const type = new RequestType<void, VersionResult, void, void>('version');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version response format
|
||||||
|
export type VersionResult = string;
|
||||||
|
|
||||||
|
// ------------------------------- </ Version Request > --------------------------------------------------
|
||||||
|
|
||||||
|
// Constants interface for each extension
|
||||||
|
export interface IExtensionConstants {
|
||||||
|
// TODO: Fill in interface
|
||||||
|
|
||||||
|
// Definitely dependent on the extension
|
||||||
|
extensionName: string;
|
||||||
|
invalidServiceFilePath: string;
|
||||||
|
serviceName: string;
|
||||||
|
extensionConfigSectionName: string;
|
||||||
|
serviceCompatibleVersion: string;
|
||||||
|
outputChannelName: string;
|
||||||
|
languageId: string;
|
||||||
|
serviceInstallingTo: string;
|
||||||
|
serviceInitializing: string;
|
||||||
|
serviceInstalled: string;
|
||||||
|
serviceLoadingFailed: string;
|
||||||
|
serviceInstallationFailed: string;
|
||||||
|
serviceInitializingOutputChannelName: string;
|
||||||
|
commandsNotAvailableWhileInstallingTheService: string;
|
||||||
|
providerId: string;
|
||||||
|
serviceCrashMessage: string;
|
||||||
|
serviceCrashLink: string;
|
||||||
|
installFolderName: string;
|
||||||
|
telemetryExtensionName: string;
|
||||||
|
|
||||||
|
getRuntimeId(platform: string, architecture: string, distribution: LinuxDistribution): Runtime;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
59
extensions-modules/src/models/contracts/languageService.ts
Normal file
59
extensions-modules/src/models/contracts/languageService.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
import { NotificationType, ServerOptions } from 'vscode-languageclient';
|
||||||
|
import { ITelemetryEventProperties, ITelemetryEventMeasures } from '../telemetry';
|
||||||
|
import { Runtime } from '../platform';
|
||||||
|
|
||||||
|
// ------------------------------- < Telemetry Sent Event > ------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event sent when the language service send a telemetry event
|
||||||
|
*/
|
||||||
|
export namespace TelemetryNotification {
|
||||||
|
export const type = new NotificationType<TelemetryParams, void>('telemetry/sqlevent');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update event parameters
|
||||||
|
*/
|
||||||
|
export class TelemetryParams {
|
||||||
|
public params: {
|
||||||
|
eventName: string;
|
||||||
|
properties: ITelemetryEventProperties;
|
||||||
|
measures: ITelemetryEventMeasures;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- </ Telemetry Sent Event > ----------------------------------
|
||||||
|
|
||||||
|
// ------------------------------- < Status Event > ------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event sent when the language service send a status change event
|
||||||
|
*/
|
||||||
|
export namespace StatusChangedNotification {
|
||||||
|
export const type = new NotificationType<StatusChangeParams, void>('textDocument/statusChanged');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update event parameters
|
||||||
|
*/
|
||||||
|
export class StatusChangeParams {
|
||||||
|
/**
|
||||||
|
* URI identifying the text document
|
||||||
|
*/
|
||||||
|
public ownerUri: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The new status of the document
|
||||||
|
*/
|
||||||
|
public status: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------- </ Status Sent Event > ----------------------------------
|
||||||
|
|
||||||
|
export interface ILanguageClientHelper {
|
||||||
|
createServerOptions(servicePath: string, runtimeId?: Runtime): ServerOptions;
|
||||||
|
}
|
||||||
@@ -4,5 +4,10 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
export const serviceName = 'AzureResourceProvider';
|
export interface ILogger {
|
||||||
export const providerId = 'azureresourceProvider';
|
logDebug(message: string): void;
|
||||||
|
increaseIndent(): void;
|
||||||
|
decreaseIndent(): void;
|
||||||
|
append(message?: string): void;
|
||||||
|
appendLine(message?: string): void;
|
||||||
|
}
|
||||||
69
extensions-modules/src/models/logger.ts
Normal file
69
extensions-modules/src/models/logger.ts
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
import * as os from 'os';
|
||||||
|
import { ILogger } from './interfaces';
|
||||||
|
import { Utils } from './utils';
|
||||||
|
import { IExtensionConstants } from './contracts/contracts';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Logger class handles logging messages using the Util functions.
|
||||||
|
*/
|
||||||
|
export class Logger implements ILogger {
|
||||||
|
private _writer: (message: string) => void;
|
||||||
|
private _prefix: string;
|
||||||
|
private _extensionConstants: IExtensionConstants;
|
||||||
|
|
||||||
|
private _indentLevel: number = 0;
|
||||||
|
private _indentSize: number = 4;
|
||||||
|
private _atLineStart: boolean = false;
|
||||||
|
|
||||||
|
constructor(writer: (message: string) => void, extensionConstants: IExtensionConstants, prefix?: string) {
|
||||||
|
this._writer = writer;
|
||||||
|
this._prefix = prefix;
|
||||||
|
this._extensionConstants = extensionConstants;
|
||||||
|
}
|
||||||
|
|
||||||
|
public logDebug(message: string): void {
|
||||||
|
Utils.logDebug(message, this._extensionConstants.extensionConfigSectionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _appendCore(message: string): void {
|
||||||
|
if (this._atLineStart) {
|
||||||
|
if (this._indentLevel > 0) {
|
||||||
|
const indent = ' '.repeat(this._indentLevel * this._indentSize);
|
||||||
|
this._writer(indent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._prefix) {
|
||||||
|
this._writer(`[${this._prefix}] `);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._atLineStart = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._writer(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public increaseIndent(): void {
|
||||||
|
this._indentLevel += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public decreaseIndent(): void {
|
||||||
|
if (this._indentLevel > 0) {
|
||||||
|
this._indentLevel -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public append(message?: string): void {
|
||||||
|
message = message || '';
|
||||||
|
this._appendCore(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public appendLine(message?: string): void {
|
||||||
|
message = message || '';
|
||||||
|
this._appendCore(message + os.EOL);
|
||||||
|
this._atLineStart = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
314
extensions-modules/src/models/platform.ts
Normal file
314
extensions-modules/src/models/platform.ts
Normal file
@@ -0,0 +1,314 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* 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 * as child_process from 'child_process';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as os from 'os';
|
||||||
|
|
||||||
|
const unknown = 'unknown';
|
||||||
|
|
||||||
|
export enum Runtime {
|
||||||
|
UnknownRuntime = <any>'Unknown',
|
||||||
|
UnknownVersion = <any>'Unknown',
|
||||||
|
Windows_86 = <any>'Windows_86',
|
||||||
|
Windows_64 = <any>'Windows_64',
|
||||||
|
OSX = <any>'OSX',
|
||||||
|
CentOS_7 = <any>'CentOS_7',
|
||||||
|
Debian_8 = <any>'Debian_8',
|
||||||
|
Fedora_23 = <any>'Fedora_23',
|
||||||
|
OpenSUSE_13_2 = <any>'OpenSUSE_13_2',
|
||||||
|
SLES_12_2 = <any>'SLES_12_2',
|
||||||
|
RHEL_7 = <any>'RHEL_7',
|
||||||
|
Ubuntu_14 = <any>'Ubuntu_14',
|
||||||
|
Ubuntu_16 = <any>'Ubuntu_16',
|
||||||
|
Linux_64 = <any>'Linux_64',
|
||||||
|
Linux_86 = <any>'Linux-86'
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getRuntimeDisplayName(runtime: Runtime): string {
|
||||||
|
switch (runtime) {
|
||||||
|
case Runtime.Windows_64:
|
||||||
|
return 'Windows';
|
||||||
|
case Runtime.Windows_86:
|
||||||
|
return 'Windows';
|
||||||
|
case Runtime.OSX:
|
||||||
|
return 'OSX';
|
||||||
|
case Runtime.CentOS_7:
|
||||||
|
return 'Linux';
|
||||||
|
case Runtime.Debian_8:
|
||||||
|
return 'Linux';
|
||||||
|
case Runtime.Fedora_23:
|
||||||
|
return 'Linux';
|
||||||
|
case Runtime.OpenSUSE_13_2:
|
||||||
|
return 'Linux';
|
||||||
|
case Runtime.SLES_12_2:
|
||||||
|
return 'Linux';
|
||||||
|
case Runtime.RHEL_7:
|
||||||
|
return 'Linux';
|
||||||
|
case Runtime.Ubuntu_14:
|
||||||
|
return 'Linux';
|
||||||
|
case Runtime.Ubuntu_16:
|
||||||
|
return 'Linux';
|
||||||
|
case Runtime.Linux_64:
|
||||||
|
return 'Linux';
|
||||||
|
case Runtime.Linux_86:
|
||||||
|
return 'Linux';
|
||||||
|
default:
|
||||||
|
return 'Unknown';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class PlatformInformation {
|
||||||
|
public runtimeId: Runtime;
|
||||||
|
|
||||||
|
public constructor(
|
||||||
|
public platform: string,
|
||||||
|
public architecture: string,
|
||||||
|
public distribution: LinuxDistribution = undefined,
|
||||||
|
public getRuntimeId: (platform: string, architecture: string, distribution: LinuxDistribution) => Runtime) {
|
||||||
|
try {
|
||||||
|
this.runtimeId = this.getRuntimeId(platform, architecture, distribution);
|
||||||
|
} catch (err) {
|
||||||
|
this.runtimeId = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public isWindows(): boolean {
|
||||||
|
return this.platform === 'win32';
|
||||||
|
}
|
||||||
|
|
||||||
|
public isMacOS(): boolean {
|
||||||
|
return this.platform === 'darwin';
|
||||||
|
}
|
||||||
|
|
||||||
|
public isLinux(): boolean {
|
||||||
|
return this.platform === 'linux';
|
||||||
|
}
|
||||||
|
|
||||||
|
public isValidRuntime(): boolean {
|
||||||
|
return this.runtimeId !== undefined && this.runtimeId !== Runtime.UnknownRuntime && this.runtimeId !== Runtime.UnknownVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getRuntimeDisplayName(): string {
|
||||||
|
return getRuntimeDisplayName(this.runtimeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public toString(): string {
|
||||||
|
let result = this.platform;
|
||||||
|
|
||||||
|
if (this.architecture) {
|
||||||
|
if (result) {
|
||||||
|
result += ', ';
|
||||||
|
}
|
||||||
|
|
||||||
|
result += this.architecture;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.distribution) {
|
||||||
|
if (result) {
|
||||||
|
result += ', ';
|
||||||
|
}
|
||||||
|
|
||||||
|
result += this.distribution.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getCurrent(getRuntimeId: (platform: string, architecture: string, distribution: LinuxDistribution) => Runtime,
|
||||||
|
extensionName: string): Promise<any> {
|
||||||
|
let platform = os.platform();
|
||||||
|
let architecturePromise: Promise<string>;
|
||||||
|
let distributionPromise: Promise<LinuxDistribution>;
|
||||||
|
|
||||||
|
switch (platform) {
|
||||||
|
case 'win32':
|
||||||
|
architecturePromise = PlatformInformation.getWindowsArchitecture();
|
||||||
|
distributionPromise = Promise.resolve(undefined);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'darwin':
|
||||||
|
let osVersion = os.release();
|
||||||
|
if (parseFloat(osVersion) < 16.0 && extensionName === 'mssql') {
|
||||||
|
return Promise.reject('The current version of macOS is not supported. Only macOS Sierra and above (>= 10.12) are supported.');
|
||||||
|
}
|
||||||
|
architecturePromise = PlatformInformation.getUnixArchitecture();
|
||||||
|
distributionPromise = Promise.resolve(undefined);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'linux':
|
||||||
|
architecturePromise = PlatformInformation.getUnixArchitecture();
|
||||||
|
distributionPromise = LinuxDistribution.getCurrent();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return Promise.reject(`Unsupported platform: ${platform}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return architecturePromise.then(arch => {
|
||||||
|
return distributionPromise.then(distro => {
|
||||||
|
return new PlatformInformation(platform, arch, distro, getRuntimeId);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static getWindowsArchitecture(): Promise<string> {
|
||||||
|
return new Promise<string>((resolve, reject) => {
|
||||||
|
// try to get the architecture from WMIC
|
||||||
|
PlatformInformation.getWindowsArchitectureWmic().then(architecture => {
|
||||||
|
if (architecture && architecture !== unknown) {
|
||||||
|
resolve(architecture);
|
||||||
|
} else {
|
||||||
|
// sometimes WMIC isn't available on the path so then try to parse the envvar
|
||||||
|
PlatformInformation.getWindowsArchitectureEnv().then(architecture => {
|
||||||
|
resolve(architecture);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static getWindowsArchitectureWmic(): Promise<string> {
|
||||||
|
return this.execChildProcess('wmic os get osarchitecture')
|
||||||
|
.then(architecture => {
|
||||||
|
if (architecture) {
|
||||||
|
let archArray: string[] = architecture.split(os.EOL);
|
||||||
|
if (archArray.length >= 2) {
|
||||||
|
let arch = archArray[1].trim();
|
||||||
|
|
||||||
|
// Note: This string can be localized. So, we'll just check to see if it contains 32 or 64.
|
||||||
|
if (arch.indexOf('64') >= 0) {
|
||||||
|
return 'x86_64';
|
||||||
|
} else if (arch.indexOf('32') >= 0) {
|
||||||
|
return 'x86';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return unknown;
|
||||||
|
}).catch((error) => {
|
||||||
|
return unknown;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static getWindowsArchitectureEnv(): Promise<string> {
|
||||||
|
return new Promise<string>((resolve, reject) => {
|
||||||
|
if (process.env.PROCESSOR_ARCHITECTURE === 'x86' && process.env.PROCESSOR_ARCHITEW6432 === undefined) {
|
||||||
|
resolve('x86');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
resolve('x86_64');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static getUnixArchitecture(): Promise<string> {
|
||||||
|
return this.execChildProcess('uname -m')
|
||||||
|
.then(architecture => {
|
||||||
|
if (architecture) {
|
||||||
|
return architecture.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static execChildProcess(process: string): Promise<string> {
|
||||||
|
return new Promise<string>((resolve, reject) => {
|
||||||
|
child_process.exec(process, { maxBuffer: 500 * 1024 }, (error: Error, stdout: string, stderr: string) => {
|
||||||
|
if (error) {
|
||||||
|
reject(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stderr && stderr.length > 0) {
|
||||||
|
reject(new Error(stderr));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(stdout);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* There is no standard way on Linux to find the distribution name and version.
|
||||||
|
* Recently, systemd has pushed to standardize the os-release file. This has
|
||||||
|
* seen adoption in "recent" versions of all major distributions.
|
||||||
|
* https://www.freedesktop.org/software/systemd/man/os-release.html
|
||||||
|
*/
|
||||||
|
export class LinuxDistribution {
|
||||||
|
public constructor(
|
||||||
|
public name: string,
|
||||||
|
public version: string,
|
||||||
|
public idLike?: string[]) { }
|
||||||
|
|
||||||
|
public static getCurrent(): Promise<LinuxDistribution> {
|
||||||
|
// Try /etc/os-release and fallback to /usr/lib/os-release per the synopsis
|
||||||
|
// at https://www.freedesktop.org/software/systemd/man/os-release.html.
|
||||||
|
return LinuxDistribution.fromFilePath('/etc/os-release')
|
||||||
|
.catch(() => LinuxDistribution.fromFilePath('/usr/lib/os-release'))
|
||||||
|
.catch(() => Promise.resolve(new LinuxDistribution(unknown, unknown)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public toString(): string {
|
||||||
|
return `name=${this.name}, version=${this.version}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static fromFilePath(filePath: string): Promise<LinuxDistribution> {
|
||||||
|
return new Promise<LinuxDistribution>((resolve, reject) => {
|
||||||
|
fs.readFile(filePath, 'utf8', (error, data) => {
|
||||||
|
if (error) {
|
||||||
|
reject(error);
|
||||||
|
} else {
|
||||||
|
resolve(LinuxDistribution.fromReleaseInfo(data));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static fromReleaseInfo(releaseInfo: string, eol: string = os.EOL): LinuxDistribution {
|
||||||
|
let name = unknown;
|
||||||
|
let version = unknown;
|
||||||
|
let idLike: string[] = undefined;
|
||||||
|
|
||||||
|
const lines = releaseInfo.split(eol);
|
||||||
|
for (let line of lines) {
|
||||||
|
line = line.trim();
|
||||||
|
|
||||||
|
let equalsIndex = line.indexOf('=');
|
||||||
|
if (equalsIndex >= 0) {
|
||||||
|
let key = line.substring(0, equalsIndex);
|
||||||
|
let value = line.substring(equalsIndex + 1);
|
||||||
|
|
||||||
|
// Strip quotes if necessary
|
||||||
|
if (value.length > 1 && value.startsWith('"') && value.endsWith('"')) {
|
||||||
|
value = value.substring(1, value.length - 1);
|
||||||
|
} else if (value.length > 1 && value.startsWith('\'') && value.endsWith('\'')) {
|
||||||
|
value = value.substring(1, value.length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key === 'ID') {
|
||||||
|
name = value;
|
||||||
|
} else if (key === 'VERSION_ID') {
|
||||||
|
version = value;
|
||||||
|
} else if (key === 'ID_LIKE') {
|
||||||
|
idLike = value.split(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name !== unknown && version !== unknown && idLike !== undefined) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new LinuxDistribution(name, version, idLike);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -4,16 +4,11 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
import * as vscode from 'vscode';
|
import vscode = require('vscode');
|
||||||
import * as opener from 'opener';
|
|
||||||
import TelemetryReporter from 'vscode-extension-telemetry';
|
import TelemetryReporter from 'vscode-extension-telemetry';
|
||||||
import { PlatformInformation } from 'service-downloader/out/platform';
|
import { Utils } from './utils';
|
||||||
import { ErrorAction, ErrorHandler, Message, CloseAction } from 'vscode-languageclient';
|
import { PlatformInformation, Runtime, LinuxDistribution } from './platform';
|
||||||
|
import { IExtensionConstants } from './contracts/contracts';
|
||||||
import * as Utils from './utils';
|
|
||||||
import * as Constants from './constants';
|
|
||||||
|
|
||||||
const packageJson = require('../package.json');
|
|
||||||
|
|
||||||
export interface ITelemetryEventProperties {
|
export interface ITelemetryEventProperties {
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
@@ -43,6 +38,15 @@ export class Telemetry {
|
|||||||
private static userId: string;
|
private static userId: string;
|
||||||
private static platformInformation: PlatformInformation;
|
private static platformInformation: PlatformInformation;
|
||||||
private static disabled: boolean;
|
private static disabled: boolean;
|
||||||
|
private static _getRuntimeId: (platform: string, architecture: string, distribution: LinuxDistribution) => Runtime;
|
||||||
|
|
||||||
|
public static get getRuntimeId() {
|
||||||
|
return this._getRuntimeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static set getRuntimeId(runtimeIdGetter: (platform: string, architecture: string, distribution: LinuxDistribution) => Runtime) {
|
||||||
|
this._getRuntimeId = runtimeIdGetter;
|
||||||
|
}
|
||||||
|
|
||||||
// Get the unique ID for the current user of the extension
|
// Get the unique ID for the current user of the extension
|
||||||
public static getUserId(): Promise<string> {
|
public static getUserId(): Promise<string> {
|
||||||
@@ -65,7 +69,7 @@ export class Telemetry {
|
|||||||
return Promise.resolve(this.platformInformation);
|
return Promise.resolve(this.platformInformation);
|
||||||
} else {
|
} else {
|
||||||
return new Promise<PlatformInformation>(resolve => {
|
return new Promise<PlatformInformation>(resolve => {
|
||||||
PlatformInformation.getCurrent().then(info => {
|
PlatformInformation.getCurrent(this.getRuntimeId, 'telemetry').then(info => {
|
||||||
this.platformInformation = info;
|
this.platformInformation = info;
|
||||||
resolve(this.platformInformation);
|
resolve(this.platformInformation);
|
||||||
});
|
});
|
||||||
@@ -73,6 +77,8 @@ export class Telemetry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disable telemetry reporting
|
* Disable telemetry reporting
|
||||||
*/
|
*/
|
||||||
@@ -83,7 +89,7 @@ export class Telemetry {
|
|||||||
/**
|
/**
|
||||||
* Initialize the telemetry reporter for use.
|
* Initialize the telemetry reporter for use.
|
||||||
*/
|
*/
|
||||||
public static initialize(): void {
|
public static initialize(context: vscode.ExtensionContext, extensionConstants: IExtensionConstants): void {
|
||||||
if (typeof this.reporter === 'undefined') {
|
if (typeof this.reporter === 'undefined') {
|
||||||
// Check if the user has opted out of telemetry
|
// Check if the user has opted out of telemetry
|
||||||
if (!vscode.workspace.getConfiguration('telemetry').get<boolean>('enableTelemetry', true)) {
|
if (!vscode.workspace.getConfiguration('telemetry').get<boolean>('enableTelemetry', true)) {
|
||||||
@@ -91,8 +97,8 @@ export class Telemetry {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let packageInfo = Utils.getPackageInfo(packageJson);
|
let packageInfo = Utils.getPackageInfo(context);
|
||||||
this.reporter = new TelemetryReporter(packageInfo.name, packageInfo.version, packageInfo.aiKey);
|
this.reporter = new TelemetryReporter(extensionConstants.telemetryExtensionName, packageInfo.version, packageInfo.aiKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,10 +120,10 @@ export class Telemetry {
|
|||||||
|
|
||||||
// Only adding the method name and the fist line of the stack trace. We don't add the error message because it might have PII
|
// Only adding the method name and the fist line of the stack trace. We don't add the error message because it might have PII
|
||||||
this.sendTelemetryEvent('Exception', { methodName: methodName, errorLine: firstLine });
|
this.sendTelemetryEvent('Exception', { methodName: methodName, errorLine: firstLine });
|
||||||
// Utils.logDebug('Unhandled Exception occurred. error: ' + err + ' method: ' + methodName, extensionConfigName);
|
Utils.logDebug('Unhandled Exception occurred. error: ' + err + ' method: ' + methodName, extensionConfigName);
|
||||||
} catch (telemetryErr) {
|
} catch (telemetryErr) {
|
||||||
// If sending telemetry event fails ignore it so it won't break the extension
|
// If sending telemetry event fails ignore it so it won't break the extension
|
||||||
// Utils.logDebug('Failed to send telemetry event. error: ' + telemetryErr, extensionConfigName);
|
Utils.logDebug('Failed to send telemetry event. error: ' + telemetryErr, extensionConfigName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,7 +138,6 @@ export class Telemetry {
|
|||||||
if (typeof this.disabled === 'undefined') {
|
if (typeof this.disabled === 'undefined') {
|
||||||
this.disabled = false;
|
this.disabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.disabled || typeof (this.reporter) === 'undefined') {
|
if (this.disabled || typeof (this.reporter) === 'undefined') {
|
||||||
// Don't do anything if telemetry is disabled
|
// Don't do anything if telemetry is disabled
|
||||||
return;
|
return;
|
||||||
@@ -143,7 +148,7 @@ export class Telemetry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Augment the properties structure with additional common properties before sending
|
// Augment the properties structure with additional common properties before sending
|
||||||
Promise.all([this.getUserId(), this.getPlatformInformation()]).then(() => {
|
Promise.all([this.getUserId, this.getPlatformInformation]).then(() => {
|
||||||
properties['userId'] = this.userId;
|
properties['userId'] = this.userId;
|
||||||
properties['distribution'] = (this.platformInformation && this.platformInformation.distribution) ?
|
properties['distribution'] = (this.platformInformation && this.platformInformation.distribution) ?
|
||||||
`${this.platformInformation.distribution.name}, ${this.platformInformation.distribution.version}` : '';
|
`${this.platformInformation.distribution.name}, ${this.platformInformation.distribution.version}` : '';
|
||||||
@@ -152,60 +157,3 @@ export class Telemetry {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle Language Service client errors
|
|
||||||
* @class LanguageClientErrorHandler
|
|
||||||
*/
|
|
||||||
export class LanguageClientErrorHandler implements ErrorHandler {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show an error message prompt with a link to known issues wiki page
|
|
||||||
* @memberOf LanguageClientErrorHandler
|
|
||||||
*/
|
|
||||||
showOnErrorPrompt(): void {
|
|
||||||
Telemetry.sendTelemetryEvent(Constants.serviceName + 'Crash');
|
|
||||||
vscode.window.showErrorMessage(
|
|
||||||
Constants.serviceCrashMessage,
|
|
||||||
Constants.serviceCrashButton).then(action => {
|
|
||||||
if (action && action === Constants.serviceCrashButton) {
|
|
||||||
opener(Constants.serviceCrashLink);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback for language service client error
|
|
||||||
*
|
|
||||||
* @param {Error} error
|
|
||||||
* @param {Message} message
|
|
||||||
* @param {number} count
|
|
||||||
* @returns {ErrorAction}
|
|
||||||
*
|
|
||||||
* @memberOf LanguageClientErrorHandler
|
|
||||||
*/
|
|
||||||
error(error: Error, message: Message, count: number): ErrorAction {
|
|
||||||
this.showOnErrorPrompt();
|
|
||||||
|
|
||||||
// we don't retry running the service since crashes leave the extension
|
|
||||||
// in a bad, unrecovered state
|
|
||||||
return ErrorAction.Shutdown;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback for language service client closed
|
|
||||||
*
|
|
||||||
* @returns {CloseAction}
|
|
||||||
*
|
|
||||||
* @memberOf LanguageClientErrorHandler
|
|
||||||
*/
|
|
||||||
closed(): CloseAction {
|
|
||||||
this.showOnErrorPrompt();
|
|
||||||
|
|
||||||
// we don't retry running the service since crashes leave the extension
|
|
||||||
// in a bad, unrecovered state
|
|
||||||
return CloseAction.DoNotRestart;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Telemetry.initialize();
|
|
||||||
130
extensions-modules/src/models/utils.ts
Normal file
130
extensions-modules/src/models/utils.ts
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* 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 * as crypto from 'crypto';
|
||||||
|
import * as os from 'os';
|
||||||
|
import vscode = require('vscode');
|
||||||
|
import { Constants } from './constants';
|
||||||
|
import { ExtensionContext } from 'vscode';
|
||||||
|
var path = require('path');
|
||||||
|
|
||||||
|
export namespace Utils {
|
||||||
|
// INTERFACES /////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Interface for package.json information
|
||||||
|
export interface IPackageInfo {
|
||||||
|
name: string;
|
||||||
|
version: string;
|
||||||
|
aiKey: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FUNCTIONS //////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Get information from the extension's package.json file
|
||||||
|
export function getPackageInfo(context: ExtensionContext): IPackageInfo {
|
||||||
|
let extensionPackage = require(context.asAbsolutePath('./package.json'));
|
||||||
|
if (extensionPackage) {
|
||||||
|
return {
|
||||||
|
name: extensionPackage.name,
|
||||||
|
version: extensionPackage.version,
|
||||||
|
aiKey: extensionPackage.aiKey
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate a new GUID
|
||||||
|
export function generateGuid(): string {
|
||||||
|
let hexValues: string[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'];
|
||||||
|
// c.f. rfc4122 (UUID version 4 = xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx)
|
||||||
|
let oct: string = '';
|
||||||
|
let tmp: number;
|
||||||
|
/* tslint:disable:no-bitwise */
|
||||||
|
for (let a: number = 0; a < 4; a++) {
|
||||||
|
tmp = (4294967296 * Math.random()) | 0;
|
||||||
|
oct += hexValues[tmp & 0xF] +
|
||||||
|
hexValues[tmp >> 4 & 0xF] +
|
||||||
|
hexValues[tmp >> 8 & 0xF] +
|
||||||
|
hexValues[tmp >> 12 & 0xF] +
|
||||||
|
hexValues[tmp >> 16 & 0xF] +
|
||||||
|
hexValues[tmp >> 20 & 0xF] +
|
||||||
|
hexValues[tmp >> 24 & 0xF] +
|
||||||
|
hexValues[tmp >> 28 & 0xF];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 'Set the two most significant bits (bits 6 and 7) of the clock_seq_hi_and_reserved to zero and one, respectively'
|
||||||
|
let clockSequenceHi: string = hexValues[8 + (Math.random() * 4) | 0];
|
||||||
|
return oct.substr(0, 8) + '-' + oct.substr(9, 4) + '-4' + oct.substr(13, 3) + '-' + clockSequenceHi + oct.substr(16, 3) + '-' + oct.substr(19, 12);
|
||||||
|
/* tslint:enable:no-bitwise */
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate a unique, deterministic ID for the current user of the extension
|
||||||
|
export function generateUserId(): Promise<string> {
|
||||||
|
return new Promise<string>(resolve => {
|
||||||
|
try {
|
||||||
|
let interfaces = os.networkInterfaces();
|
||||||
|
let mac;
|
||||||
|
for (let key of Object.keys(interfaces)) {
|
||||||
|
let item = interfaces[key][0];
|
||||||
|
if (!item.internal) {
|
||||||
|
mac = item.mac;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mac) {
|
||||||
|
resolve(crypto.createHash('sha256').update(mac + os.homedir(), 'utf8').digest('hex'));
|
||||||
|
} else {
|
||||||
|
resolve(generateGuid());
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
resolve(generateGuid()); // fallback
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the URI for the currently open file if there is one; otherwise return the empty string
|
||||||
|
export function getActiveTextEditorUri(): string {
|
||||||
|
if (typeof vscode.window.activeTextEditor !== 'undefined' &&
|
||||||
|
typeof vscode.window.activeTextEditor.document !== 'undefined') {
|
||||||
|
return vscode.window.activeTextEditor.document.uri.toString();
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper to log debug messages
|
||||||
|
export function logDebug(msg: any, extensionConfigSectionName: string): void {
|
||||||
|
let config = vscode.workspace.getConfiguration(extensionConfigSectionName);
|
||||||
|
let logDebugInfo = config[Constants.configLogDebugInfo];
|
||||||
|
if (logDebugInfo === true) {
|
||||||
|
let currentTime = new Date().toLocaleTimeString();
|
||||||
|
let outputMsg = '[' + currentTime + ']: ' + msg ? msg.toString() : '';
|
||||||
|
console.log(outputMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper to show an error message
|
||||||
|
export function showErrorMsg(msg: string, extensionName: string): void {
|
||||||
|
vscode.window.showErrorMessage(extensionName + ': ' + msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isEmpty(str: any): boolean {
|
||||||
|
return (!str || '' === str);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The function is a duplicate of \src\paths.js. IT would be better to import path.js but it doesn't
|
||||||
|
// work for now because the extension is running in different process.
|
||||||
|
export function getAppDataPath() {
|
||||||
|
var platform = process.platform;
|
||||||
|
switch (platform) {
|
||||||
|
case 'win32': return process.env['APPDATA'] || path.join(process.env['USERPROFILE'], 'AppData', 'Roaming');
|
||||||
|
case 'darwin': return path.join(os.homedir(), 'Library', 'Application Support');
|
||||||
|
case 'linux': return process.env['XDG_CONFIG_HOME'] || path.join(os.homedir(), '.config');
|
||||||
|
default: throw new Error('Platform not supported');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDefaultLogLocation() {
|
||||||
|
return path.join(getAppDataPath(), 'sqlops');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"target": "es6",
|
"target": "es6",
|
||||||
"outDir": "./out",
|
"outDir": "../lib",
|
||||||
"lib": [
|
"lib": [
|
||||||
"es6", "es2015.promise"
|
"es6", "es2015.promise"
|
||||||
],
|
],
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user