mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 11:01:37 -05:00
Compare commits
168 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0de5d7a96a | ||
|
|
2f8f6064a1 | ||
|
|
d3526f8cf7 | ||
|
|
b045e536c1 | ||
|
|
ab91c88b34 | ||
|
|
f91010c398 | ||
|
|
cd0d0f911b | ||
|
|
bd67006f63 | ||
|
|
5aedd96276 | ||
|
|
751a89d839 | ||
|
|
a226e90c38 | ||
|
|
2eeb2b0d71 | ||
|
|
f2779f2a50 | ||
|
|
357bb1916e | ||
|
|
67a9ff3e16 | ||
|
|
7099b11651 | ||
|
|
27e9e8ec2b | ||
|
|
4d1e3263f4 | ||
|
|
cb1d630cfb | ||
|
|
d7b9e9ab78 | ||
|
|
cb7b8b956f | ||
|
|
a0608a51c1 | ||
|
|
217f5e7ee5 | ||
|
|
50c4fd79b7 | ||
|
|
4cfd9bdbc0 | ||
|
|
f76e8ae2c5 | ||
|
|
089577c5a8 | ||
|
|
c116f933e2 | ||
|
|
fe496ab03b | ||
|
|
3c3d8417e9 | ||
|
|
2b2672e4bd | ||
|
|
1bfc8c1914 | ||
|
|
2f854cce4a | ||
|
|
40550d0840 | ||
|
|
38bedea0bd | ||
|
|
75ab5c1a36 | ||
|
|
3d7c081068 | ||
|
|
c276bd8a37 | ||
|
|
890bece70c | ||
|
|
4a4fe584d5 | ||
|
|
bcd72d21c7 | ||
|
|
722f5e56cd | ||
|
|
f3c7b2416b | ||
|
|
383d74ceb4 | ||
|
|
64f61b2954 | ||
|
|
5c0002404a | ||
|
|
66f39fd3eb | ||
|
|
e79e3bdf1d | ||
|
|
9dd3ec9179 | ||
|
|
c06ab27d08 | ||
|
|
fab4185c1f | ||
|
|
bc4b399f87 | ||
|
|
52544fa953 | ||
|
|
8b2ea4f0a0 | ||
|
|
45b1ae1fb1 | ||
|
|
090ac6eab2 | ||
|
|
b7169f3da9 | ||
|
|
587c3ab436 | ||
|
|
80bbd9dbf3 | ||
|
|
c019175fff | ||
|
|
7f79ab47ac | ||
|
|
ba188189a8 | ||
|
|
8e6359b3a4 | ||
|
|
aac77ed982 | ||
|
|
1d284ea66a | ||
|
|
9f5268101d | ||
|
|
0bba972657 | ||
|
|
bab9fc01ea | ||
|
|
692ed02df8 | ||
|
|
2e67d03b56 | ||
|
|
56ca3406c4 | ||
|
|
94e8ce5185 | ||
|
|
bb54b0280a | ||
|
|
a99c34d817 | ||
|
|
c06f45cf0e | ||
|
|
8114498fb5 | ||
|
|
889b60a71b | ||
|
|
45023b2e71 | ||
|
|
1c08e64651 | ||
|
|
3432dac261 | ||
|
|
5adab4fafb | ||
|
|
d45aebcd19 | ||
|
|
6bf21e4340 | ||
|
|
7ee6dfa21e | ||
|
|
bd7341ddc2 | ||
|
|
f9d8f479b5 | ||
|
|
fdc956e116 | ||
|
|
a44df9adab | ||
|
|
dbc2ce0b3a | ||
|
|
51b8e02455 | ||
|
|
4f9dfe9afa | ||
|
|
db05ed840d | ||
|
|
8570910a43 | ||
|
|
8a9ee40524 | ||
|
|
c166ce112b | ||
|
|
cea52d2314 | ||
|
|
d1cc937f9d | ||
|
|
b61fbc806b | ||
|
|
dfc212369a | ||
|
|
47b855adf8 | ||
|
|
d1bffd0eb0 | ||
|
|
f1b64918ce | ||
|
|
005e3f1476 | ||
|
|
49d19a9ab8 | ||
|
|
f5a866aa42 | ||
|
|
f1ddea986a | ||
|
|
040549d264 | ||
|
|
4b51d9b386 | ||
|
|
73fbd787d8 | ||
|
|
b6f848eff1 | ||
|
|
6f21d6e27e | ||
|
|
af9c3d3872 | ||
|
|
7806a29bed | ||
|
|
0412b643d2 | ||
|
|
d7ee37a946 | ||
|
|
af53a13e6b | ||
|
|
98fa028ce5 | ||
|
|
ed4d4e33b5 | ||
|
|
6c83736626 | ||
|
|
959b4fbab5 | ||
|
|
3b7ff61000 | ||
|
|
cf283a9266 | ||
|
|
e28b86ea87 | ||
|
|
362664c4d8 | ||
|
|
c860a0edb2 | ||
|
|
8e11e460b5 | ||
|
|
ce4e7f4bef | ||
|
|
a8c7c69509 | ||
|
|
579e6bf0cb | ||
|
|
332dc03df0 | ||
|
|
24ea675d7d | ||
|
|
3df522536f | ||
|
|
f5aa49ebb9 | ||
|
|
3076390eb1 | ||
|
|
b7c935c602 | ||
|
|
bbb0f39a94 | ||
|
|
fe04fd72bc | ||
|
|
8a350809fd | ||
|
|
642514fd94 | ||
|
|
234c2f7c9e | ||
|
|
1b2e264c7d | ||
|
|
495c2e62e6 | ||
|
|
03baf3610a | ||
|
|
251ae01c3e | ||
|
|
9a1ac20710 | ||
|
|
f640bda802 | ||
|
|
f9ff1c5910 | ||
|
|
a63800deb1 | ||
|
|
e432884e25 | ||
|
|
0c14c3cc7f | ||
|
|
006eedd3a1 | ||
|
|
cb4fe55bef | ||
|
|
b33ffafdc0 | ||
|
|
e2efe69b73 | ||
|
|
8b85a47cf7 | ||
|
|
5afa287e47 | ||
|
|
0cc7c540a9 | ||
|
|
edd867b6fc | ||
|
|
7808496416 | ||
|
|
ad27f7dbba | ||
|
|
a6cb7cbd65 | ||
|
|
146fd41b50 | ||
|
|
fcb6f7f9ee | ||
|
|
94bd1c4d7d | ||
|
|
e4a0e4e0c1 | ||
|
|
b73b09a1d3 | ||
|
|
a69a9778a6 | ||
|
|
6d3995aa29 |
@@ -11,6 +11,6 @@ trim_trailing_whitespace = true
|
||||
|
||||
# The indent size used in the `package.json` file cannot be changed
|
||||
# https://github.com/npm/npm/pull/3180#issuecomment-16336516
|
||||
[{*.yml,*.yaml,npm-shrinkwrap.json,package.json}]
|
||||
[{*.yml,*.yaml,package.json}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
@@ -10,5 +10,10 @@
|
||||
"no-extra-semi": "warn",
|
||||
"semi": "warn"
|
||||
},
|
||||
"extends": "eslint:recommended"
|
||||
"extends": "eslint:recommended",
|
||||
"parserOptions": {
|
||||
"ecmaFeatures": {
|
||||
"experimentalObjectRestSpread": true
|
||||
}
|
||||
}
|
||||
}
|
||||
17
.gitignore
vendored
17
.gitignore
vendored
@@ -1,22 +1,8 @@
|
||||
.DS_Store
|
||||
npm-debug.log
|
||||
Thumbs.db
|
||||
.DS_Store
|
||||
*.dat
|
||||
*.db
|
||||
*.exe
|
||||
*.log
|
||||
*.nupkg
|
||||
*.orig
|
||||
*.vsix
|
||||
*BROWSE.VC*
|
||||
sqltoolsservice
|
||||
coverage
|
||||
test-reports
|
||||
.vscode-test
|
||||
node_modules/
|
||||
.build/
|
||||
.vs/
|
||||
out/
|
||||
out-build/
|
||||
out-editor/
|
||||
@@ -26,4 +12,5 @@ out-vscode/
|
||||
out-vscode-min/
|
||||
build/node_modules
|
||||
coverage/
|
||||
_site
|
||||
test_data/
|
||||
yarn-error.log
|
||||
24
.travis.yml
24
.travis.yml
@@ -7,10 +7,13 @@ os:
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.npm
|
||||
- $HOME/.cache/yarn
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
webhooks:
|
||||
- http://vscode-probot.westus.cloudapp.azure.com:3450/travis/notifications
|
||||
- http://vscode-test-probot.westus.cloudapp.azure.com:3450/travis/notifications
|
||||
|
||||
addons:
|
||||
apt:
|
||||
@@ -31,23 +34,26 @@ before_install:
|
||||
- git submodule update --init --recursive
|
||||
- git clone --depth 1 https://github.com/creationix/nvm.git ./.nvm
|
||||
- source ./.nvm/nvm.sh
|
||||
- nvm install 7.9.0
|
||||
- nvm use 7.9.0
|
||||
- npm config set python `which python`
|
||||
- npm install -g gulp
|
||||
- nvm install 8.9.1
|
||||
- nvm use 8.9.1
|
||||
- npm i -g yarn
|
||||
# - npm config set python `which python`
|
||||
- if [ $TRAVIS_OS_NAME == "linux" ]; then
|
||||
export CXX="g++-4.9" CC="gcc-4.9" DISPLAY=:99.0;
|
||||
sh -e /etc/init.d/xvfb start;
|
||||
sleep 3;
|
||||
fi
|
||||
# Make npm logs less verbose
|
||||
# - npm config set depth 0
|
||||
# - npm config set loglevel warn
|
||||
|
||||
install:
|
||||
- ./scripts/npm.sh install
|
||||
- yarn
|
||||
|
||||
script:
|
||||
- gulp electron --silent
|
||||
- gulp compile --silent --max_old_space_size=4096
|
||||
- gulp optimize-vscode --silent --max_old_space_size=4096
|
||||
- node_modules/.bin/gulp electron --silent
|
||||
- node_modules/.bin/gulp compile --silent --max_old_space_size=4096
|
||||
- node_modules/.bin/gulp optimize-vscode --silent --max_old_space_size=4096
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./scripts/test.sh --coverage --reporter dot; else ./scripts/test.sh --reporter dot; fi
|
||||
|
||||
after_success:
|
||||
|
||||
1
.vscode/launch.json
vendored
1
.vscode/launch.json
vendored
@@ -104,6 +104,7 @@
|
||||
},
|
||||
"stopOnEntry": false,
|
||||
"args": [
|
||||
"--delay",
|
||||
"--timeout",
|
||||
"2000"
|
||||
],
|
||||
|
||||
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@@ -34,5 +34,7 @@
|
||||
"command": "${workspaceFolder}\\scripts\\test.bat --coverage --run ${file}"
|
||||
}
|
||||
}
|
||||
]
|
||||
],
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"git.ignoreLimitWarning": true
|
||||
}
|
||||
6
.vscode/tasks.json
vendored
6
.vscode/tasks.json
vendored
@@ -33,11 +33,11 @@
|
||||
"task": "tslint",
|
||||
"label": "Run tslint",
|
||||
"problemMatcher": [
|
||||
"$tslint4"
|
||||
"$tslint5"
|
||||
]
|
||||
},
|
||||
{
|
||||
"taskName": "Run tests",
|
||||
"label": "Run tests",
|
||||
"type": "shell",
|
||||
"command": "./scripts/test.sh",
|
||||
"windows": {
|
||||
@@ -50,7 +50,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"taskName": "Run Dev",
|
||||
"label": "Run Dev",
|
||||
"type": "shell",
|
||||
"command": "./scripts/code.sh",
|
||||
"windows": {
|
||||
|
||||
3
.yarnrc
Normal file
3
.yarnrc
Normal file
@@ -0,0 +1,3 @@
|
||||
disturl "https://atom.io/download/electron"
|
||||
target "1.7.11"
|
||||
runtime "electron"
|
||||
41
CHANGELOG.md
41
CHANGELOG.md
@@ -1,6 +1,44 @@
|
||||
# Change Log
|
||||
|
||||
## Version 0.25.2
|
||||
## 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 status: Public Preview
|
||||
|
||||
## What's new in this version
|
||||
The February release fixes several important customer reported issues, as well as various feature improvements. We've also introduced auto-update support in February which will simplify keeping updated with the lastest changes.
|
||||
|
||||
Here's some of the highlights in the February release.
|
||||
|
||||
* Support Auto-Update installation on Windows and macOS
|
||||
* Publish RPM and DEB packages to offical Microsoft repos
|
||||
* 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 #481 Add "Check for updates" option.
|
||||
* SQL Editor colorization and auto-completion fixes
|
||||
* `#584 Keyword "FULL" not highlighted by IntelliSense`
|
||||
* `#345 Colorize SQL functions within the editor`
|
||||
* `#300 [#tempData] latest "]" will display green color`
|
||||
* `#225 Keyword color mismatch`
|
||||
* `#60 invalid sql syntax color highlighting when using temporary table in from clause`
|
||||
* Introduce Connection extensibility API
|
||||
* VS Code Editor 1.19 integration
|
||||
* Update JustinPealing/html-query-plan component to pick-up several Query Plan viewer improvements
|
||||
|
||||
## 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:
|
||||
|
||||
* SebastianPfliegel for `Add cursor snippet (#475)`
|
||||
* mikaoelitiana for fix: `revert README and CONTRIBUTING after last VSCode merge (#574)`
|
||||
* alextercete for `Reinstate menu item to install from VSIX (#682)`
|
||||
|
||||
## Version 0.25.4
|
||||
* Release date: January 17, 2017
|
||||
* Release status: Public Preview
|
||||
|
||||
@@ -23,6 +61,7 @@ Here's some of the highlights in the January release.
|
||||
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
|
||||
|
||||
* alextercete for `Fix "No extension gallery service configured" error (#427)`
|
||||
* SebastianPfliegel for `Add cursor snippet (#475)`
|
||||
|
||||
## Version 0.24.1
|
||||
* Release date: December 19, 2017
|
||||
|
||||
@@ -771,5 +771,42 @@
|
||||
"\"\"\""
|
||||
],
|
||||
"isProd": true
|
||||
},
|
||||
{
|
||||
"name": "spdlog original",
|
||||
"version": "0.14.0",
|
||||
"repositoryURL": "https://github.com/gabime/spdlog",
|
||||
"license": "MIT",
|
||||
"isProd": true
|
||||
},
|
||||
{
|
||||
"isLicense": true,
|
||||
"name": "spdlog",
|
||||
"version": "0.14.0",
|
||||
"repositoryURL": "https://github.com/gabime/spdlog",
|
||||
"license": "MIT",
|
||||
"licenseDetail": [
|
||||
"MIT License",
|
||||
"",
|
||||
"Copyright (c) Microsoft Corporation. All rights reserved.",
|
||||
"",
|
||||
"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"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
45
README.md
45
README.md
@@ -1,22 +1,34 @@
|
||||
# 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.
|
||||
|
||||
**Download SQL Operations Studio December Public Preview**
|
||||
**Download SQL Operations Studio February Public Preview**
|
||||
|
||||
Platform | Link
|
||||
-- | --
|
||||
Windows Setup Installer | https://go.microsoft.com/fwlink/?linkid=865305
|
||||
Windows ZIP | https://go.microsoft.com/fwlink/?linkid=865304
|
||||
macOS ZIP | https://go.microsoft.com/fwlink/?linkid=865306
|
||||
Linux TAR.GZ | https://go.microsoft.com/fwlink/?linkid=865307
|
||||
Linux DEB | https://go.microsoft.com/fwlink/?linkid=865308
|
||||
Linux RPM | https://go.microsoft.com/fwlink/?linkid=865309
|
||||
Windows Setup Installer | https://go.microsoft.com/fwlink/?linkid=867998
|
||||
Windows ZIP | https://go.microsoft.com/fwlink/?linkid=867997
|
||||
macOS ZIP | https://go.microsoft.com/fwlink/?linkid=867999
|
||||
Linux TAR.GZ | https://go.microsoft.com/fwlink/?linkid=868000
|
||||
Linux DEB | https://go.microsoft.com/fwlink/?linkid=868002
|
||||
Linux RPM | https://go.microsoft.com/fwlink/?linkid=868001
|
||||
|
||||
Go to our [download page](https://aka.ms/sqlopsstudio) for more specific instructions.
|
||||
|
||||
Try out the latest insiders build from `master` at https://github.com/Microsoft/sqlopsstudio/releases.
|
||||
|
||||
See the [change log](https://github.com/Microsoft/sqlopsstudio/blob/master/CHANGELOG.md) for additional details of what's in this release.
|
||||
|
||||
**Design Discussions**
|
||||
|
||||
The SQL Operations Studio team would like to incorporate community feedback earlier in the development process. To facilitate this, we'd like to share our designs while features are actively being built.
|
||||
|
||||
We're currently collecting input on the **SQL Agent** experience and enhancements to the Manage Dashboard that we're calling **"Command Center"**. We'll add additional design feedback requests below as we start work in new feature areas. Please leave comments on these issues to help us understand your requirements and shape feature development.
|
||||
|
||||
* [#750 Seeking community feedback on SQL Agent UX prototype](https://github.com/Microsoft/sqlopsstudio/issues/750)
|
||||
|
||||
**Feature Highlights**
|
||||
|
||||
- Cross-Platform DB management for Windows, macOS and Linux with simple XCopy deployment
|
||||
@@ -46,9 +58,28 @@ 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.
|
||||
|
||||
## 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
|
||||
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"
|
||||
We would like to thank all our users who raised issues, and in particular the following users who helped contribute fixes:
|
||||
|
||||
* SebastianPfliegel for `Add cursor snippet (#475)`
|
||||
* mikaoelitiana for fix: `revert README and CONTRIBUTING after last VSCode merge (#574)`
|
||||
* alextercete for `Reinstate menu item to install from VSIX (#682)`
|
||||
* alextercete for `Fix "No extension gallery service configured" error (#427)`
|
||||
* 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 `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)`
|
||||
* SebastianPfliegel `Remove sqlExtensionHelp (#312)`
|
||||
* olljanat for `Implemented npm version check (#314)`
|
||||
|
||||
## License
|
||||
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
@@ -3,19 +3,17 @@ environment:
|
||||
VSCODE_BUILD_VERBOSE: true
|
||||
|
||||
cache:
|
||||
- '%APPDATA%\npm-cache'
|
||||
- '%LOCALAPPDATA%\Yarn\cache'
|
||||
|
||||
install:
|
||||
- ps: Install-Product node 7.9.0 x64
|
||||
- npm install -g npm@4 --silent
|
||||
- ps: Install-Product node 8.9.1 x64
|
||||
|
||||
build_script:
|
||||
- .\scripts\npm.bat install
|
||||
- yarn
|
||||
- .\node_modules\.bin\gulp electron
|
||||
- npm run compile
|
||||
|
||||
test_script:
|
||||
- node --version
|
||||
- npm --version
|
||||
- .\scripts\test.bat
|
||||
- .\scripts\test-integration.bat
|
||||
|
||||
74
build/dependencies.js
Normal file
74
build/dependencies.js
Normal file
@@ -0,0 +1,74 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 path = require('path');
|
||||
const parseSemver = require('parse-semver');
|
||||
const cp = require('child_process');
|
||||
const _ = require('underscore');
|
||||
|
||||
function asYarnDependency(prefix, tree) {
|
||||
let parseResult;
|
||||
|
||||
try {
|
||||
parseResult = parseSemver(tree.name);
|
||||
} catch (err) {
|
||||
err.message += `: ${tree.name}`;
|
||||
console.warn(`Could not parse semver: ${tree.name}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
// not an actual dependency in disk
|
||||
if (parseResult.version !== parseResult.range) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const name = parseResult.name;
|
||||
const version = parseResult.version;
|
||||
const dependencyPath = path.join(prefix, name);
|
||||
const children = [];
|
||||
|
||||
for (const child of (tree.children || [])) {
|
||||
const dep = asYarnDependency(path.join(prefix, name, 'node_modules'), child);
|
||||
|
||||
if (dep) {
|
||||
children.push(dep);
|
||||
}
|
||||
}
|
||||
|
||||
return { name, version, path: dependencyPath, children };
|
||||
}
|
||||
|
||||
function getYarnProductionDependencies(cwd) {
|
||||
const raw = cp.execSync('yarn list --json', { cwd, encoding: 'utf8', env: { ...process.env, NODE_ENV: 'production' }, stdio: [null, null, 'ignore'] });
|
||||
const match = /^{"type":"tree".*$/m.exec(raw);
|
||||
|
||||
if (!match || match.length !== 1) {
|
||||
throw new Error('Could not parse result of `yarn list --json`');
|
||||
}
|
||||
|
||||
const trees = JSON.parse(match[0]).data.trees;
|
||||
|
||||
return trees
|
||||
.map(tree => asYarnDependency(path.join(cwd, 'node_modules'), tree))
|
||||
.filter(dep => !!dep);
|
||||
}
|
||||
|
||||
function getProductionDependencies(cwd) {
|
||||
const result = [];
|
||||
const deps = getYarnProductionDependencies(cwd);
|
||||
const flatten = dep => { result.push({ name: dep.name, version: dep.version, path: dep.path }); dep.children.forEach(flatten); };
|
||||
deps.forEach(flatten);
|
||||
|
||||
return _.uniq(result);
|
||||
}
|
||||
|
||||
module.exports.getProductionDependencies = getProductionDependencies;
|
||||
|
||||
if (require.main === module) {
|
||||
const root = path.dirname(__dirname);
|
||||
console.log(JSON.stringify(getProductionDependencies(root), null, ' '));
|
||||
}
|
||||
@@ -62,6 +62,8 @@ const tasks = compilations.map(function (tsconfigFile) {
|
||||
const reporter = createReporter();
|
||||
|
||||
tsOptions.inlineSources = !!build;
|
||||
tsOptions.base = path.dirname(absolutePath);
|
||||
|
||||
const compilation = tsb.create(tsOptions, null, null, err => reporter(err.toString()));
|
||||
|
||||
return function () {
|
||||
|
||||
@@ -37,6 +37,7 @@ 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}',
|
||||
@@ -56,6 +57,7 @@ const indentationFilter = [
|
||||
'!**/*.template',
|
||||
'!**/*.yaml',
|
||||
'!**/*.yml',
|
||||
'!**/yarn.lock',
|
||||
'!**/lib/**',
|
||||
'!extensions/**/*.d.ts',
|
||||
'!src/typings/**/*.d.ts',
|
||||
@@ -63,11 +65,11 @@ const indentationFilter = [
|
||||
'!**/*.d.ts.recipe',
|
||||
'!test/assert.js',
|
||||
'!**/package.json',
|
||||
'!**/npm-shrinkwrap.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',
|
||||
@@ -122,7 +124,8 @@ const tslintFilter = [
|
||||
'!**/node_modules/**',
|
||||
'!extensions/typescript/test/colorize-fixtures/**',
|
||||
'!extensions/vscode-api-tests/testWorkspace/**',
|
||||
'!extensions/**/*.test.ts'
|
||||
'!extensions/**/*.test.ts',
|
||||
'!extensions/html/server/lib/jquery.d.ts'
|
||||
];
|
||||
|
||||
const copyrightHeader = [
|
||||
@@ -132,17 +135,6 @@ const copyrightHeader = [
|
||||
' *--------------------------------------------------------------------------------------------*/'
|
||||
].join('\n');
|
||||
|
||||
function reportFailures(failures) {
|
||||
failures.forEach(failure => {
|
||||
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}`);
|
||||
});
|
||||
}
|
||||
|
||||
gulp.task('eslint', () => {
|
||||
return vfs.src(all, { base: '.', follow: true, allowEmpty: true })
|
||||
.pipe(filter(eslintFilter))
|
||||
@@ -152,12 +144,12 @@ gulp.task('eslint', () => {
|
||||
});
|
||||
|
||||
gulp.task('tslint', () => {
|
||||
const options = { summarizeFailureOutput: true };
|
||||
const options = { emitError: false };
|
||||
|
||||
return vfs.src(all, { base: '.', follow: true, allowEmpty: true })
|
||||
.pipe(filter(tslintFilter))
|
||||
.pipe(gulptslint({ rulesDirectory: 'build/lib/tslint' }))
|
||||
.pipe(gulptslint.report(reportFailures, options));
|
||||
.pipe(gulptslint.report(options));
|
||||
});
|
||||
|
||||
const hygiene = exports.hygiene = (some, options) => {
|
||||
@@ -219,6 +211,17 @@ const hygiene = exports.hygiene = (some, options) => {
|
||||
});
|
||||
});
|
||||
|
||||
function reportFailures(failures) {
|
||||
failures.forEach(failure => {
|
||||
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 configuration = tslint.Configuration.findConfiguration(null, '.');
|
||||
const options = { formatter: 'json', rulesDirectory: 'build/lib/tslint' };
|
||||
@@ -227,9 +230,9 @@ const hygiene = exports.hygiene = (some, options) => {
|
||||
linter.lint(file.relative, contents, configuration.results);
|
||||
const result = linter.getResult();
|
||||
|
||||
if (result.failureCount > 0) {
|
||||
if (result.failures.length > 0) {
|
||||
reportFailures(result.failures);
|
||||
errorCount += result.failureCount;
|
||||
errorCount += result.failures.length;
|
||||
}
|
||||
|
||||
this.emit('data', file);
|
||||
@@ -254,20 +257,20 @@ const hygiene = exports.hygiene = (some, options) => {
|
||||
const javascript = result
|
||||
.pipe(filter(eslintFilter))
|
||||
.pipe(gulpeslint('src/.eslintrc'))
|
||||
.pipe(gulpeslint.formatEach('compact'));
|
||||
.pipe(gulpeslint.formatEach('compact'))
|
||||
// {{SQL CARBON EDIT}}
|
||||
// .pipe(gulpeslint.failAfterError());
|
||||
|
||||
return es.merge(typescript, javascript)
|
||||
.pipe(es.through(null, function () {
|
||||
// {{SQL CARBON EDIT}}
|
||||
// if (errorCount > 0) {
|
||||
// this.emit('error', 'Hygiene failed with ' + errorCount + ' errors. Check \'build/gulpfile.hygiene.js\'.');
|
||||
// } else {
|
||||
// this.emit('end');
|
||||
// }
|
||||
this.emit('end');
|
||||
}));
|
||||
return es.merge(typescript, javascript)
|
||||
.pipe(es.through(null, function () {
|
||||
// {{SQL CARBON EDIT}}
|
||||
// if (errorCount > 0) {
|
||||
// this.emit('error', 'Hygiene failed with ' + errorCount + ' errors. Check \'build/gulpfile.hygiene.js\'.');
|
||||
// } else {
|
||||
// this.emit('end');
|
||||
// }
|
||||
this.emit('end');
|
||||
}));
|
||||
};
|
||||
|
||||
gulp.task('hygiene', () => hygiene(''));
|
||||
@@ -303,11 +306,13 @@ if (require.main === module) {
|
||||
.split(/\r?\n/)
|
||||
.filter(l => !!l);
|
||||
|
||||
hygiene(some, { skipEOL: skipEOL }).on('error', err => {
|
||||
console.error();
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
if (some.length > 0) {
|
||||
hygiene(some, { skipEOL: skipEOL }).on('error', err => {
|
||||
console.error();
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -6,21 +6,14 @@
|
||||
'use strict';
|
||||
|
||||
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');
|
||||
const pkg = require('../package.json');
|
||||
// {{SQL CARBON EDIT}}
|
||||
const jeditor = require('gulp-json-editor');
|
||||
|
||||
gulp.task('mixin', function () {
|
||||
const repo = process.env['VSCODE_MIXIN_REPO'];
|
||||
|
||||
if (!repo) {
|
||||
console.log('Missing VSCODE_MIXIN_REPO, skipping mixin');
|
||||
// {{SQL CARBON EDIT}}
|
||||
const updateUrl = process.env['SQLOPS_UPDATEURL'];
|
||||
if (!updateUrl) {
|
||||
console.log('Missing SQLOPS_UPDATEURL, skipping mixin');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -31,39 +24,20 @@ gulp.task('mixin', function () {
|
||||
return;
|
||||
}
|
||||
|
||||
const url = `https://github.com/${repo}/archive/${pkg.distro}.zip`;
|
||||
const opts = { base: url };
|
||||
const username = process.env['VSCODE_MIXIN_USERNAME'];
|
||||
const password = process.env['VSCODE_MIXIN_PASSWORD'];
|
||||
|
||||
if (username || password) {
|
||||
opts.auth = { user: username || '', pass: password || '' };
|
||||
// {{SQL CARBON EDIT}}
|
||||
let serviceUrl = 'https://raw.githubusercontent.com/Microsoft/sqlopsstudio/release/extensions/extensionsGallery.json';
|
||||
if (quality === 'insider') {
|
||||
serviceUrl = `https://raw.githubusercontent.com/Microsoft/sqlopsstudio/release/extensions/extensionsGallery-${quality}.json`;
|
||||
}
|
||||
let newValues = {
|
||||
"updateUrl": updateUrl,
|
||||
"quality": quality,
|
||||
"extensionsGallery": {
|
||||
"serviceUrl": serviceUrl
|
||||
}
|
||||
};
|
||||
|
||||
console.log('Mixing in sources from \'' + url + '\':');
|
||||
|
||||
let all = remote('', opts)
|
||||
.pipe(zip.src())
|
||||
.pipe(filter(function (f) { return !f.isDirectory(); }))
|
||||
.pipe(util.rebase(1));
|
||||
|
||||
if (quality) {
|
||||
const productJsonFilter = filter('product.json', { restore: true });
|
||||
const mixin = all
|
||||
.pipe(filter(['quality/' + quality + '/**']))
|
||||
.pipe(util.rebase(2))
|
||||
.pipe(productJsonFilter)
|
||||
.pipe(buffer())
|
||||
.pipe(json(o => assign({}, require('../product.json'), o)))
|
||||
.pipe(productJsonFilter.restore);
|
||||
|
||||
all = es.merge(mixin);
|
||||
}
|
||||
|
||||
return all
|
||||
.pipe(es.mapSync(function (f) {
|
||||
console.log(f.relative);
|
||||
return f;
|
||||
}))
|
||||
return gulp.src('./product.json')
|
||||
.pipe(jeditor(newValues))
|
||||
.pipe(gulp.dest('.'));
|
||||
});
|
||||
@@ -13,10 +13,6 @@ const filter = require('gulp-filter');
|
||||
|
||||
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-client', util.rimraf('dataprotocol-node/client/node_modules'));
|
||||
gulp.task('clean-jsonrpc', util.rimraf('dataprotocol-node/jsonrpc/node_modules'));
|
||||
gulp.task('clean-server', util.rimraf('dataprotocol-node/server/node_modules'));
|
||||
gulp.task('clean-types', util.rimraf('dataprotocol-node/types/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']);
|
||||
|
||||
|
||||
@@ -29,18 +29,19 @@ const root = path.dirname(__dirname);
|
||||
const commit = util.getVersion(root);
|
||||
const packageJson = require('../package.json');
|
||||
const product = require('../product.json');
|
||||
const shrinkwrap = require('../npm-shrinkwrap.json');
|
||||
const crypto = require('crypto');
|
||||
const i18n = require('./lib/i18n');
|
||||
var del = require('del');
|
||||
const serviceInstaller = require('../extensions-modules/lib/languageservice/serviceInstallerUtil');
|
||||
const glob = require('glob');
|
||||
const deps = require('./dependencies');
|
||||
const getElectronVersion = require('./lib/electron').getElectronVersion;
|
||||
|
||||
const productionDependencies = deps.getProductionDependencies(path.dirname(__dirname));
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
const serviceInstaller = require('extensions-modules/lib/languageservice/serviceInstallerUtil');
|
||||
const glob = require('glob');
|
||||
|
||||
const productDependencies = Object.keys(product.dependencies || {});
|
||||
const dependencies = Object.keys(shrinkwrap.dependencies)
|
||||
.concat(productDependencies); // additional dependencies from our product configuration
|
||||
var del = require('del');
|
||||
const extensionsRoot = path.join(root, 'extensions');
|
||||
const extensionsProductionDependencies = deps.getProductionDependencies(extensionsRoot);
|
||||
const baseModules = Object.keys(process.binding('natives')).filter(n => !/^_|\//.test(n));
|
||||
// {{SQL CARBON EDIT}}
|
||||
const nodeModules = [
|
||||
@@ -50,14 +51,15 @@ const nodeModules = [
|
||||
'rxjs/Subject',
|
||||
'rxjs/Observer',
|
||||
'ng2-charts/ng2-charts']
|
||||
.concat(dependencies)
|
||||
.concat(Object.keys(product.dependencies || {}))
|
||||
.concat(_.uniq(productionDependencies.map(d => d.name)))
|
||||
.concat(baseModules);
|
||||
|
||||
// Build
|
||||
|
||||
const builtInExtensions = [
|
||||
{ name: 'ms-vscode.node-debug', version: '1.18.3' },
|
||||
{ name: 'ms-vscode.node-debug2', version: '1.18.5' }
|
||||
{ name: 'ms-vscode.node-debug', version: '1.19.8' },
|
||||
{ name: 'ms-vscode.node-debug2', version: '1.19.4' }
|
||||
];
|
||||
|
||||
const excludedExtensions = [
|
||||
@@ -65,6 +67,14 @@ const excludedExtensions = [
|
||||
'vscode-colorize-tests'
|
||||
];
|
||||
|
||||
// {{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([
|
||||
buildfile.entrypoint('vs/workbench/workbench.main'),
|
||||
buildfile.base,
|
||||
@@ -79,8 +89,8 @@ const vscodeResources = [
|
||||
'out-build/bootstrap-amd.js',
|
||||
'out-build/paths.js',
|
||||
'out-build/vs/**/*.{svg,png,cur,html}',
|
||||
'out-build/vs/base/node/startupTimers.js',
|
||||
'out-build/vs/base/node/{stdForkStart.js,terminateProcess.sh}',
|
||||
'out-build/vs/base/common/performance.js',
|
||||
'out-build/vs/base/node/{stdForkStart.js,terminateProcess.sh,ps-win.ps1}',
|
||||
'out-build/vs/base/browser/ui/octiconLabel/octicons/**',
|
||||
'out-build/vs/workbench/browser/media/*-theme.css',
|
||||
'out-build/vs/workbench/electron-browser/bootstrap/**',
|
||||
@@ -94,7 +104,7 @@ const vscodeResources = [
|
||||
'out-build/vs/workbench/services/files/**/*.exe',
|
||||
'out-build/vs/workbench/services/files/**/*.md',
|
||||
'out-build/vs/code/electron-browser/sharedProcess.js',
|
||||
// {{SQL CARBON EDIT}}
|
||||
// {{SQL CARBON EDIT}}
|
||||
'out-build/sql/workbench/electron-browser/splashscreen/*',
|
||||
'out-build/sql/**/*.{svg,png,cur,html}',
|
||||
'out-build/sql/base/browser/ui/table/media/*.{gif,png,svg}',
|
||||
@@ -111,6 +121,7 @@ const vscodeResources = [
|
||||
'out-build/sql/parts/grid/views/**/*.html',
|
||||
'out-build/sql/parts/tasks/**/*.html',
|
||||
'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/icons/*.svg',
|
||||
'!**/test/**'
|
||||
@@ -154,10 +165,10 @@ gulp.task('minify-vscode', ['clean-minified-vscode', 'optimize-index-js'], commo
|
||||
const darwinCreditsTemplate = product.darwinCredits && _.template(fs.readFileSync(path.join(root, product.darwinCredits), 'utf8'));
|
||||
|
||||
const config = {
|
||||
version: packageJson.electronVersion,
|
||||
version: getElectronVersion(),
|
||||
productAppName: product.nameLong,
|
||||
companyName: 'Microsoft Corporation',
|
||||
copyright: 'Copyright (C) 2018 Microsoft. All rights reserved',
|
||||
copyright: 'Copyright (C) 2017 Microsoft. All rights reserved',
|
||||
darwinIcon: 'resources/darwin/code.icns',
|
||||
darwinBundleIdentifier: product.darwinBundleIdentifier,
|
||||
darwinApplicationCategoryType: 'public.app-category.developer-tools',
|
||||
@@ -240,10 +251,30 @@ function computeChecksum(filename) {
|
||||
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) {
|
||||
opts = opts || {};
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
// {{SQL CARBON EDIT}}
|
||||
const destination = path.join(path.dirname(root), 'sqlops') + (platform ? '-' + platform : '') + (arch ? '-' + arch : '');
|
||||
platform = platform || process.platform;
|
||||
|
||||
@@ -269,7 +300,10 @@ function packageTask(platform, arch, opts) {
|
||||
return { name: extensionName, path: extensionPath };
|
||||
})
|
||||
.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 nlsFilter = filter('**/*.nls.json', { restore: true });
|
||||
@@ -283,9 +317,18 @@ function packageTask(platform, arch, opts) {
|
||||
.pipe(nlsFilter.restore);
|
||||
}));
|
||||
|
||||
const localExtensionDependencies = gulp.src('extensions/node_modules/**', { base: '.' });
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
const extensionDepsSrc = [
|
||||
..._.flatten(extensionsProductionDependencies.map(d => path.relative(root, d.path)).map(d => [`${d}/**`, `!${d}/**/{test,tests}/**`])),
|
||||
];
|
||||
|
||||
const localExtensionDependencies = gulp.src(extensionDepsSrc, { base: '.', dot: true })
|
||||
.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('dataprotocol-client', ['node_modules/**', 'src/*.js'], undefined))
|
||||
.pipe(util.cleanNodeModule('extensions-modules', ['node_modules/**', 'src/*.js'], undefined))
|
||||
.pipe(util.cleanNodeModule('typescript', ['**/**'], undefined));
|
||||
|
||||
const sources = es.merge(src, localExtensions, localExtensionDependencies)
|
||||
.pipe(util.setExecutableBit(['**/*.sh']))
|
||||
.pipe(filter(['**',
|
||||
@@ -318,8 +361,10 @@ function packageTask(platform, arch, opts) {
|
||||
// {{SQL CARBON EDIT}}
|
||||
const dataApi = gulp.src('src/vs/data.d.ts').pipe(rename('out/sql/data.d.ts'));
|
||||
|
||||
const depsSrc = _.flatten(dependencies
|
||||
.map(function (d) { return ['node_modules/' + d + '/**', '!node_modules/' + d + '/**/{test,tests}/**']; }));
|
||||
const depsSrc = [
|
||||
..._.flatten(productionDependencies.map(d => path.relative(root, d.path)).map(d => [`${d}/**`, `!${d}/**/{test,tests}/**`])),
|
||||
..._.flatten(Object.keys(product.dependencies || {}).map(d => [`node_modules/${d}/**`, `!node_modules/${d}/**/{test,tests}/**`]))
|
||||
];
|
||||
|
||||
const deps = gulp.src(depsSrc, { base: '.', dot: true })
|
||||
.pipe(filter(['**', '!**/package-lock.json']))
|
||||
@@ -328,13 +373,22 @@ function packageTask(platform, arch, opts) {
|
||||
.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-watchdog', ['binding.gyp', 'build/**', 'src/**'], ['**/*.node']))
|
||||
.pipe(util.cleanNodeModule('spdlog', ['binding.gyp', 'build/**', 'deps/**', 'src/**', 'test/**'], ['**/*.node']))
|
||||
.pipe(util.cleanNodeModule('jschardet', ['dist/**']))
|
||||
.pipe(util.cleanNodeModule('windows-foreground-love', ['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('v8-profiler', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node', 'src/index.js']))
|
||||
.pipe(util.cleanNodeModule('keytar', ['binding.gyp', 'build/**', 'src/**', 'script/**', 'node_modules/**'], ['**/*.node']))
|
||||
.pipe(util.cleanNodeModule('node-pty', ['binding.gyp', 'build/**', 'src/**', 'tools/**'], ['build/Release/**']))
|
||||
|
||||
// {{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('emmet', ['node_modules/**'], undefined))
|
||||
.pipe(util.cleanNodeModule('pty.js', ['build/**'], ['build/Release/**']))
|
||||
.pipe(util.cleanNodeModule('jquery-ui', ['external/**', 'demos/**'], undefined))
|
||||
.pipe(util.cleanNodeModule('core-js', ['**/**'], 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']));
|
||||
|
||||
@@ -487,7 +541,7 @@ gulp.task('upload-vscode-sourcemaps', ['minify-vscode'], () => {
|
||||
const allConfigDetailsPath = path.join(os.tmpdir(), 'configuration.json');
|
||||
gulp.task('upload-vscode-configuration', ['generate-vscode-configuration'], () => {
|
||||
const branch = process.env.BUILD_SOURCEBRANCH;
|
||||
if (!branch.endsWith('/master') && !branch.indexOf('/release/') >= 0) {
|
||||
if (!branch.endsWith('/master') && branch.indexOf('/release/') < 0) {
|
||||
console.log(`Only runs on master and release branches, not ${branch}`);
|
||||
return;
|
||||
}
|
||||
|
||||
28
build/lib/electron.js
Normal file
28
build/lib/electron.js
Normal file
@@ -0,0 +1,28 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const root = path.dirname(path.dirname(__dirname));
|
||||
|
||||
function getElectronVersion() {
|
||||
const yarnrc = fs.readFileSync(path.join(root, '.yarnrc'), 'utf8');
|
||||
const target = /^target "(.*)"$/m.exec(yarnrc)[1];
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
module.exports.getElectronVersion = getElectronVersion;
|
||||
|
||||
// returns 0 if the right version of electron is in .build/electron
|
||||
if (require.main === module) {
|
||||
const version = getElectronVersion();
|
||||
const versionFile = path.join(root, '.build', 'electron', 'version');
|
||||
const isUpToDate = fs.existsSync(versionFile) && fs.readFileSync(versionFile, 'utf8') === `v${version}`;
|
||||
|
||||
process.exit(isUpToDate ? 0 : 1);
|
||||
}
|
||||
@@ -20,7 +20,7 @@ var vsce = require("vsce");
|
||||
var File = require("vinyl");
|
||||
function fromLocal(extensionPath) {
|
||||
var result = es.through();
|
||||
vsce.listFiles({ cwd: extensionPath })
|
||||
vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn })
|
||||
.then(function (fileNames) {
|
||||
var files = fileNames
|
||||
.map(function (fileName) { return path.join(extensionPath, fileName); })
|
||||
|
||||
@@ -22,7 +22,7 @@ import * as File from 'vinyl';
|
||||
export function fromLocal(extensionPath: string): Stream {
|
||||
const result = es.through();
|
||||
|
||||
vsce.listFiles({ cwd: extensionPath })
|
||||
vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn })
|
||||
.then(fileNames => {
|
||||
const files = fileNames
|
||||
.map(fileName => path.join(extensionPath, fileName))
|
||||
|
||||
@@ -141,7 +141,7 @@ var XLF = /** @class */ (function () {
|
||||
};
|
||||
XLF.prototype.addStringItem = function (item) {
|
||||
if (!item.id || !item.message) {
|
||||
throw new Error('No item ID or value specified.');
|
||||
throw new Error("No item ID or value specified: " + JSON.stringify(item));
|
||||
}
|
||||
this.appendNewLine("<trans-unit id=\"" + item.id + "\">", 4);
|
||||
this.appendNewLine("<source xml:lang=\"en\">" + item.message + "</source>", 6);
|
||||
@@ -501,6 +501,8 @@ function prepareXlfFiles(projectName, extensionName) {
|
||||
}
|
||||
exports.prepareXlfFiles = prepareXlfFiles;
|
||||
var editorProject = 'vscode-editor', workbenchProject = 'vscode-workbench', extensionsProject = 'vscode-extensions', setupProject = 'vscode-setup';
|
||||
// {{SQL CARBON EDIT}}
|
||||
var sqlopsProject = 'sqlops-core';
|
||||
function getResource(sourceFile) {
|
||||
var resource;
|
||||
if (/^vs\/platform/.test(sourceFile)) {
|
||||
@@ -529,6 +531,9 @@ function getResource(sourceFile) {
|
||||
else if (/^vs\/workbench/.test(sourceFile)) {
|
||||
return { name: 'vs/workbench', project: workbenchProject };
|
||||
}
|
||||
else if (/^sql/.test(sourceFile)) {
|
||||
return { name: 'sql', project: sqlopsProject };
|
||||
}
|
||||
throw new Error("Could not identify the XLF bundle for " + sourceFile);
|
||||
}
|
||||
exports.getResource = getResource;
|
||||
|
||||
@@ -192,7 +192,7 @@ export class XLF {
|
||||
|
||||
private addStringItem(item: Item): void {
|
||||
if (!item.id || !item.message) {
|
||||
throw new Error('No item ID or value specified.');
|
||||
throw new Error(`No item ID or value specified: ${JSON.stringify(item)}`);
|
||||
}
|
||||
|
||||
this.appendNewLine(`<trans-unit id="${item.id}">`, 4);
|
||||
@@ -578,6 +578,9 @@ const editorProject: string = 'vscode-editor',
|
||||
extensionsProject: string = 'vscode-extensions',
|
||||
setupProject: string = 'vscode-setup';
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
const sqlopsProject: string = 'sqlops-core';
|
||||
|
||||
export function getResource(sourceFile: string): Resource {
|
||||
let resource: string;
|
||||
|
||||
@@ -601,6 +604,11 @@ export function getResource(sourceFile: string): Resource {
|
||||
return { name: 'vs/workbench', project: workbenchProject };
|
||||
}
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
else if (/^sql/.test(sourceFile)) {
|
||||
return { name: 'sql', project: sqlopsProject };
|
||||
}
|
||||
|
||||
throw new Error(`Could not identify the XLF bundle for ${sourceFile}`);
|
||||
}
|
||||
|
||||
|
||||
@@ -212,8 +212,7 @@ function uglifyWithCopyrights() {
|
||||
return stream.pipe(minify({
|
||||
output: {
|
||||
comments: preserveComments(f),
|
||||
// linux tfs build agent is crashing, does this help?§
|
||||
max_line_len: 3200000
|
||||
max_line_len: 1024
|
||||
}
|
||||
}));
|
||||
}));
|
||||
|
||||
@@ -287,8 +287,7 @@ function uglifyWithCopyrights(): NodeJS.ReadWriteStream {
|
||||
return stream.pipe(minify({
|
||||
output: {
|
||||
comments: preserveComments(<FileWithCopyright>f),
|
||||
// linux tfs build agent is crashing, does this help?§
|
||||
max_line_len: 3200000
|
||||
max_line_len: 1024
|
||||
}
|
||||
}));
|
||||
}));
|
||||
|
||||
@@ -88,10 +88,11 @@ var NoUnexternalizedStringsRuleWalker = /** @class */ (function (_super) {
|
||||
var info = this.findDescribingParent(node);
|
||||
// Ignore strings in import and export nodes.
|
||||
if (info && info.isImport && doubleQuoted) {
|
||||
this.addFailureAtNode(node, NoUnexternalizedStringsRuleWalker.ImportFailureMessage, new Lint.Fix(NoUnexternalizedStringsRuleWalker.ImportFailureMessage, [
|
||||
this.createReplacement(node.getStart(), 1, '\''),
|
||||
this.createReplacement(node.getStart() + text.length - 1, 1, '\''),
|
||||
]));
|
||||
var fix = [
|
||||
Lint.Replacement.replaceFromTo(node.getStart(), 1, '\''),
|
||||
Lint.Replacement.replaceFromTo(node.getStart() + text.length - 1, 1, '\''),
|
||||
];
|
||||
this.addFailureAtNode(node, NoUnexternalizedStringsRuleWalker.ImportFailureMessage, fix);
|
||||
return;
|
||||
}
|
||||
var callInfo = info ? info.callInfo : null;
|
||||
@@ -101,8 +102,9 @@ var NoUnexternalizedStringsRuleWalker = /** @class */ (function (_super) {
|
||||
}
|
||||
if (doubleQuoted && (!callInfo || callInfo.argIndex === -1 || !this.signatures[functionName])) {
|
||||
var s = node.getText();
|
||||
var replacement = new Lint.Replacement(node.getStart(), node.getWidth(), "nls.localize('KEY-" + s.substring(1, s.length - 1) + "', " + s + ")");
|
||||
var fix = new Lint.Fix('Unexternalitzed string', [replacement]);
|
||||
var fix = [
|
||||
Lint.Replacement.replaceFromTo(node.getStart(), node.getWidth(), "nls.localize('KEY-" + s.substring(1, s.length - 1) + "', " + s + ")"),
|
||||
];
|
||||
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), "Unexternalized string found: " + node.getText(), fix));
|
||||
return;
|
||||
}
|
||||
@@ -134,16 +136,24 @@ var NoUnexternalizedStringsRuleWalker = /** @class */ (function (_super) {
|
||||
}
|
||||
}
|
||||
}
|
||||
var messageArg = callInfo.argIndex === this.messageIndex
|
||||
? callInfo.callExpression.arguments[this.messageIndex]
|
||||
: null;
|
||||
if (messageArg && messageArg !== node) {
|
||||
var messageArg = callInfo.callExpression.arguments[this.messageIndex];
|
||||
if (messageArg && messageArg.kind !== ts.SyntaxKind.StringLiteral) {
|
||||
this.addFailure(this.createFailure(messageArg.getStart(), messageArg.getWidth(), "Message argument to '" + callInfo.callExpression.expression.getText() + "' must be a string literal."));
|
||||
return;
|
||||
}
|
||||
};
|
||||
NoUnexternalizedStringsRuleWalker.prototype.recordKey = function (keyNode, messageNode) {
|
||||
var text = keyNode.getText();
|
||||
// We have an empty key
|
||||
if (text.match(/(['"]) *\1/)) {
|
||||
if (messageNode) {
|
||||
this.addFailureAtNode(keyNode, "Key is empty for message: " + messageNode.getText());
|
||||
}
|
||||
else {
|
||||
this.addFailureAtNode(keyNode, "Key is empty.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
var occurrences = this.usedKeys[text];
|
||||
if (!occurrences) {
|
||||
occurrences = [];
|
||||
@@ -176,7 +186,7 @@ var NoUnexternalizedStringsRuleWalker = /** @class */ (function (_super) {
|
||||
node = parent;
|
||||
}
|
||||
};
|
||||
NoUnexternalizedStringsRuleWalker.ImportFailureMessage = 'Do not use double qoutes for imports.';
|
||||
NoUnexternalizedStringsRuleWalker.ImportFailureMessage = 'Do not use double quotes for imports.';
|
||||
NoUnexternalizedStringsRuleWalker.DOUBLE_QUOTE = '"';
|
||||
return NoUnexternalizedStringsRuleWalker;
|
||||
}(Lint.RuleWalker));
|
||||
|
||||
@@ -45,7 +45,7 @@ interface KeyMessagePair {
|
||||
|
||||
class NoUnexternalizedStringsRuleWalker extends Lint.RuleWalker {
|
||||
|
||||
private static ImportFailureMessage = 'Do not use double qoutes for imports.';
|
||||
private static ImportFailureMessage = 'Do not use double quotes for imports.';
|
||||
|
||||
private static DOUBLE_QUOTE: string = '"';
|
||||
|
||||
@@ -104,13 +104,14 @@ class NoUnexternalizedStringsRuleWalker extends Lint.RuleWalker {
|
||||
let info = this.findDescribingParent(node);
|
||||
// Ignore strings in import and export nodes.
|
||||
if (info && info.isImport && doubleQuoted) {
|
||||
const fix = [
|
||||
Lint.Replacement.replaceFromTo(node.getStart(), 1, '\''),
|
||||
Lint.Replacement.replaceFromTo(node.getStart() + text.length - 1, 1, '\''),
|
||||
];
|
||||
this.addFailureAtNode(
|
||||
node,
|
||||
NoUnexternalizedStringsRuleWalker.ImportFailureMessage,
|
||||
new Lint.Fix(NoUnexternalizedStringsRuleWalker.ImportFailureMessage, [
|
||||
this.createReplacement(node.getStart(), 1, '\''),
|
||||
this.createReplacement(node.getStart() + text.length - 1, 1, '\''),
|
||||
])
|
||||
fix
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -122,8 +123,9 @@ class NoUnexternalizedStringsRuleWalker extends Lint.RuleWalker {
|
||||
|
||||
if (doubleQuoted && (!callInfo || callInfo.argIndex === -1 || !this.signatures[functionName])) {
|
||||
const s = node.getText();
|
||||
const replacement = new Lint.Replacement(node.getStart(), node.getWidth(), `nls.localize('KEY-${s.substring(1, s.length - 1)}', ${s})`);
|
||||
const fix = new Lint.Fix('Unexternalitzed string', [replacement]);
|
||||
const fix = [
|
||||
Lint.Replacement.replaceFromTo(node.getStart(), node.getWidth(), `nls.localize('KEY-${s.substring(1, s.length - 1)}', ${s})`),
|
||||
];
|
||||
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), `Unexternalized string found: ${node.getText()}`, fix));
|
||||
return;
|
||||
}
|
||||
@@ -154,10 +156,10 @@ class NoUnexternalizedStringsRuleWalker extends Lint.RuleWalker {
|
||||
}
|
||||
}
|
||||
}
|
||||
let messageArg: ts.Expression = callInfo.argIndex === this.messageIndex
|
||||
? callInfo.callExpression.arguments[this.messageIndex]
|
||||
: null;
|
||||
if (messageArg && messageArg !== node) {
|
||||
|
||||
const messageArg = callInfo.callExpression.arguments[this.messageIndex];
|
||||
|
||||
if (messageArg && messageArg.kind !== ts.SyntaxKind.StringLiteral) {
|
||||
this.addFailure(this.createFailure(
|
||||
messageArg.getStart(), messageArg.getWidth(),
|
||||
`Message argument to '${callInfo.callExpression.expression.getText()}' must be a string literal.`));
|
||||
@@ -167,6 +169,15 @@ class NoUnexternalizedStringsRuleWalker extends Lint.RuleWalker {
|
||||
|
||||
private recordKey(keyNode: ts.StringLiteral, messageNode: ts.Node) {
|
||||
let text = keyNode.getText();
|
||||
// We have an empty key
|
||||
if (text.match(/(['"]) *\1/)) {
|
||||
if (messageNode) {
|
||||
this.addFailureAtNode(keyNode, `Key is empty for message: ${messageNode.getText()}`);
|
||||
} else {
|
||||
this.addFailureAtNode(keyNode, `Key is empty.`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
let occurrences: KeyMessagePair[] = this.usedKeys[text];
|
||||
if (!occurrences) {
|
||||
occurrences = [];
|
||||
|
||||
1
build/lib/watch/.gitignore
vendored
Normal file
1
build/lib/watch/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.yarnrc
|
||||
1302
build/lib/watch/yarn.lock
Normal file
1302
build/lib/watch/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
1
build/monaco/LICENSE
Normal file
1
build/monaco/LICENSE
Normal file
@@ -0,0 +1 @@
|
||||
See project root directory
|
||||
@@ -52,7 +52,7 @@ declare module monaco.editor {
|
||||
#include(vs/editor/standalone/common/standaloneThemeService): BuiltinTheme, IStandaloneThemeData, IColors
|
||||
#include(vs/editor/common/modes/supports/tokenization): ITokenThemeRule
|
||||
#include(vs/editor/common/services/webWorker): MonacoWebWorker, IWebWorkerOptions
|
||||
#include(vs/editor/standalone/browser/standaloneCodeEditor): IEditorConstructionOptions, IDiffEditorConstructionOptions, IStandaloneCodeEditor, IStandaloneDiffEditor
|
||||
#include(vs/editor/standalone/browser/standaloneCodeEditor): IActionDescriptor, IEditorConstructionOptions, IDiffEditorConstructionOptions, IStandaloneCodeEditor, IStandaloneDiffEditor
|
||||
export interface ICommandHandler {
|
||||
(...args:any[]): void;
|
||||
}
|
||||
@@ -74,7 +74,7 @@ declare module monaco.languages {
|
||||
|
||||
#includeAll(vs/editor/standalone/browser/standaloneLanguages;modes.=>;editorCommon.=>editor.;IMarkerData=>editor.IMarkerData):
|
||||
#includeAll(vs/editor/common/modes/languageConfiguration):
|
||||
#includeAll(vs/editor/common/modes;editorCommon.IRange=>IRange;editorCommon.IPosition=>IPosition;editorCommon.=>editor.):
|
||||
#includeAll(vs/editor/common/modes;editorCommon.IRange=>IRange;editorCommon.IPosition=>IPosition;editorCommon.=>editor.;IMarkerData=>editor.IMarkerData):
|
||||
#include(vs/editor/common/services/modeService): ILanguageExtensionPoint
|
||||
#includeAll(vs/editor/standalone/common/monarch/monarchTypes):
|
||||
|
||||
|
||||
@@ -11,47 +11,5 @@
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/Microsoft/vscode/issues"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/minimist": "1.2.0",
|
||||
"@types/mocha": "2.2.39",
|
||||
"@types/semver": "5.3.30",
|
||||
"@types/sinon": "1.16.34",
|
||||
"debounce": "^1.0.0",
|
||||
"eslint": "^3.4.0",
|
||||
"event-stream": "^3.1.7",
|
||||
"ghooks": "1.0.3",
|
||||
"glob": "^5.0.13",
|
||||
"gulp": "^3.8.9",
|
||||
"gulp-bom": "^1.0.0",
|
||||
"gulp-concat": "^2.6.0",
|
||||
"gulp-cssnano": "^2.1.0",
|
||||
"gulp-filter": "^3.0.0",
|
||||
"gulp-flatmap": "^1.0.0",
|
||||
"gulp-rename": "^1.2.0",
|
||||
"gulp-sourcemaps": "^1.11.0",
|
||||
"gulp-tsb": "^2.0.3",
|
||||
"gulp-tslint": "^7.0.1",
|
||||
"gulp-uglify": "^2.0.0",
|
||||
"gulp-util": "^3.0.6",
|
||||
"gulp-watch": "^4.3.9",
|
||||
"is": "^3.1.0",
|
||||
"istanbul": "^0.3.17",
|
||||
"jsdom-no-contextify": "^3.1.0",
|
||||
"lazy.js": "^0.4.2",
|
||||
"minimatch": "^2.0.10",
|
||||
"mocha": "^2.2.5",
|
||||
"object-assign": "^4.0.1",
|
||||
"pump": "^1.0.1",
|
||||
"remap-istanbul": "^0.6.4",
|
||||
"rimraf": "^2.2.8",
|
||||
"sinon": "^1.17.2",
|
||||
"source-map": "^0.4.4",
|
||||
"tslint": "^4.3.1",
|
||||
"typescript": "2.5.2",
|
||||
"typescript-formatter": "4.0.1",
|
||||
"underscore": "^1.8.2",
|
||||
"vinyl": "^0.4.5",
|
||||
"vscode-nls-dev": "^2.0.1"
|
||||
}
|
||||
}
|
||||
|
||||
4668
build/monaco/yarn.lock
Normal file
4668
build/monaco/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
@@ -5,14 +5,15 @@
|
||||
|
||||
const cp = require('child_process');
|
||||
const path = require('path');
|
||||
const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
||||
const fs = require('fs');
|
||||
const yarn = process.platform === 'win32' ? 'yarn.cmd' : 'yarn';
|
||||
|
||||
function npmInstall(location, opts) {
|
||||
function yarnInstall(location, opts) {
|
||||
opts = opts || {};
|
||||
opts.cwd = location;
|
||||
opts.stdio = 'inherit';
|
||||
|
||||
const result = cp.spawnSync(npm, ['install'], opts);
|
||||
const result = cp.spawnSync(yarn, ['install'], opts);
|
||||
|
||||
if (result.error || result.status !== 0) {
|
||||
process.exit(1);
|
||||
@@ -20,44 +21,43 @@ function npmInstall(location, opts) {
|
||||
}
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
const protocol = [
|
||||
'jsonrpc',
|
||||
'types',
|
||||
'client'
|
||||
];
|
||||
|
||||
protocol.forEach(item => npmInstall(`dataprotocol-node/${item}`));
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
npmInstall('extensions-modules');
|
||||
npmInstall('extensions'); // node modules shared by all extensions
|
||||
yarnInstall('extensions-modules');
|
||||
yarnInstall('extensions'); // node modules shared by all extensions
|
||||
|
||||
const extensions = [
|
||||
'vscode-colorize-tests',
|
||||
'git',
|
||||
'json',
|
||||
'mssql',
|
||||
'mssql',
|
||||
'configuration-editing',
|
||||
'extension-editing',
|
||||
'markdown',
|
||||
'git',
|
||||
'merge-conflict',
|
||||
'insights-default',
|
||||
'account-provider-azure'
|
||||
'account-provider-azure',
|
||||
'agent'
|
||||
];
|
||||
|
||||
extensions.forEach(extension => npmInstall(`extensions/${extension}`));
|
||||
extensions.forEach(extension => yarnInstall(`extensions/${extension}`));
|
||||
|
||||
function npmInstallBuildDependencies() {
|
||||
// make sure we install gulp watch for the system installed
|
||||
function yarnInstallBuildDependencies() {
|
||||
// make sure we install the deps of build/lib/watch for the system installed
|
||||
// node, since that is the driver of gulp
|
||||
const env = Object.assign({}, process.env);
|
||||
const watchPath = path.join(path.dirname(__dirname), 'lib', 'watch');
|
||||
const yarnrcPath = path.join(watchPath, '.yarnrc');
|
||||
|
||||
delete env['npm_config_disturl'];
|
||||
delete env['npm_config_target'];
|
||||
delete env['npm_config_runtime'];
|
||||
const disturl = 'https://nodejs.org/download/release';
|
||||
const target = process.versions.node;
|
||||
const runtime = 'node';
|
||||
|
||||
npmInstall(path.join(path.dirname(__dirname), 'lib', 'watch'), { env });
|
||||
const yarnrc = `disturl "${disturl}"
|
||||
target "${target}"
|
||||
runtime "${runtime}"`;
|
||||
|
||||
fs.writeFileSync(yarnrcPath, yarnrc, 'utf8');
|
||||
yarnInstall(watchPath, { env });
|
||||
}
|
||||
|
||||
npmInstall(`build`); // node modules required for build
|
||||
npmInstallBuildDependencies(); // node modules for watching, specific to host node version, not electron
|
||||
yarnInstall(`build`); // node modules required for build
|
||||
yarnInstallBuildDependencies(); // node modules for watching, specific to host node version, not electron
|
||||
@@ -3,13 +3,21 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
if (process.env['npm_config_disturl'] !== 'https://atom.io/download/electron') {
|
||||
console.error("You can't use plain npm to install Code's dependencies.");
|
||||
console.error(
|
||||
/^win/.test(process.platform)
|
||||
? "Please run '.\\scripts\\npm.bat install' instead."
|
||||
: "Please run './scripts/npm.sh install' instead."
|
||||
);
|
||||
let err = false;
|
||||
|
||||
const major = parseInt(/^(\d+)\./.exec(process.versions.node)[1]);
|
||||
|
||||
if (major < 8) {
|
||||
console.error('\033[1;31m*** Please use node>=8.\033[0;0m');
|
||||
err = true;
|
||||
}
|
||||
|
||||
if (!/yarn\.js$|yarnpkg$/.test(process.env['npm_execpath'])) {
|
||||
console.error('\033[1;31m*** Please use yarn to install dependencies.\033[0;0m');
|
||||
err = true;
|
||||
}
|
||||
|
||||
if (err) {
|
||||
console.error('');
|
||||
process.exit(1);
|
||||
}
|
||||
@@ -18,7 +18,7 @@ function updateGrammar(location) {
|
||||
}
|
||||
|
||||
const extensions = [
|
||||
// 'bat' Grammar no longer available
|
||||
'bat',
|
||||
'clojure',
|
||||
'coffeescript',
|
||||
'cpp',
|
||||
|
||||
@@ -11,13 +11,13 @@
|
||||
"@types/xml2js": "0.0.33",
|
||||
"azure-storage": "^2.1.0",
|
||||
"decompress": "^4.2.0",
|
||||
"documentdb": "^1.11.0",
|
||||
"documentdb": "1.13.0",
|
||||
"extensions-modules": "file:../extensions-modules",
|
||||
"fs-extra-promise": "^1.0.1",
|
||||
"mime": "^1.3.4",
|
||||
"minimist": "^1.2.0",
|
||||
"typescript": "2.5.2",
|
||||
"vscode": "^1.0.1",
|
||||
"typescript": "2.6.1",
|
||||
"vscode": "^1.0.1",
|
||||
"xml2js": "^0.4.17"
|
||||
},
|
||||
"scripts": {
|
||||
@@ -25,4 +25,4 @@
|
||||
"watch": "tsc --watch",
|
||||
"postinstall": "npm run compile"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,9 @@ if [ -n "$AGENT_WORKFOLDER" ]
|
||||
then
|
||||
export npm_config_cache="$AGENT_WORKFOLDER/npm-cache"
|
||||
echo "Using npm cache: $npm_config_cache"
|
||||
|
||||
export YARN_CACHE_FOLDER="$AGENT_WORKFOLDER/yarn-cache"
|
||||
echo "Using yarn cache: $YARN_CACHE_FOLDER"
|
||||
fi
|
||||
|
||||
SUMMARY="Task;Duration"$'\n'
|
||||
|
||||
@@ -4,23 +4,15 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
const cp = require('child_process');
|
||||
const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
||||
|
||||
function npmInstall(package: string, args: string[]): void {
|
||||
const result = cp.spawnSync(npm, ['install', package, ...args], {
|
||||
stdio: 'inherit'
|
||||
});
|
||||
|
||||
if (result.error || result.status !== 0) {
|
||||
process.exit(1);
|
||||
}
|
||||
function yarnInstall(package: string): void {
|
||||
cp.execSync(`yarn add --no-lockfile ${package}`);
|
||||
}
|
||||
|
||||
const product = require('../../../product.json');
|
||||
const dependencies = product.dependencies || {} as { [name: string]: string; };
|
||||
const [, , ...args] = process.argv;
|
||||
|
||||
Object.keys(dependencies).forEach(name => {
|
||||
const url = dependencies[name];
|
||||
npmInstall(url, args);
|
||||
yarnInstall(url);
|
||||
});
|
||||
@@ -10,6 +10,9 @@ else
|
||||
fi
|
||||
|
||||
# install node
|
||||
NODE_VERSION=7.10.0
|
||||
NODE_VERSION=8.9.1
|
||||
nvm install $NODE_VERSION
|
||||
nvm use $NODE_VERSION
|
||||
nvm use $NODE_VERSION
|
||||
|
||||
# install yarn
|
||||
npm i -g yarn
|
||||
@@ -14,8 +14,9 @@ import * as mime from 'mime';
|
||||
import * as minimist from 'minimist';
|
||||
import { DocumentClient, NewDocument } from 'documentdb';
|
||||
|
||||
if (process.argv.length < 6) {
|
||||
console.error('Usage: node publish.js <product> <platform> <type> <name> <version> <commit> <is_update> <file>');
|
||||
// {{SQL CARBON EDIT}}
|
||||
if (process.argv.length < 9) {
|
||||
console.error('Usage: node publish.js <product_quality> <platform> <file_type> <file_name> <version> <is_update> <file> [commit_id]');
|
||||
process.exit(-1);
|
||||
}
|
||||
|
||||
@@ -183,21 +184,10 @@ async function publish(commit: string, quality: string, platform: string, type:
|
||||
const blobService = azure.createBlobService(storageAccount, process.env['AZURE_STORAGE_ACCESS_KEY_2'])
|
||||
.withFilter(new azure.ExponentialRetryPolicyFilter(20));
|
||||
|
||||
const mooncakeBlobService = azure.createBlobService(storageAccount, process.env['MOONCAKE_STORAGE_ACCESS_KEY'], `${storageAccount}.blob.core.chinacloudapi.cn`)
|
||||
.withFilter(new azure.ExponentialRetryPolicyFilter(20));
|
||||
// {{SQL CARBON EDIT}}
|
||||
await assertContainer(blobService, quality);
|
||||
|
||||
// mooncake is fussy and far away, this is needed!
|
||||
mooncakeBlobService.defaultClientRequestTimeoutInMs = 10 * 60 * 1000;
|
||||
|
||||
await Promise.all([
|
||||
assertContainer(blobService, quality),
|
||||
assertContainer(mooncakeBlobService, quality)
|
||||
]);
|
||||
|
||||
const [blobExists, moooncakeBlobExists] = await Promise.all([
|
||||
doesAssetExist(blobService, quality, blobName),
|
||||
doesAssetExist(mooncakeBlobService, quality, blobName)
|
||||
]);
|
||||
const blobExists = await doesAssetExist(blobService, quality, blobName);
|
||||
|
||||
const promises = [];
|
||||
|
||||
@@ -205,8 +195,23 @@ async function publish(commit: string, quality: string, platform: string, type:
|
||||
promises.push(uploadBlob(blobService, quality, blobName, file));
|
||||
}
|
||||
|
||||
if (!moooncakeBlobExists) {
|
||||
promises.push(uploadBlob(mooncakeBlobService, quality, blobName, file));
|
||||
// {{SQL CARBON EDIT}}
|
||||
if (process.env['MOONCAKE_STORAGE_ACCESS_KEY']) {
|
||||
const mooncakeBlobService = azure.createBlobService(storageAccount, process.env['MOONCAKE_STORAGE_ACCESS_KEY'], `${storageAccount}.blob.core.chinacloudapi.cn`)
|
||||
.withFilter(new azure.ExponentialRetryPolicyFilter(20));
|
||||
|
||||
// mooncake is fussy and far away, this is needed!
|
||||
mooncakeBlobService.defaultClientRequestTimeoutInMs = 10 * 60 * 1000;
|
||||
|
||||
await assertContainer(mooncakeBlobService, quality);
|
||||
|
||||
const mooncakeBlobExists = await doesAssetExist(mooncakeBlobService, quality, blobName);
|
||||
|
||||
if (!mooncakeBlobExists) {
|
||||
promises.push(uploadBlob(mooncakeBlobService, quality, blobName, file));
|
||||
}
|
||||
} else {
|
||||
console.log('Skipping Mooncake publishing.');
|
||||
}
|
||||
|
||||
if (promises.length === 0) {
|
||||
@@ -228,7 +233,8 @@ async function publish(commit: string, quality: string, platform: string, type:
|
||||
platform: platform,
|
||||
type: type,
|
||||
url: `${process.env['AZURE_CDN_URL']}/${quality}/${blobName}`,
|
||||
mooncakeUrl: `${process.env['MOONCAKE_CDN_URL']}/${quality}/${blobName}`,
|
||||
// {{SQL CARBON EDIT}}
|
||||
mooncakeUrl: process.env['MOONCAKE_CDN_URL'] ? `${process.env['MOONCAKE_CDN_URL']}/${quality}/${blobName}` : undefined,
|
||||
hash: sha1hash,
|
||||
sha256hash,
|
||||
size
|
||||
@@ -261,8 +267,11 @@ function main(): void {
|
||||
boolean: ['upload-only']
|
||||
});
|
||||
|
||||
const [quality, platform, type, name, version, _isUpdate, file] = opts._;
|
||||
const commit = execSync('git rev-parse HEAD', { encoding: 'utf8' }).trim();
|
||||
// {{SQL CARBON EDIT}}
|
||||
let [quality, platform, type, name, version, _isUpdate, file, commit] = opts._;
|
||||
if (!commit) {
|
||||
commit = execSync('git rev-parse HEAD', { encoding: 'utf8' }).trim();
|
||||
}
|
||||
|
||||
publish(commit, quality, platform, type, name, version, _isUpdate, file, opts).catch(err => {
|
||||
console.error(err);
|
||||
|
||||
@@ -14,7 +14,7 @@ VSO_PAT="$6"
|
||||
echo "machine monacotools.visualstudio.com password $VSO_PAT" > ~/.netrc
|
||||
|
||||
step "Install dependencies" \
|
||||
npm install
|
||||
yarn
|
||||
|
||||
step "Hygiene" \
|
||||
npm run gulp -- hygiene
|
||||
|
||||
@@ -3,10 +3,6 @@
|
||||
. ./scripts/env.sh
|
||||
. ./build/tfs/common/common.sh
|
||||
|
||||
(cd $BUILD_SOURCESDIRECTORY/build/tfs/common && \
|
||||
step "Install build dependencies" \
|
||||
npm i)
|
||||
|
||||
REPO=`pwd`
|
||||
ZIP=$REPO/../VSCode-darwin-selfsigned.zip
|
||||
UNSIGNEDZIP=$REPO/../VSCode-darwin-unsigned.zip
|
||||
|
||||
3
build/tfs/linux/.gitignore
vendored
3
build/tfs/linux/.gitignore
vendored
@@ -1 +1,2 @@
|
||||
pat
|
||||
pat
|
||||
*.js
|
||||
@@ -5,6 +5,7 @@
|
||||
. ./build/tfs/common/common.sh
|
||||
|
||||
export ARCH="$1"
|
||||
export npm_config_arch="$ARCH"
|
||||
export VSCODE_MIXIN_PASSWORD="$2"
|
||||
export AZURE_STORAGE_ACCESS_KEY="$3"
|
||||
export AZURE_STORAGE_ACCESS_KEY_2="$4"
|
||||
@@ -16,7 +17,7 @@ VSO_PAT="$8"
|
||||
echo "machine monacotools.visualstudio.com password $VSO_PAT" > ~/.netrc
|
||||
|
||||
step "Install dependencies" \
|
||||
npm install --arch=$ARCH --unsafe-perm
|
||||
yarn
|
||||
|
||||
step "Hygiene" \
|
||||
npm run gulp -- hygiene
|
||||
@@ -28,7 +29,7 @@ step "Get Electron" \
|
||||
npm run gulp -- "electron-$ARCH"
|
||||
|
||||
step "Install distro dependencies" \
|
||||
node build/tfs/common/installDistro.js --arch=$ARCH
|
||||
node build/tfs/common/installDistro.js
|
||||
|
||||
step "Build minified" \
|
||||
npm run gulp -- "vscode-linux-$ARCH-min"
|
||||
|
||||
42
build/tfs/linux/frozen-check.ts
Normal file
42
build/tfs/linux/frozen-check.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 { DocumentClient } from 'documentdb';
|
||||
|
||||
interface Config {
|
||||
id: string;
|
||||
frozen: boolean;
|
||||
}
|
||||
|
||||
function createDefaultConfig(quality: string): Config {
|
||||
return {
|
||||
id: quality,
|
||||
frozen: false
|
||||
};
|
||||
}
|
||||
|
||||
function getConfig(quality: string): Promise<Config> {
|
||||
const client = new DocumentClient(process.env['AZURE_DOCUMENTDB_ENDPOINT'], { masterKey: process.env['AZURE_DOCUMENTDB_MASTERKEY'] });
|
||||
const collection = 'dbs/builds/colls/config';
|
||||
const query = {
|
||||
query: `SELECT TOP 1 * FROM c WHERE c.id = @quality`,
|
||||
parameters: [
|
||||
{ name: '@quality', value: quality }
|
||||
]
|
||||
};
|
||||
|
||||
return new Promise<Config>((c, e) => {
|
||||
client.queryDocuments(collection, query).toArray((err, results) => {
|
||||
if (err && err.code !== 409) { return e(err); }
|
||||
|
||||
c(!results || results.length === 0 ? createDefaultConfig(quality) : results[0] as any as Config);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getConfig(process.argv[2])
|
||||
.then(c => console.log(c.frozen), e => console.error(e));
|
||||
6
build/tfs/linux/new_package.json.template
Normal file
6
build/tfs/linux/new_package.json.template
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "PACKAGENAME",
|
||||
"version": "PACKAGEVERSION",
|
||||
"repositoryId": "REPOSITORYID",
|
||||
"sourceUrl": "PACKAGEURL"
|
||||
}
|
||||
@@ -12,10 +12,6 @@ step "Build RPM package" \
|
||||
# step "Build snap package" \
|
||||
# npm run gulp -- "vscode-linux-$ARCH-build-snap"
|
||||
|
||||
(cd $BUILD_SOURCESDIRECTORY/build/tfs/common && \
|
||||
step "Install build dependencies" \
|
||||
npm install --unsafe-perm)
|
||||
|
||||
# Variables
|
||||
PLATFORM_LINUX="linux-$ARCH"
|
||||
PLATFORM_DEB="linux-deb-$ARCH"
|
||||
@@ -55,36 +51,29 @@ step "Publish RPM package" \
|
||||
# SNAP_FILENAME="$(ls $REPO/.build/linux/snap/$ARCH/ | grep .snap)"
|
||||
# SNAP_PATH="$REPO/.build/linux/snap/$ARCH/$SNAP_FILENAME"
|
||||
|
||||
IS_FROZEN="$(node build/tfs/linux/frozen-check.js $VSCODE_QUALITY)"
|
||||
|
||||
if [ -z "$VSCODE_QUALITY" ]; then
|
||||
echo "VSCODE_QUALITY is not set, skipping repo package publish"
|
||||
elif [ "$IS_FROZEN" = "true" ]; then
|
||||
echo "$VSCODE_QUALITY is frozen, skipping repo package publish"
|
||||
else
|
||||
if [ "$BUILD_SOURCEBRANCH" = "master" ] || [ "$BUILD_SOURCEBRANCH" = "refs/heads/master" ]; then
|
||||
if [[ $BUILD_QUEUEDBY = *"Project Collection Service Accounts"* || $BUILD_QUEUEDBY = *"Microsoft.VisualStudio.Services.TFS"* ]]; then
|
||||
# Get necessary information
|
||||
pushd $REPO && COMMIT_HASH=$(git rev-parse HEAD) && popd
|
||||
PACKAGE_NAME="$(ls $REPO/.build/linux/deb/$DEB_ARCH/deb/ | sed -e 's/_.*//g')"
|
||||
DEB_URL="https://az764295.vo.msecnd.net/$VSCODE_QUALITY/$COMMIT_HASH/$DEB_FILENAME"
|
||||
RPM_URL="https://az764295.vo.msecnd.net/$VSCODE_QUALITY/$COMMIT_HASH/$RPM_FILENAME"
|
||||
PACKAGE_VERSION="$(ls $REPO/.build/linux/deb/$DEB_ARCH/deb/ | sed -e 's/code-[a-z]*_//g' -e 's/\_.*$//g')"
|
||||
# Write config files needed by API, use eval to force environment variable expansion
|
||||
DIRNAME=$(dirname $(readlink -f $0))
|
||||
pushd $DIRNAME
|
||||
# Submit to apt repo
|
||||
if [ "$DEB_ARCH" = "amd64" ]; then
|
||||
eval echo '{ \"server\": \"azure-apt-cat.cloudapp.net\", \"protocol\": \"https\", \"port\": \"443\", \"repositoryId\": \"58a4adf642421134a1a48d1a\", \"username\": \"$LINUX_REPO_USERNAME\", \"password\": \"$LINUX_REPO_PASSWORD\" }' > apt-config.json
|
||||
eval echo '{ \"name\": \"$PACKAGE_NAME\", \"version\": \"$PACKAGE_VERSION\", \"repositoryId\": \"58a4adf642421134a1a48d1a\", \"sourceUrl\": \"$DEB_URL\" }' > apt-addpkg.json
|
||||
echo "Submitting apt-addpkg.json:"
|
||||
cat apt-addpkg.json
|
||||
|
||||
step "Publish to repositories" \
|
||||
./repoapi_client.sh -config apt-config.json -addpkg apt-addpkg.json
|
||||
./repoapi_client.sh -config apt-config.json -addfile $DEB_PATH
|
||||
fi
|
||||
# Submit to yum repo (disabled as it's manual until signing is automated)
|
||||
# eval echo '{ \"server\": \"azure-apt-cat.cloudapp.net\", \"protocol\": \"https\", \"port\": \"443\", \"repositoryId\": \"58a4ae3542421134a1a48d1b\", \"username\": \"$LINUX_REPO_USERNAME\", \"password\": \"$LINUX_REPO_PASSWORD\" }' > yum-config.json
|
||||
# eval echo '{ \"name\": \"$PACKAGE_NAME\", \"version\": \"$PACKAGE_VERSION\", \"repositoryId\": \"58a4ae3542421134a1a48d1b\", \"sourceUrl\": \"$RPM_URL\" }' > yum-addpkg.json
|
||||
# echo "Submitting yum-addpkg.json:"
|
||||
# cat yum-addpkg.json
|
||||
# ./repoapi_client.sh -config yum-config.json -addpkg yum-addpkg.json
|
||||
|
||||
# ./repoapi_client.sh -config yum-config.json -addfile $RPM_PATH
|
||||
popd
|
||||
echo "To check repo publish status run ./repoapi_client.sh -config config.json -check <id>"
|
||||
fi
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
# This is a VERY basic script for Create/Delete operations on repos and packages
|
||||
#
|
||||
cmd=$1
|
||||
urls=urls.txt
|
||||
defaultPackageFile=new_package.json
|
||||
defaultRepoFile=new_repo.json
|
||||
docDir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" # chrmarti: Changed to script's directory.
|
||||
packageJsonTemplate=$docDir/new_package.json.template
|
||||
repoJsonTemplate=$docDir/new_repo.json.template
|
||||
|
||||
function Bail
|
||||
{
|
||||
@@ -24,14 +24,21 @@ function Usage {
|
||||
echo "$0 -config FILENAME -listrepos | -listpkgs | -addrepo FILENAME | -addpkg FILENAME |"
|
||||
echo "-addpkgs FILENAME | -check ID | -delrepo REPOID | -delpkg PKGID"
|
||||
echo -e "\t-config FILENAME : JSON file containing API server name and creds"
|
||||
echo -e "\t-listrepos : List repositories"
|
||||
echo -e "Package Operations:"
|
||||
echo -e "\t-listpkgs [REGEX] : List packages, optionally filter by REGEX"
|
||||
echo -e "\t-addrepo FILENAME : Create a new repo using the specified JSON file"
|
||||
echo -e "\t-addpkg FILENAME : Add package to repo using the specified JSON file"
|
||||
echo -e "\t-addpkgs FILENAME : Add packages to repo using urls contained in FILENAME"
|
||||
echo -e "\t-check ID : Check upload operation by ID"
|
||||
echo -e "\t-delrepo REPOID : Delete the specified repo by ID"
|
||||
echo -e "\t-delpkg PKGID : Delete the specified package by ID"
|
||||
echo -e "File Operations:"
|
||||
echo -e "\t-uploadfile FILENAME: Upload FILENAME (does not publish) "
|
||||
echo -e "\t-addfile FILENAME : Upload FILENAME AND publish to the repo"
|
||||
echo -e "\t-listfiles : List uploaded files"
|
||||
echo -e "\t-delfile FILEID : Delete uploaded file by ID"
|
||||
echo -e "Repository Operations:"
|
||||
echo -e "\t-listrepos : List repositories"
|
||||
echo -e "\t-addrepo FILENAME : Create a new repo using the specified JSON file"
|
||||
echo -e "\t-delrepo REPOID : Delete the specified repo by ID"
|
||||
exit 1
|
||||
}
|
||||
|
||||
@@ -84,33 +91,136 @@ function AddRepo
|
||||
{
|
||||
repoFile=$1
|
||||
if [ -z $repoFile ]; then
|
||||
Bail "Error: Must specify a JSON-formatted file. Reference $defaultRepoFile.template"
|
||||
Bail "Error: Must specify a JSON-formatted file. Reference $repoJsonTemplate"
|
||||
fi
|
||||
if [ ! -f $repoFile ]; then
|
||||
Bail "Error: Cannot create repo - $repoFile does not exist"
|
||||
fi
|
||||
packageUrl=$(grep "url" $repoFile | head -n 1 | awk '{print $2}' | tr -d ',')
|
||||
echo "Creating new repo on $server [$packageUrl]"
|
||||
curl -i -k "$baseurl/v1/repositories" --data @./$repoFile -H "Content-Type: application/json"
|
||||
curl -i -k "$baseurl/v1/repositories" --data @$repoFile -H "Content-Type: application/json"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Upload AND publish the file
|
||||
function AddFile
|
||||
{
|
||||
packageFile=$1
|
||||
# Validity checks are performed by UploadFile
|
||||
echo "Uploading package to $server [$packageFile]"
|
||||
response=$(UploadFile $packageFile "true")
|
||||
id=$(echo $response | jq -r ".id")
|
||||
|
||||
# Parse package metadata first to confirm it's a valid deb/rpm
|
||||
# Needs to be performed in this function so we can use it to publish the package
|
||||
jsonFile=$(WritePackageInfoToFile $packageFile)
|
||||
|
||||
sed -i "s/REPOSITORYID/$repositoryId/g" $jsonFile
|
||||
# Replace the url field with fileId
|
||||
sed -i "s/PACKAGEURL/$id/g" $jsonFile
|
||||
sed -i "s/sourceUrl/fileId/g" $jsonFile
|
||||
|
||||
AddPackage $jsonFile
|
||||
rm -f $jsonFile
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Upload a file
|
||||
function UploadFile
|
||||
{
|
||||
packageFile=$1
|
||||
quick=$2
|
||||
if [ -z $packageFile ]; then
|
||||
Bail "Error: Must specify the path to a file to upload "
|
||||
fi
|
||||
if [ ! -f $packageFile ]; then
|
||||
Bail "Error: Cannot upload - $packageFile does not exist"
|
||||
fi
|
||||
|
||||
# Additional validation and output if quick mode isn't enabled
|
||||
# Basically, if this is part of a publish operation, these steps are handled elsewhere
|
||||
if [ "$quick" != "true" ]; then
|
||||
# Parse package metadata first to confirm it's a valid deb/rpm
|
||||
jsonFile=$(WritePackageInfoToFile $packageFile)
|
||||
rm -f $jsonFile
|
||||
|
||||
echo "Uploading package to $server [$packageFile]"
|
||||
fi
|
||||
curl -s -k -X POST -F file=@$packageFile "$baseurl/v1/files"
|
||||
echo ""
|
||||
}
|
||||
|
||||
function ListFiles
|
||||
{
|
||||
curl -s -k "$baseurl/v1/files" | jq
|
||||
}
|
||||
|
||||
function DeleteFile
|
||||
{
|
||||
fileId=$1
|
||||
if [ -z "$fileId" ]; then
|
||||
Bail "Error: Must specify an ID to delete"
|
||||
fi
|
||||
curl -s -X DELETE "$baseurl/v1/files/$fileId"
|
||||
}
|
||||
|
||||
# Upload a single package using the specified JSON file
|
||||
function AddPackage
|
||||
{
|
||||
packageFile=$1
|
||||
if [ -z $packageFile ]; then
|
||||
Bail "Error: Must specify a JSON-formatted file. Reference $defaultPackageFile.template"
|
||||
Bail "Error: Must specify a JSON-formatted file. Reference $packageJsonTemplate"
|
||||
fi
|
||||
if [ ! -f $packageFile ]; then
|
||||
Bail "Error: Cannot add package - $packageFile does not exist"
|
||||
fi
|
||||
packageUrl=$(grep "sourceUrl" $packageFile | head -n 1 | awk '{print $2}')
|
||||
echo "Adding package to $server [$packageUrl]"
|
||||
curl -i -k "$baseurl/v1/packages" --data @./$packageFile -H "Content-Type: application/json"
|
||||
curl -i -k "$baseurl/v1/packages" --data @$packageFile -H "Content-Type: application/json"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Gets the package name and version and writes it to a file
|
||||
function WritePackageInfoToFile
|
||||
{
|
||||
packageFile=$1
|
||||
tmpOut=$(mktemp)
|
||||
if [ -z "$packageFile" ]; then
|
||||
Bail "Error: Must specify path to a deb/rpm package"
|
||||
elif [ ! -f "$packageFile" ]; then
|
||||
Bail "Error: Specified file $packageFile does not exist"
|
||||
fi
|
||||
if dpkg -I $packageFile > $tmpOut 2> /dev/null; then
|
||||
>&2 echo "File is deb format"
|
||||
pkgName=$(grep "^\s*Package:" $tmpOut | awk '{print $2}')
|
||||
pkgVer=$(grep "^\s*Version:" $tmpOut | awk '{print $2}')
|
||||
elif rpm -qpi $packageFile > $tmpOut 2> /dev/null; then
|
||||
>&2 echo "File is rpm format"
|
||||
pkgName=$(egrep "^Name" $tmpOut | tr -d ':' | awk '{print $2}')
|
||||
pkgVer=$(egrep "^Version" $tmpOut | tr -d ':' | awk '{print $2}')
|
||||
else
|
||||
rm -f $tmpOut
|
||||
Bail "File is not a valid deb/rpm package $url"
|
||||
fi
|
||||
|
||||
rm -f $tmpOut
|
||||
if [ -z "$pkgName" ]; then
|
||||
Bail "Unable to parse package name for $url"
|
||||
elif [ -z "$pkgVer" ]; then
|
||||
Bail "Unable to parse package version number for $url"
|
||||
fi
|
||||
|
||||
# Create Package .json file
|
||||
outJson=$(mktemp)
|
||||
escapedUrl=$(echo "$url" | sed 's/\//\\\//g' | sed 's/\&/\\\&/g')
|
||||
cp $packageJsonTemplate $outJson
|
||||
sed -i "s/PACKAGENAME/$pkgName/g" $outJson
|
||||
sed -i "s/PACKAGEVERSION/$pkgVer/g" $outJson
|
||||
|
||||
# Return path to json file
|
||||
echo $outJson
|
||||
}
|
||||
|
||||
# Upload a single package by dynamically creating a JSON file using a provided URL
|
||||
function AddPackageByUrl
|
||||
{
|
||||
@@ -119,41 +229,20 @@ function AddPackageByUrl
|
||||
Bail "Unable to publish package because no URL was specified"
|
||||
fi
|
||||
tmpFile=$(mktemp)
|
||||
tmpOut=$(mktemp)
|
||||
if ! wget -q "$url" -O $tmpFile; then
|
||||
rm -f $tmpFile $tmpFile
|
||||
rm -f $tmpFile
|
||||
Bail "Unable to download URL $url"
|
||||
elif dpkg -I $tmpFile > $tmpOut 2> /dev/null; then
|
||||
echo "File is deb format"
|
||||
pkgName=$(grep "^\s*Package:" $tmpOut | awk '{print $2}')
|
||||
pkgVer=$(grep "^\s*Version:" $tmpOut | awk '{print $2}')
|
||||
elif rpm -qpi $tmpFile > $tmpOut 2> /dev/null; then
|
||||
echo "File is rpm format"
|
||||
pkgName=$(egrep "^Name" $tmpOut | tr -d ':' | awk '{print $2}')
|
||||
pkgVer=$(egrep "^Version" $tmpOut | tr -d ':' | awk '{print $2}')
|
||||
else
|
||||
rm -f $tmpFile $tmpOut
|
||||
Bail "File is not a valid deb/rpm package $url"
|
||||
fi
|
||||
|
||||
rm -f $tmpFile $tmpOut
|
||||
if [ -z "$pkgName" ]; then
|
||||
Bail "Unable to parse package name for $url"
|
||||
elif [ -z "$pkgVer" ]; then
|
||||
Bail "Unable to parse package version number for $url"
|
||||
fi
|
||||
|
||||
jsonFile=$(WritePackageInfoToFile $tmpFile)
|
||||
# Create Package .json file
|
||||
escapedUrl=$(echo "$url" | sed 's/\//\\\//g' | sed 's/\&/\\\&/g')
|
||||
cp $defaultPackageFile.template $defaultPackageFile
|
||||
sed -i "s/PACKAGENAME/$pkgName/g" $defaultPackageFile
|
||||
sed -i "s/PACKAGEVERSION/$pkgVer/g" $defaultPackageFile
|
||||
sed -i "s/PACKAGEURL/$escapedUrl/g" $defaultPackageFile
|
||||
sed -i "s/REPOSITORYID/$repositoryId/g" $defaultPackageFile
|
||||
sed -i "s/PACKAGEURL/$escapedUrl/g" $jsonFile
|
||||
sed -i "s/REPOSITORYID/$repositoryId/g" $jsonFile
|
||||
# Perform Upload
|
||||
AddPackage $defaultPackageFile
|
||||
AddPackage $jsonFile
|
||||
# Cleanup
|
||||
rm -f $defaultPackageFile
|
||||
rm -f $jsonFile
|
||||
}
|
||||
|
||||
# Upload multiple packages by reading urls line-by-line from the specified file
|
||||
@@ -180,7 +269,7 @@ function CheckUpload {
|
||||
if [ -z "$id" ]; then
|
||||
Bail "Must specify an ID"
|
||||
fi
|
||||
curl -k $baseurl/v1/packages/queue/$id
|
||||
curl -s -k $baseurl/v1/packages/queue/$id | jq
|
||||
echo ""
|
||||
}
|
||||
|
||||
@@ -232,6 +321,20 @@ while (( "$#" )); do
|
||||
operation=AddPackages
|
||||
shift
|
||||
operand="$1"
|
||||
elif [[ "$1" == "-addfile" ]]; then
|
||||
operation=AddFile
|
||||
shift
|
||||
operand="$1"
|
||||
elif [[ "$1" == "-uploadfile" ]]; then
|
||||
operation=UploadFile
|
||||
shift
|
||||
operand="$1"
|
||||
elif [[ "$1" == "-listfiles" ]]; then
|
||||
operation=ListFiles
|
||||
elif [[ "$1" == "-delfile" ]]; then
|
||||
operation=DeleteFile
|
||||
shift
|
||||
operand="$1"
|
||||
elif [[ "$1" == "-check" ]]; then
|
||||
operation=CheckUpload
|
||||
shift
|
||||
|
||||
@@ -14,9 +14,10 @@ Param(
|
||||
|
||||
# Set the right architecture
|
||||
$env:npm_config_arch="$arch"
|
||||
$env:CHILD_CONCURRENCY="1"
|
||||
|
||||
step "Install dependencies" {
|
||||
exec { & npm install }
|
||||
exec { & yarn }
|
||||
}
|
||||
|
||||
step "Hygiene" {
|
||||
|
||||
@@ -17,9 +17,10 @@ Param(
|
||||
|
||||
# Set the right architecture
|
||||
$env:npm_config_arch="$arch"
|
||||
$env:CHILD_CONCURRENCY="1"
|
||||
|
||||
step "Install dependencies" {
|
||||
exec { & npm install }
|
||||
exec { & yarn }
|
||||
}
|
||||
|
||||
step "Hygiene" {
|
||||
|
||||
@@ -6,6 +6,7 @@ $env:HOME=$env:USERPROFILE
|
||||
if (Test-Path env:AGENT_WORKFOLDER) {
|
||||
$env:HOME="${env:AGENT_WORKFOLDER}\home"
|
||||
$env:npm_config_cache="${env:HOME}\npm-cache"
|
||||
$env:YARN_CACHE_FOLDER="${env:HOME}\yarn-cache"
|
||||
$env:npm_config_devdir="${env:HOME}\npm-devdir"
|
||||
New-Item -Path "$env:HOME" -Type directory -Force | out-null
|
||||
New-Item -Path "$env:npm_config_cache" -Type directory -Force | out-null
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# install node
|
||||
$env:Path = $env:NVM_HOME + ";" + $env:NVM_SYMLINK + ";" + $env:Path
|
||||
$NodeVersion = "7.10.0"
|
||||
$NodeVersion = "8.9.1"
|
||||
nvm install $NodeVersion
|
||||
nvm use $NodeVersion
|
||||
npm install -g yarn
|
||||
$env:Path = $env:NVM_HOME + "\v" + $NodeVersion + ";" + $env:Path
|
||||
@@ -2,10 +2,10 @@
|
||||
"rules": {
|
||||
"no-unused-expression": true,
|
||||
"no-duplicate-variable": true,
|
||||
"no-unused-variable": true,
|
||||
"curly": true,
|
||||
"class-name": true,
|
||||
"semicolon": [
|
||||
true,
|
||||
"always"
|
||||
],
|
||||
"triple-equals": true
|
||||
|
||||
@@ -48,11 +48,11 @@ Name: "simplifiedChinese"; MessagesFile: "{#RepoDir}\build\win32\i18n\Default.zh
|
||||
Name: "traditionalChinese"; MessagesFile: "{#RepoDir}\build\win32\i18n\Default.zh-tw.isl,{#RepoDir}\build\win32\i18n\messages.zh-tw.isl" {#LocalizedLanguageFile("cht")}
|
||||
|
||||
[InstallDelete]
|
||||
Type: filesandordirs; Name: {app}\resources\app\out
|
||||
Type: filesandordirs; Name: {app}\resources\app\plugins
|
||||
Type: filesandordirs; Name: {app}\resources\app\extensions
|
||||
Type: filesandordirs; Name: {app}\resources\app\node_modules
|
||||
Type: files; Name: {app}\resources\app\Credits_45.0.2454.85.html
|
||||
Type: filesandordirs; Name: "{app}\resources\app\out"; 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\node_modules"; Check: IsNotUpdate
|
||||
Type: files; Name: "{app}\resources\app\Credits_45.0.2454.85.html"; Check: IsNotUpdate
|
||||
|
||||
[Tasks]
|
||||
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1
|
||||
@@ -68,14 +68,13 @@ Name: "{commondesktop}\{#NameLong}"; Filename: "{app}\{#ExeBasename}.exe"; AppUs
|
||||
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#NameLong}"; Filename: "{app}\{#ExeBasename}.exe"; Tasks: quicklaunchicon; AppUserModelID: "{#AppUserId}"
|
||||
|
||||
[Run]
|
||||
Filename: "{app}\{#ExeBasename}.exe"; Description: "{cm:LaunchProgram,{#NameLong}}"; Tasks: runcode; Flags: nowait postinstall; Check: WizardSilent
|
||||
Filename: "{app}\{#ExeBasename}.exe"; Description: "{cm:LaunchProgram,{#NameLong}}"; Tasks: runcode; Flags: nowait postinstall; Check: ShouldRunAfterUpdate
|
||||
Filename: "{app}\{#ExeBasename}.exe"; Description: "{cm:LaunchProgram,{#NameLong}}"; Flags: nowait postinstall; Check: WizardNotSilent
|
||||
|
||||
[Registry]
|
||||
Root: HKCR; Subkey: "{#RegValueName}SourceFile"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,{#NameLong}}"; Flags: uninsdeletekey
|
||||
Root: HKCR; Subkey: "{#RegValueName}SourceFile\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\code_file.ico"
|
||||
Root: HKCR; Subkey: "{#RegValueName}SourceFile\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""
|
||||
|
||||
Root: HKCU; Subkey: "Environment"; ValueType: expandsz; ValueName: "Path"; ValueData: "{olddata};{app}\bin"; Tasks: addtopath; Check: NeedsAddPath(ExpandConstant('{app}\bin'))
|
||||
|
||||
[Code]
|
||||
@@ -112,6 +111,33 @@ begin
|
||||
Result := not WizardSilent();
|
||||
end;
|
||||
|
||||
// Updates
|
||||
function IsBackgroundUpdate(): Boolean;
|
||||
begin
|
||||
Result := ExpandConstant('{param:update|false}') <> 'false';
|
||||
end;
|
||||
|
||||
function IsNotUpdate(): Boolean;
|
||||
begin
|
||||
Result := not IsBackgroundUpdate();
|
||||
end;
|
||||
|
||||
// SqlOps will create a flag file before the update starts (/update=C:\foo\bar)
|
||||
// - if the file exists at this point, the user quit SqlOps before the update finished, so don't start SqlOps after update
|
||||
// - otherwise, the user has accepted to apply the update and SqlOps should start
|
||||
function LockFileExists(): Boolean;
|
||||
begin
|
||||
Result := FileExists(ExpandConstant('{param:update}'))
|
||||
end;
|
||||
|
||||
function ShouldRunAfterUpdate(): Boolean;
|
||||
begin
|
||||
if IsBackgroundUpdate() then
|
||||
Result := not LockFileExists()
|
||||
else
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
// http://stackoverflow.com/a/23838239/261019
|
||||
procedure Explode(var Dest: TArrayOfString; Text: String; Separator: String);
|
||||
var
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
AddContextMenuFiles=エクスプローラーのファイル コンテキスト メニューに [%1 で開く] アクションを追加する
|
||||
AddContextMenuFolders=エクスプローラーのディレクトリ コンテキスト メニューに [%1 で開く] アクションを追加する
|
||||
AssociateWithFiles=サポートされているファイルの種類のエディターとして、%1 を登録する
|
||||
AddToPath=PATH への追加 (再起動後に使用可能になる)
|
||||
AddToPath=PATH への追加(再起動後に使用可能)
|
||||
RunAfter=インストール後に %1 を実行する
|
||||
Other=その他:
|
||||
SourceFile=%1 ソース ファイル
|
||||
2167
build/yarn.lock
Normal file
2167
build/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
29
dataprotocol-node/.gitignore
vendored
29
dataprotocol-node/.gitignore
vendored
@@ -1,29 +0,0 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
lib/
|
||||
out/
|
||||
|
||||
# Dependency directory
|
||||
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git-
|
||||
node_modules
|
||||
|
||||
# Debug log from npm
|
||||
npm-debug.log
|
||||
@@ -1,18 +0,0 @@
|
||||
|
||||
Copyright (c) Microsoft Corporation
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Source EULA
|
||||
|
||||
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.
|
||||
@@ -1,4 +0,0 @@
|
||||
# Microsoft Data Management Protocol - Node
|
||||
|
||||
## License
|
||||
[MIT](https://github.com/Microsoft/carbon/blob/dev/license.txt)
|
||||
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"rules": {
|
||||
"indent": [
|
||||
2,
|
||||
"tab"
|
||||
],
|
||||
"quotes": [
|
||||
2,
|
||||
"single"
|
||||
],
|
||||
"linebreak-style": [
|
||||
2,
|
||||
"windows"
|
||||
],
|
||||
"semi": [
|
||||
2,
|
||||
"always"
|
||||
]
|
||||
},
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"extends": "eslint:recommended"
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
.vscode/
|
||||
lib/test/
|
||||
lib/*.map
|
||||
src/
|
||||
test/
|
||||
.eslintrc
|
||||
.gitignore
|
||||
gulpfile.js
|
||||
tsd.json
|
||||
32
dataprotocol-node/client/.vscode/launch.json
vendored
32
dataprotocol-node/client/.vscode/launch.json
vendored
@@ -1,32 +0,0 @@
|
||||
{
|
||||
"version": "0.1.0",
|
||||
// List of configurations. Add new configurations or edit existing ones.
|
||||
// ONLY "node" and "mono" are supported, change "type" to switch.
|
||||
"configurations": [
|
||||
{
|
||||
"request": "launch",
|
||||
// Name of configuration; appears in the launch configuration drop down menu.
|
||||
"name": "Mocha",
|
||||
// Type of configuration. Possible values: "node", "mono".
|
||||
"type": "node",
|
||||
// Workspace relative or absolute path to the program.
|
||||
"program": "node_modules/mocha/bin/_mocha",
|
||||
// Automatically stop program after launch.
|
||||
"stopOnEntry": false,
|
||||
// Command line arguments passed to the program.
|
||||
"args": ["--timeout", "999999"],
|
||||
// Workspace relative or absolute path to the working directory of the program being debugged. Default is the current workspace.
|
||||
"cwd": ".",
|
||||
// Workspace relative or absolute path to the runtime executable to be used. Default is the runtime executable on the PATH.
|
||||
"runtimeExecutable": null,
|
||||
// Optional arguments passed to the runtime executable.
|
||||
"runtimeArgs": [],
|
||||
// Environment variables passed to the program.
|
||||
"env": { },
|
||||
// Use JavaScript source maps (if they exist).
|
||||
"sourceMaps": true,
|
||||
// If JavaScript source maps are enabled, the generated code is expected in this directory.
|
||||
"outDir": "lib"
|
||||
}
|
||||
]
|
||||
}
|
||||
11
dataprotocol-node/client/.vscode/settings.json
vendored
11
dataprotocol-node/client/.vscode/settings.json
vendored
@@ -1,11 +0,0 @@
|
||||
// Place your settings in this file to overwrite default and user settings.
|
||||
{
|
||||
"javascript.validate.enable": false,
|
||||
"files.trimTrailingWhitespace": true,
|
||||
"eslint.enable": false,
|
||||
"editor.insertSpaces": false,
|
||||
"editor.tabSize": 4,
|
||||
"tslint.enable": false,
|
||||
"typescript.tsdk": "./node_modules/typescript/lib",
|
||||
"typescript.tsserver.trace": "off"
|
||||
}
|
||||
9
dataprotocol-node/client/.vscode/tasks.json
vendored
9
dataprotocol-node/client/.vscode/tasks.json
vendored
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"version": "0.1.0",
|
||||
"command": "npm",
|
||||
"isShellCommand": true,
|
||||
"args": ["run", "watch"],
|
||||
"showOutput": "silent",
|
||||
"isWatching": true,
|
||||
"problemMatcher": "$tsc-watch"
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
# Microsoft Data Management Protocol - Node
|
||||
|
||||
## License
|
||||
[MIT](https://github.com/Microsoft/carbon/blob/dev/license.txt)
|
||||
@@ -1,32 +0,0 @@
|
||||
{
|
||||
"name": "dataprotocol-client",
|
||||
"description": "VSCode Language client implementation",
|
||||
"version": "2.6.3",
|
||||
"author": "Microsoft Corporation",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"vscode": "^1.5.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/vscode-languageserver-node.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/Microsoft/vscode-languageserver-node/issues"
|
||||
},
|
||||
"main": "./lib/main.js",
|
||||
"typings": "./lib/main",
|
||||
"devDependencies": {
|
||||
"typescript": "2.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"dataprotocol-jsonrpc": "file:../jsonrpc",
|
||||
"dataprotocol-languageserver-types": "file:../types"
|
||||
},
|
||||
"scripts": {
|
||||
"prepublish": "tsc -p ./src",
|
||||
"compile": "tsc -p ./src",
|
||||
"watch": "tsc -w -p ./src",
|
||||
"update-vscode": "node ./node_modules/vscode/bin/install"
|
||||
}
|
||||
}
|
||||
@@ -1,526 +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 code from 'vscode';
|
||||
import * as data from 'data';
|
||||
import * as ls from 'dataprotocol-languageserver-types';
|
||||
import * as proto from './protocol';
|
||||
import * as is from './utils/is';
|
||||
import ProtocolCompletionItem from './protocolCompletionItem';
|
||||
import ProtocolCodeLens from './protocolCodeLens';
|
||||
import os = require('os');
|
||||
import path = require('path');
|
||||
|
||||
export interface Converter {
|
||||
|
||||
asUri(uri: code.Uri): string;
|
||||
|
||||
asTextDocumentIdentifier(textDocument: code.TextDocument): ls.TextDocumentIdentifier;
|
||||
|
||||
asOpenTextDocumentParams(textDocument: code.TextDocument): proto.DidOpenTextDocumentParams;
|
||||
|
||||
asChangeTextDocumentParams(textDocument: code.TextDocument): proto.DidChangeTextDocumentParams;
|
||||
asChangeTextDocumentParams(event: code.TextDocumentChangeEvent): proto.DidChangeTextDocumentParams;
|
||||
|
||||
asCloseTextDocumentParams(textDocument: code.TextDocument): proto.DidCloseTextDocumentParams;
|
||||
|
||||
asSaveTextDocumentParams(textDocument: code.TextDocument): proto.DidSaveTextDocumentParams;
|
||||
|
||||
asTextDocumentPositionParams(textDocument: code.TextDocument, position: code.Position): proto.TextDocumentPositionParams;
|
||||
|
||||
asWorkerPosition(position: code.Position): ls.Position;
|
||||
|
||||
asRange(value: code.Range): ls.Range;
|
||||
|
||||
asPosition(value: code.Position): ls.Position;
|
||||
|
||||
asDiagnosticSeverity(value: code.DiagnosticSeverity): ls.DiagnosticSeverity;
|
||||
|
||||
asDiagnostic(item: code.Diagnostic): ls.Diagnostic;
|
||||
asDiagnostics(items: code.Diagnostic[]): ls.Diagnostic[];
|
||||
|
||||
asCompletionItem(item: code.CompletionItem): ls.CompletionItem;
|
||||
|
||||
asTextEdit(edit: code.TextEdit): ls.TextEdit;
|
||||
|
||||
asReferenceParams(textDocument: code.TextDocument, position: code.Position, options: { includeDeclaration: boolean; }): proto.ReferenceParams;
|
||||
|
||||
asCodeActionContext(context: code.CodeActionContext): ls.CodeActionContext;
|
||||
|
||||
asCommand(item: code.Command): ls.Command;
|
||||
|
||||
asCodeLens(item: code.CodeLens): ls.CodeLens;
|
||||
|
||||
asFormattingOptions(item: code.FormattingOptions): ls.FormattingOptions;
|
||||
|
||||
asDocumentSymbolParams(textDocument: code.TextDocument): proto.DocumentSymbolParams;
|
||||
|
||||
asCodeLensParams(textDocument: code.TextDocument): proto.CodeLensParams;
|
||||
|
||||
asDocumentLink(item: code.DocumentLink): ls.DocumentLink;
|
||||
|
||||
asDocumentLinkParams(textDocument: code.TextDocument): proto.DocumentLinkParams;
|
||||
|
||||
asConnectionParams(connectionUri: string, connectionInfo: data.ConnectionInfo): proto.ConnectParams;
|
||||
|
||||
asCapabilitiesParams(client: data.DataProtocolClientCapabilities): proto.CapabiltiesDiscoveryParams;
|
||||
|
||||
asMetadataQueryParams(connectionUri: string): ls.MetadataQueryParams;
|
||||
|
||||
asListDatabasesParams(connectionUri: string): proto.ListDatabasesParams;
|
||||
|
||||
asTableMetadataParams(connectionUri: string, metadata: data.ObjectMetadata): proto.TableMetadataParams;
|
||||
|
||||
asScriptingParams(connectionUri: string, operation: ls.ScriptOperation, metadata: data.ObjectMetadata, paramDetails: data.ScriptingParamDetails): ls.ScriptingParams;
|
||||
|
||||
asConnectionDetail(connInfo: data.ConnectionInfo): ls.ConnectionDetails;
|
||||
|
||||
asExpandInfo(nodeInfo: data.ExpandNodeInfo): ls.ExpandParams;
|
||||
|
||||
asCloseSessionInfo(nodeInfo: data.ObjectExplorerCloseSessionInfo): ls.CloseSessionParams;
|
||||
|
||||
asExecutionPlanOptions(planOptions: data.ExecutionPlanOptions): proto.ExecutionPlanOptions;
|
||||
|
||||
asListTasksParams(params: data.ListTasksParams): ls.ListTasksParams;
|
||||
|
||||
asCancelTaskParams(params: data.CancelTaskParams): ls.CancelTaskParams;
|
||||
|
||||
asRestoreParams(ownerUri: string, params: data.RestoreInfo): ls.RestoreParams;
|
||||
|
||||
asRestoreConfigInfoParams(ownerUri: string): ls.RestoreConfigInfoRequestParams;
|
||||
}
|
||||
|
||||
export interface URIConverter {
|
||||
(value: code.Uri): string;
|
||||
}
|
||||
|
||||
export function createConverter(uriConverter?: URIConverter): Converter {
|
||||
|
||||
const nullConverter = (value: code.Uri) => value.toString();
|
||||
|
||||
const _uriConverter: URIConverter = uriConverter || nullConverter;
|
||||
|
||||
function asUri(value: code.Uri): string {
|
||||
return _uriConverter(value);
|
||||
}
|
||||
|
||||
function asTextDocumentIdentifier(textDocument: code.TextDocument): ls.TextDocumentIdentifier {
|
||||
return {
|
||||
uri: _uriConverter(textDocument.uri)
|
||||
};
|
||||
}
|
||||
|
||||
function asOpenTextDocumentParams(textDocument: code.TextDocument): proto.DidOpenTextDocumentParams {
|
||||
return {
|
||||
textDocument: {
|
||||
uri: _uriConverter(textDocument.uri),
|
||||
languageId: textDocument.languageId,
|
||||
version: textDocument.version,
|
||||
text: textDocument.getText()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function isTextDocumentChangeEvent(value: any): value is code.TextDocumentChangeEvent {
|
||||
let candidate = <code.TextDocumentChangeEvent>value;
|
||||
return is.defined(candidate.document) && is.defined(candidate.contentChanges);
|
||||
}
|
||||
|
||||
function isTextDocument(value: any): value is code.TextDocument {
|
||||
let candidate = <code.TextDocument>value;
|
||||
return is.defined(candidate.uri) && is.defined(candidate.version);
|
||||
}
|
||||
|
||||
function asChangeTextDocumentParams(textDocument: code.TextDocument): proto.DidChangeTextDocumentParams;
|
||||
function asChangeTextDocumentParams(event: code.TextDocumentChangeEvent): proto.DidChangeTextDocumentParams;
|
||||
function asChangeTextDocumentParams(arg: code.TextDocumentChangeEvent | code.TextDocument): proto.DidChangeTextDocumentParams {
|
||||
if (isTextDocument(arg)) {
|
||||
let result: proto.DidChangeTextDocumentParams = {
|
||||
textDocument: {
|
||||
uri: _uriConverter(arg.uri),
|
||||
version: arg.version
|
||||
},
|
||||
contentChanges: [{ text: arg.getText() }]
|
||||
}
|
||||
return result;
|
||||
} else if (isTextDocumentChangeEvent(arg)) {
|
||||
let document = arg.document;
|
||||
let result: proto.DidChangeTextDocumentParams = {
|
||||
textDocument: {
|
||||
uri: _uriConverter(document.uri),
|
||||
version: document.version
|
||||
},
|
||||
contentChanges: arg.contentChanges.map((change): proto.TextDocumentContentChangeEvent => {
|
||||
let range = change.range;
|
||||
return {
|
||||
range: {
|
||||
start: { line: range.start.line, character: range.start.character },
|
||||
end: { line: range.end.line, character: range.end.character }
|
||||
},
|
||||
rangeLength: change.rangeLength,
|
||||
text: change.text
|
||||
}
|
||||
})
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
throw Error('Unsupported text document change parameter');
|
||||
}
|
||||
}
|
||||
|
||||
function asCloseTextDocumentParams(textDocument: code.TextDocument): proto.DidCloseTextDocumentParams {
|
||||
return {
|
||||
textDocument: asTextDocumentIdentifier(textDocument)
|
||||
};
|
||||
}
|
||||
|
||||
function asSaveTextDocumentParams(textDocument: code.TextDocument): proto.DidSaveTextDocumentParams {
|
||||
return {
|
||||
textDocument: asTextDocumentIdentifier(textDocument)
|
||||
}
|
||||
}
|
||||
|
||||
function asTextDocumentPositionParams(textDocument: code.TextDocument, position: code.Position): proto.TextDocumentPositionParams {
|
||||
return {
|
||||
textDocument: asTextDocumentIdentifier(textDocument),
|
||||
position: asWorkerPosition(position)
|
||||
};
|
||||
}
|
||||
|
||||
function asWorkerPosition(position: code.Position): ls.Position {
|
||||
return { line: position.line, character: position.character };
|
||||
}
|
||||
|
||||
function asRange(value: code.Range): ls.Range {
|
||||
if (is.undefined(value)) {
|
||||
return undefined;
|
||||
} else if (is.nil(value)) {
|
||||
return null;
|
||||
}
|
||||
return { start: asPosition(value.start), end: asPosition(value.end) };
|
||||
}
|
||||
|
||||
function asPosition(value: code.Position): ls.Position {
|
||||
if (is.undefined(value)) {
|
||||
return undefined;
|
||||
} else if (is.nil(value)) {
|
||||
return null;
|
||||
}
|
||||
return { line: value.line, character: value.character };
|
||||
}
|
||||
|
||||
function set(value, func: () => void): void {
|
||||
if (is.defined(value)) {
|
||||
func();
|
||||
}
|
||||
}
|
||||
|
||||
function asDiagnosticSeverity(value: code.DiagnosticSeverity): ls.DiagnosticSeverity {
|
||||
switch (value) {
|
||||
case code.DiagnosticSeverity.Error:
|
||||
return ls.DiagnosticSeverity.Error;
|
||||
case code.DiagnosticSeverity.Warning:
|
||||
return ls.DiagnosticSeverity.Warning;
|
||||
case code.DiagnosticSeverity.Information:
|
||||
return ls.DiagnosticSeverity.Information;
|
||||
case code.DiagnosticSeverity.Hint:
|
||||
return ls.DiagnosticSeverity.Hint;
|
||||
}
|
||||
}
|
||||
|
||||
function asDiagnostic(item: code.Diagnostic): ls.Diagnostic {
|
||||
let result: ls.Diagnostic = ls.Diagnostic.create(asRange(item.range), item.message);
|
||||
set(item.severity, () => result.severity = asDiagnosticSeverity(item.severity));
|
||||
set(item.code, () => result.code = item.code);
|
||||
set(item.source, () => result.source = item.source);
|
||||
return result;
|
||||
}
|
||||
|
||||
function asDiagnostics(items: code.Diagnostic[]): ls.Diagnostic[] {
|
||||
if (is.undefined(items) || is.nil(items)) {
|
||||
return items;
|
||||
}
|
||||
return items.map(asDiagnostic);
|
||||
}
|
||||
|
||||
function asCompletionItem(item: code.CompletionItem): ls.CompletionItem {
|
||||
let result: ls.CompletionItem = { label: item.label };
|
||||
set(item.detail, () => result.detail = item.detail);
|
||||
set(item.documentation, () => result.documentation = item.documentation);
|
||||
set(item.filterText, () => result.filterText = item.filterText);
|
||||
set(item.insertText, () => result.insertText = String(item.insertText));
|
||||
// Protocol item kind is 1 based, codes item kind is zero based.
|
||||
set(item.kind, () => result.kind = item.kind + 1);
|
||||
set(item.sortText, () => result.sortText = item.sortText);
|
||||
set(item.textEdit, () => result.textEdit = asTextEdit(item.textEdit));
|
||||
set(item.additionalTextEdits, () => result.additionalTextEdits = asTextEdits(item.additionalTextEdits));
|
||||
set(item.command, () => result.command = asCommand(item.command));
|
||||
if (item instanceof ProtocolCompletionItem) {
|
||||
set(item.data, () => result.data = item.data);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function asTextEdit(edit: code.TextEdit): ls.TextEdit {
|
||||
return { range: asRange(edit.range), newText: edit.newText };
|
||||
}
|
||||
|
||||
function asTextEdits(edits: code.TextEdit[]): ls.TextEdit[] {
|
||||
if (is.undefined(edits) || is.nil(edits)) {
|
||||
return edits;
|
||||
}
|
||||
return edits.map(asTextEdit);
|
||||
}
|
||||
|
||||
function asReferenceParams(textDocument: code.TextDocument, position: code.Position, options: { includeDeclaration: boolean; }): proto.ReferenceParams {
|
||||
return {
|
||||
textDocument: asTextDocumentIdentifier(textDocument),
|
||||
position: asWorkerPosition(position),
|
||||
context: { includeDeclaration: options.includeDeclaration }
|
||||
};
|
||||
}
|
||||
|
||||
function asCodeActionContext(context: code.CodeActionContext): ls.CodeActionContext {
|
||||
if (is.undefined(context) || is.nil(context)) {
|
||||
return context;
|
||||
}
|
||||
return ls.CodeActionContext.create(asDiagnostics(context.diagnostics));
|
||||
}
|
||||
|
||||
function asCommand(item: code.Command): ls.Command {
|
||||
let result = ls.Command.create(item.title, item.command);
|
||||
if (is.defined(item.arguments)) result.arguments = item.arguments;
|
||||
return result;
|
||||
}
|
||||
|
||||
function asCodeLens(item: code.CodeLens): ls.CodeLens {
|
||||
let result = ls.CodeLens.create(asRange(item.range));
|
||||
if (is.defined(item.command)) result.command = asCommand(item.command);
|
||||
if (item instanceof ProtocolCodeLens) {
|
||||
if (is.defined(item.data)) result.data = item.data;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function asFormattingOptions(item: code.FormattingOptions): ls.FormattingOptions {
|
||||
return { tabSize: item.tabSize, insertSpaces: item.insertSpaces };
|
||||
}
|
||||
|
||||
function asDocumentSymbolParams(textDocument: code.TextDocument): proto.DocumentSymbolParams {
|
||||
return {
|
||||
textDocument: asTextDocumentIdentifier(textDocument)
|
||||
}
|
||||
}
|
||||
|
||||
function asCodeLensParams(textDocument: code.TextDocument): proto.CodeLensParams {
|
||||
return {
|
||||
textDocument: asTextDocumentIdentifier(textDocument)
|
||||
};
|
||||
}
|
||||
|
||||
function asDocumentLink(item: code.DocumentLink): ls.DocumentLink {
|
||||
let result = ls.DocumentLink.create(asRange(item.range));
|
||||
if (is.defined(item.target)) result.target = asUri(item.target);
|
||||
return result;
|
||||
}
|
||||
|
||||
function asDocumentLinkParams(textDocument: code.TextDocument): proto.DocumentLinkParams {
|
||||
return {
|
||||
textDocument: asTextDocumentIdentifier(textDocument)
|
||||
};
|
||||
}
|
||||
|
||||
function asCapabilitiesParams(client: data.DataProtocolClientCapabilities): proto.CapabiltiesDiscoveryParams {
|
||||
let params: proto.CapabiltiesDiscoveryParams = {
|
||||
hostName: client.hostName,
|
||||
hostVersion: client.hostVersion
|
||||
};
|
||||
return params;
|
||||
}
|
||||
|
||||
function asConnectionParams(connUri: string, connInfo: data.ConnectionInfo): proto.ConnectParams {
|
||||
return {
|
||||
ownerUri: connUri,
|
||||
connection: {
|
||||
options: connInfo.options
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function asMetadataQueryParams(connectionUri: string): ls.MetadataQueryParams {
|
||||
return <ls.MetadataQueryParams>{
|
||||
ownerUri: connectionUri
|
||||
};
|
||||
}
|
||||
|
||||
function asListDatabasesParams(connectionUri: string): proto.ListDatabasesParams {
|
||||
return <proto.ListDatabasesParams>{
|
||||
ownerUri: connectionUri
|
||||
};
|
||||
}
|
||||
|
||||
function asTableMetadataParams(connectionUri: string, metadata: data.ObjectMetadata): proto.TableMetadataParams {
|
||||
return <proto.TableMetadataParams>{
|
||||
ownerUri: connectionUri,
|
||||
schema: metadata.schema,
|
||||
objectName: metadata.name
|
||||
};
|
||||
}
|
||||
|
||||
function asScriptingParams(connectionUri: string, operation: ls.ScriptOperation, metadata: data.ObjectMetadata, paramDetails: data.ScriptingParamDetails): ls.ScriptingParams {
|
||||
let scriptingObject: ls.ScriptingObject = {
|
||||
type: metadata.metadataTypeName,
|
||||
schema: metadata.schema,
|
||||
name: metadata.name
|
||||
}
|
||||
let targetDatabaseEngineEdition = paramDetails.targetDatabaseEngineEdition;
|
||||
let targetDatabaseEngineType = paramDetails.targetDatabaseEngineType;
|
||||
let scriptCompatibilityOption = paramDetails.scriptCompatibilityOption;
|
||||
let options: ls.ScriptOptions = {
|
||||
scriptCreateDrop: (operation === ls.ScriptOperation.Delete) ? "ScriptDrop" :
|
||||
(operation === ls.ScriptOperation.Select) ? "ScriptSelect" : "ScriptCreate",
|
||||
typeOfDataToScript: "SchemaOnly",
|
||||
scriptStatistics: "ScriptStatsNone",
|
||||
targetDatabaseEngineEdition: targetDatabaseEngineEdition ? targetDatabaseEngineEdition : "SqlServerEnterpriseEdition",
|
||||
targetDatabaseEngineType: targetDatabaseEngineType ? targetDatabaseEngineType : "SingleInstance",
|
||||
scriptCompatibilityOption: scriptCompatibilityOption ? scriptCompatibilityOption : "Script140Compat"
|
||||
}
|
||||
return <ls.ScriptingParams> {
|
||||
connectionString: null,
|
||||
filePath: paramDetails.filePath,
|
||||
scriptingObjects: [scriptingObject],
|
||||
scriptDestination: "ToEditor",
|
||||
includeObjectCriteria: null,
|
||||
excludeObjectCriteria: null,
|
||||
includeSchemas: null,
|
||||
excludeSchemas: null,
|
||||
includeTypes: null,
|
||||
excludeTypes: null,
|
||||
scriptOptions: options,
|
||||
connectionDetails: null,
|
||||
ownerURI: connectionUri,
|
||||
operation: operation
|
||||
};
|
||||
}
|
||||
|
||||
function asConnectionDetail(connInfo: data.ConnectionInfo): ls.ConnectionDetails {
|
||||
return <ls.ConnectionDetails>{
|
||||
options: connInfo.options
|
||||
};
|
||||
}
|
||||
|
||||
function asExpandInfo(nodeInfo: data.ExpandNodeInfo): ls.ExpandParams {
|
||||
return <ls.ExpandParams>{
|
||||
sessionId: nodeInfo.sessionId,
|
||||
nodePath: nodeInfo.nodePath
|
||||
};
|
||||
}
|
||||
|
||||
function asCloseSessionInfo(nodeInfo: data.ObjectExplorerCloseSessionInfo): ls.CloseSessionParams {
|
||||
return <ls.CloseSessionParams>{
|
||||
sessionId: nodeInfo.sessionId
|
||||
};
|
||||
}
|
||||
|
||||
function asExecutionPlanOptions(planOptions: data.ExecutionPlanOptions): proto.ExecutionPlanOptions {
|
||||
return <proto.ExecutionPlanOptions>{
|
||||
includeEstimatedExecutionPlanXml: planOptions ? planOptions.displayEstimatedQueryPlan : undefined,
|
||||
includeActualExecutionPlanXml: planOptions ? planOptions.displayActualQueryPlan : undefined
|
||||
};
|
||||
}
|
||||
|
||||
function asListTasksParams(params: data.ListTasksParams): ls.ListTasksParams {
|
||||
return <ls.ListTasksParams>{
|
||||
listActiveTasksOnly: params.listActiveTasksOnly
|
||||
};
|
||||
}
|
||||
|
||||
function asCancelTaskParams(params: data.CancelTaskParams): ls.CancelTaskParams {
|
||||
return <ls.CancelTaskParams>{
|
||||
taskId: params.taskId
|
||||
};
|
||||
}
|
||||
|
||||
function asRestoreParams(ownerUri: string, params: data.RestoreInfo): ls.RestoreParams {
|
||||
return <ls.RestoreParams>{
|
||||
ownerUri: ownerUri,
|
||||
options: params.options,
|
||||
taskExecutionMode: params.taskExecutionMode
|
||||
};
|
||||
}
|
||||
|
||||
function asRestoreConfigInfoParams(ownerUri: string): ls.RestoreConfigInfoRequestParams {
|
||||
return <ls.RestoreConfigInfoRequestParams>{
|
||||
ownerUri: ownerUri
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
asUri,
|
||||
asTextDocumentIdentifier,
|
||||
asOpenTextDocumentParams,
|
||||
asChangeTextDocumentParams,
|
||||
asCloseTextDocumentParams,
|
||||
asSaveTextDocumentParams,
|
||||
asTextDocumentPositionParams,
|
||||
asWorkerPosition,
|
||||
asRange,
|
||||
asPosition,
|
||||
asDiagnosticSeverity,
|
||||
asDiagnostic,
|
||||
asDiagnostics,
|
||||
asCompletionItem,
|
||||
asTextEdit,
|
||||
asReferenceParams,
|
||||
asCodeActionContext,
|
||||
asCommand,
|
||||
asCodeLens,
|
||||
asFormattingOptions,
|
||||
asDocumentSymbolParams,
|
||||
asCodeLensParams,
|
||||
asDocumentLink,
|
||||
asDocumentLinkParams,
|
||||
asCapabilitiesParams,
|
||||
asConnectionParams,
|
||||
asMetadataQueryParams,
|
||||
asTableMetadataParams,
|
||||
asListDatabasesParams,
|
||||
asScriptingParams,
|
||||
asConnectionDetail,
|
||||
asExpandInfo,
|
||||
asCloseSessionInfo,
|
||||
asExecutionPlanOptions,
|
||||
asListTasksParams,
|
||||
asCancelTaskParams,
|
||||
asRestoreParams,
|
||||
asRestoreConfigInfoParams
|
||||
};
|
||||
}
|
||||
|
||||
// This for backward compatibility since we exported the converter functions as API.
|
||||
let defaultConverter = createConverter();
|
||||
|
||||
export const asTextDocumentIdentifier: (textDocument: code.TextDocument) => ls.TextDocumentIdentifier = defaultConverter.asTextDocumentIdentifier;
|
||||
export const asOpenTextDocumentParams: (textDocument: code.TextDocument) => proto.DidOpenTextDocumentParams = defaultConverter.asOpenTextDocumentParams;
|
||||
export const asChangeTextDocumentParams: (arg: code.TextDocumentChangeEvent | code.TextDocument) => proto.DidChangeTextDocumentParams = defaultConverter.asChangeTextDocumentParams;
|
||||
export const asCloseTextDocumentParams: (textDocument: code.TextDocument) => proto.DidCloseTextDocumentParams = defaultConverter.asCloseTextDocumentParams;
|
||||
export const asSaveTextDocumentParams: (textDocument: code.TextDocument) => proto.DidSaveTextDocumentParams = defaultConverter.asSaveTextDocumentParams;
|
||||
export const asTextDocumentPositionParams: (textDocument: code.TextDocument, position: code.Position) => proto.TextDocumentPositionParams = defaultConverter.asTextDocumentPositionParams;
|
||||
export const asWorkerPosition: (position: code.Position) => ls.Position = defaultConverter.asWorkerPosition;
|
||||
export const asRange: (value: code.Range) => ls.Range = defaultConverter.asRange;
|
||||
export const asPosition: (value: code.Position) => ls.Position = defaultConverter.asPosition;
|
||||
export const asDiagnosticSeverity: (value: code.DiagnosticSeverity) => ls.DiagnosticSeverity = defaultConverter.asDiagnosticSeverity;
|
||||
export const asDiagnostic: (item: code.Diagnostic) => ls.Diagnostic = defaultConverter.asDiagnostic;
|
||||
export const asDiagnostics: (items: code.Diagnostic[]) => ls.Diagnostic[] = defaultConverter.asDiagnostics;
|
||||
export const asCompletionItem: (item: code.CompletionItem) => ls.CompletionItem = defaultConverter.asCompletionItem;
|
||||
export const asTextEdit: (edit: code.TextEdit) => ls.TextEdit = defaultConverter.asTextEdit;
|
||||
export const asReferenceParams: (textDocument: code.TextDocument, position: code.Position, options: { includeDeclaration: boolean; }) => proto.ReferenceParams = defaultConverter.asReferenceParams;
|
||||
export const asCodeActionContext: (context: code.CodeActionContext) => ls.CodeActionContext = defaultConverter.asCodeActionContext;
|
||||
export const asCommand: (item: code.Command) => ls.Command = defaultConverter.asCommand;
|
||||
export const asCodeLens: (item: code.CodeLens) => ls.CodeLens = defaultConverter.asCodeLens;
|
||||
export const asFormattingOptions: (item: code.FormattingOptions) => ls.FormattingOptions = defaultConverter.asFormattingOptions;
|
||||
export const asDocumentSymbolParams: (textDocument: code.TextDocument) => proto.DocumentSymbolParams = defaultConverter.asDocumentSymbolParams;
|
||||
export const asCodeLensParams: (textDocument: code.TextDocument) => proto.CodeLensParams = defaultConverter.asCodeLensParams;
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,16 +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 code from 'vscode';
|
||||
|
||||
export default class ProtocolCodeLens extends code.CodeLens {
|
||||
|
||||
public data: any;
|
||||
|
||||
constructor(range: code.Range) {
|
||||
super(range);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +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 code from 'vscode';
|
||||
|
||||
export default class ProtocolCompletionItem extends code.CompletionItem {
|
||||
|
||||
public data: any;
|
||||
|
||||
constructor(label: string) {
|
||||
super(label);
|
||||
}
|
||||
}
|
||||
@@ -1,769 +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 code from 'vscode';
|
||||
import * as data from 'data';
|
||||
import * as ls from 'dataprotocol-languageserver-types';
|
||||
import * as is from './utils/is';
|
||||
import ProtocolCompletionItem from './protocolCompletionItem';
|
||||
import ProtocolCodeLens from './protocolCodeLens';
|
||||
|
||||
export interface Converter {
|
||||
|
||||
asUri(value: string): code.Uri;
|
||||
|
||||
asDiagnostics(diagnostics: ls.Diagnostic[]): code.Diagnostic[];
|
||||
|
||||
asDiagnostic(diagnostic: ls.Diagnostic): code.Diagnostic;
|
||||
|
||||
asRange(value: ls.Range): code.Range;
|
||||
|
||||
asPosition(value: ls.Position): code.Position;
|
||||
|
||||
asDiagnosticSeverity(value: number): code.DiagnosticSeverity;
|
||||
|
||||
asHover(hover: ls.Hover): code.Hover;
|
||||
|
||||
asCompletionResult(result: ls.CompletionItem[] | ls.CompletionList): code.CompletionItem[] | code.CompletionList
|
||||
|
||||
asCompletionItem(item: ls.CompletionItem): ProtocolCompletionItem;
|
||||
|
||||
asTextEdit(edit: ls.TextEdit): code.TextEdit;
|
||||
|
||||
asTextEdits(items: ls.TextEdit[]): code.TextEdit[];
|
||||
|
||||
asSignatureHelp(item: ls.SignatureHelp): code.SignatureHelp;
|
||||
|
||||
asSignatureInformations(items: ls.SignatureInformation[]): code.SignatureInformation[];
|
||||
|
||||
asSignatureInformation(item: ls.SignatureInformation): code.SignatureInformation;
|
||||
|
||||
asParameterInformations(item: ls.ParameterInformation[]): code.ParameterInformation[];
|
||||
|
||||
asParameterInformation(item: ls.ParameterInformation): code.ParameterInformation;
|
||||
|
||||
asDefinitionResult(item: ls.Definition): code.Definition;
|
||||
|
||||
asLocation(item: ls.Location): code.Location;
|
||||
|
||||
asReferences(values: ls.Location[]): code.Location[];
|
||||
|
||||
asDocumentHighlights(values: ls.DocumentHighlight[]): code.DocumentHighlight[];
|
||||
|
||||
asDocumentHighlight(item: ls.DocumentHighlight): code.DocumentHighlight;
|
||||
|
||||
asDocumentHighlightKind(item: ls.DocumentHighlightKind): code.DocumentHighlightKind;
|
||||
|
||||
asSymbolInformations(values: ls.SymbolInformation[], uri?: code.Uri): code.SymbolInformation[];
|
||||
|
||||
asSymbolInformation(item: ls.SymbolInformation, uri?: code.Uri): code.SymbolInformation;
|
||||
|
||||
asCommand(item: ls.Command): code.Command;
|
||||
|
||||
asCommands(items: ls.Command[]): code.Command[];
|
||||
|
||||
asCodeLens(item: ls.CodeLens): code.CodeLens;
|
||||
|
||||
asCodeLenses(items: ls.CodeLens[]): code.CodeLens[];
|
||||
|
||||
asWorkspaceEdit(item: ls.WorkspaceEdit): code.WorkspaceEdit;
|
||||
|
||||
asDocumentLink(item: ls.DocumentLink): code.DocumentLink;
|
||||
|
||||
asDocumentLinks(items: ls.DocumentLink[]): code.DocumentLink[];
|
||||
|
||||
asConnectionSummary(params: ls.ConnectionCompleteParams): data.ConnectionInfoSummary;
|
||||
|
||||
asServerCapabilities(params: ls.CapabiltiesDiscoveryResult): data.DataProtocolServerCapabilities;
|
||||
|
||||
asProviderMetadata(params: ls.MetadataQueryResult): data.ProviderMetadata;
|
||||
|
||||
asScriptingResult(params: ls.ScriptingResult): data.ScriptingResult;
|
||||
|
||||
asObjectExplorerSession(params: ls.SessionCreatedParameters): data.ObjectExplorerSession;
|
||||
|
||||
asObjectExplorerCreateSessionResponse(params: ls.CreateSessionResponse): data.ObjectExplorerSessionResponse;
|
||||
|
||||
asObjectExplorerNodeInfo(params: ls.ExpandResponse): data.ObjectExplorerExpandInfo;
|
||||
|
||||
asObjectExplorerCloseSessionResponse(params: ls.CloseSessionResponse): data.ObjectExplorerCloseSessionResponse;
|
||||
|
||||
asListTasksResponse(response: ls.ListTasksResponse): data.ListTasksResponse;
|
||||
|
||||
asTaskInfo(params: ls.TaskInfo): data.TaskInfo;
|
||||
|
||||
asRestorePlanResponse(params: ls.RestorePlanResponse): data.RestorePlanResponse;
|
||||
|
||||
asRestoreResponse(params: ls.RestoreResponse): data.RestoreResponse;
|
||||
|
||||
asRestoreConfigInfo(params: ls.RestoreConfigInfoResponse): data.RestoreConfigInfo;
|
||||
}
|
||||
|
||||
export interface URIConverter {
|
||||
(value: string): code.Uri;
|
||||
}
|
||||
|
||||
export function createConverter(uriConverter?: URIConverter): Converter {
|
||||
|
||||
const nullConverter = (value: string) => code.Uri.parse(value);
|
||||
|
||||
const _uriConverter: URIConverter = uriConverter || nullConverter;
|
||||
|
||||
function asUri(value: string): code.Uri {
|
||||
return _uriConverter(value);
|
||||
}
|
||||
|
||||
function asDiagnostics(diagnostics: ls.Diagnostic[]): code.Diagnostic[] {
|
||||
return diagnostics.map(asDiagnostic);
|
||||
}
|
||||
|
||||
function asDiagnostic(diagnostic: ls.Diagnostic): code.Diagnostic {
|
||||
let result = new code.Diagnostic(asRange(diagnostic.range), diagnostic.message, asDiagnosticSeverity(diagnostic.severity));
|
||||
if (is.defined(diagnostic.code)) {
|
||||
result.code = diagnostic.code;
|
||||
}
|
||||
if (is.defined(diagnostic.source)) {
|
||||
result.source = diagnostic.source;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function asRange(value: ls.Range): code.Range {
|
||||
if (is.undefined(value)) {
|
||||
return undefined;
|
||||
} else if (is.nil(value)) {
|
||||
return null;
|
||||
}
|
||||
return new code.Range(asPosition(value.start), asPosition(value.end));
|
||||
}
|
||||
|
||||
function asPosition(value: ls.Position): code.Position {
|
||||
if (is.undefined(value)) {
|
||||
return undefined;
|
||||
} else if (is.nil(value)) {
|
||||
return null;
|
||||
}
|
||||
return new code.Position(value.line, value.character);
|
||||
}
|
||||
|
||||
function asDiagnosticSeverity(value: number): code.DiagnosticSeverity {
|
||||
if (is.undefined(value) || is.nil(value)) {
|
||||
return code.DiagnosticSeverity.Error;
|
||||
}
|
||||
switch (value) {
|
||||
case ls.DiagnosticSeverity.Error:
|
||||
return code.DiagnosticSeverity.Error;
|
||||
case ls.DiagnosticSeverity.Warning:
|
||||
return code.DiagnosticSeverity.Warning;
|
||||
case ls.DiagnosticSeverity.Information:
|
||||
return code.DiagnosticSeverity.Information;
|
||||
case ls.DiagnosticSeverity.Hint:
|
||||
return code.DiagnosticSeverity.Hint;
|
||||
}
|
||||
return code.DiagnosticSeverity.Error;
|
||||
}
|
||||
|
||||
function asHover(hover: ls.Hover): code.Hover {
|
||||
if (is.undefined(hover)) {
|
||||
return undefined;
|
||||
}
|
||||
if (is.nil(hover)) {
|
||||
return null;
|
||||
}
|
||||
if (is.nil(hover.contents) || is.undefined(hover.contents)) {
|
||||
// Contents must be defined or hover will throw
|
||||
return null;
|
||||
}
|
||||
return new code.Hover(hover.contents, is.defined(hover.range) ? asRange(hover.range) : undefined);
|
||||
}
|
||||
|
||||
function asCompletionResult(result: ls.CompletionItem[] | ls.CompletionList): code.CompletionItem[] | code.CompletionList {
|
||||
if (is.undefined(result)) {
|
||||
return undefined;
|
||||
} else if (is.nil(result)) {
|
||||
return null;
|
||||
}
|
||||
if (Array.isArray(result)) {
|
||||
let items = <ls.CompletionItem[]>result;
|
||||
return items.map(asCompletionItem);
|
||||
}
|
||||
let list = <ls.CompletionList>result;
|
||||
return new code.CompletionList(list.items.map(asCompletionItem), list.isIncomplete);
|
||||
}
|
||||
|
||||
function set<T>(value: T, func: () => void): void {
|
||||
if (is.defined(value)) {
|
||||
func();
|
||||
}
|
||||
}
|
||||
|
||||
function asCompletionItem(item: ls.CompletionItem): ProtocolCompletionItem {
|
||||
let result = new ProtocolCompletionItem(item.label);
|
||||
set(item.detail, () => result.detail = item.detail);
|
||||
set(item.documentation, () => result.documentation = item.documentation);
|
||||
set(item.filterText, () => result.filterText = item.filterText);
|
||||
set(item.insertText, () => result.insertText = item.insertText);
|
||||
// Protocol item kind is 1 based, codes item kind is zero based.
|
||||
set(item.kind, () => result.kind = item.kind - 1);
|
||||
set(item.sortText, () => result.sortText = item.sortText);
|
||||
set(item.textEdit, () => result.textEdit = asTextEdit(item.textEdit));
|
||||
set(item.additionalTextEdits, () => result.additionalTextEdits = asTextEdits(item.additionalTextEdits));
|
||||
set(item.command, () => result.command = asCommand(item.command));
|
||||
set(item.data, () => result.data = item.data);
|
||||
return result;
|
||||
}
|
||||
|
||||
function asTextEdit(edit: ls.TextEdit): code.TextEdit {
|
||||
return new code.TextEdit(asRange(edit.range), edit.newText);
|
||||
}
|
||||
|
||||
function asTextEdits(items: ls.TextEdit[]): code.TextEdit[] {
|
||||
if (is.undefined(items)) {
|
||||
return undefined;
|
||||
} else if (is.nil(items)) {
|
||||
return null;
|
||||
}
|
||||
return items.map(asTextEdit);
|
||||
}
|
||||
|
||||
function asSignatureHelp(item: ls.SignatureHelp): code.SignatureHelp {
|
||||
if (is.undefined(item)) {
|
||||
return undefined;
|
||||
} else if (is.nil(item)) {
|
||||
return null;
|
||||
}
|
||||
let result = new code.SignatureHelp();
|
||||
set(item.activeParameter, () => result.activeParameter = item.activeParameter);
|
||||
set(item.activeSignature, () => result.activeSignature = item.activeSignature);
|
||||
set(item.signatures, () => result.signatures = asSignatureInformations(item.signatures));
|
||||
return result;
|
||||
}
|
||||
|
||||
function asSignatureInformations(items: ls.SignatureInformation[]): code.SignatureInformation[] {
|
||||
return items ? items.map(asSignatureInformation) : undefined;
|
||||
}
|
||||
|
||||
function asSignatureInformation(item: ls.SignatureInformation): code.SignatureInformation {
|
||||
if (!item) {
|
||||
return undefined;
|
||||
}
|
||||
let result = new code.SignatureInformation(item.label);
|
||||
set(item.documentation, () => result.documentation = item.documentation);
|
||||
set(item.parameters, () => result.parameters = asParameterInformations(item.parameters));
|
||||
return result;
|
||||
}
|
||||
|
||||
function asParameterInformations(item: ls.ParameterInformation[]): code.ParameterInformation[] {
|
||||
return item.map(asParameterInformation);
|
||||
}
|
||||
|
||||
function asParameterInformation(item: ls.ParameterInformation): code.ParameterInformation {
|
||||
let result = new code.ParameterInformation(item.label);
|
||||
set(item.documentation, () => result.documentation = item.documentation);
|
||||
return result;
|
||||
}
|
||||
|
||||
function asDefinitionResult(item: ls.Definition): code.Definition {
|
||||
if (is.undefined(item)) {
|
||||
return undefined;
|
||||
} else if (is.nil(item)) {
|
||||
return null;
|
||||
}
|
||||
if (is.array(item)) {
|
||||
return item.map(asLocation);
|
||||
} else {
|
||||
return asLocation(item);
|
||||
}
|
||||
}
|
||||
|
||||
function asLocation(item: ls.Location): code.Location {
|
||||
if (is.undefined(item)) {
|
||||
return undefined;
|
||||
}
|
||||
if (is.nil(item)) {
|
||||
return null;
|
||||
}
|
||||
return new code.Location(_uriConverter(item.uri), asRange(item.range));
|
||||
}
|
||||
|
||||
function asReferences(values: ls.Location[]): code.Location[] {
|
||||
if (is.undefined(values)) {
|
||||
return undefined;
|
||||
}
|
||||
if (is.nil(values)) {
|
||||
return null;
|
||||
}
|
||||
return values.map(asLocation);
|
||||
}
|
||||
|
||||
function asDocumentHighlights(values: ls.DocumentHighlight[]): code.DocumentHighlight[] {
|
||||
if (is.undefined(values)) {
|
||||
return undefined;
|
||||
}
|
||||
if (is.nil(values)) {
|
||||
return null;
|
||||
}
|
||||
return values.map(asDocumentHighlight);
|
||||
}
|
||||
|
||||
function asDocumentHighlight(item: ls.DocumentHighlight): code.DocumentHighlight {
|
||||
let result = new code.DocumentHighlight(asRange(item.range));
|
||||
set(item.kind, () => result.kind = asDocumentHighlightKind(item.kind));
|
||||
return result;
|
||||
}
|
||||
|
||||
function asDocumentHighlightKind(item: ls.DocumentHighlightKind): code.DocumentHighlightKind {
|
||||
switch (item) {
|
||||
case ls.DocumentHighlightKind.Text:
|
||||
return code.DocumentHighlightKind.Text;
|
||||
case ls.DocumentHighlightKind.Read:
|
||||
return code.DocumentHighlightKind.Read;
|
||||
case ls.DocumentHighlightKind.Write:
|
||||
return code.DocumentHighlightKind.Write;
|
||||
}
|
||||
return code.DocumentHighlightKind.Text;
|
||||
}
|
||||
|
||||
function asSymbolInformations(values: ls.SymbolInformation[], uri?: code.Uri): code.SymbolInformation[] {
|
||||
if (is.undefined(values)) {
|
||||
return undefined;
|
||||
}
|
||||
if (is.nil(values)) {
|
||||
return null;
|
||||
}
|
||||
return values.map(information => asSymbolInformation(information, uri));
|
||||
}
|
||||
|
||||
function asSymbolInformation(item: ls.SymbolInformation, uri?: code.Uri): code.SymbolInformation {
|
||||
// Symbol kind is one based in the protocol and zero based in code.
|
||||
let result = new code.SymbolInformation(
|
||||
item.name, item.kind - 1,
|
||||
asRange(item.location.range),
|
||||
item.location.uri ? _uriConverter(item.location.uri) : uri);
|
||||
set(item.containerName, () => result.containerName = item.containerName);
|
||||
return result;
|
||||
}
|
||||
|
||||
function asCommand(item: ls.Command): code.Command {
|
||||
let result: code.Command = { title: item.title, command: item.command };
|
||||
set(item.arguments, () => result.arguments = item.arguments);
|
||||
return result;
|
||||
}
|
||||
|
||||
function asCommands(items: ls.Command[]): code.Command[] {
|
||||
if (is.undefined(items)) {
|
||||
return undefined;
|
||||
}
|
||||
if (is.nil(items)) {
|
||||
return null;
|
||||
}
|
||||
return items.map(asCommand);
|
||||
}
|
||||
|
||||
function asCodeLens(item: ls.CodeLens): code.CodeLens {
|
||||
let result: ProtocolCodeLens = new ProtocolCodeLens(asRange(item.range));
|
||||
if (is.defined(item.command)) { result.command = asCommand(item.command); }
|
||||
if (is.defined(item.data)) { result.data = item.data; }
|
||||
return result;
|
||||
}
|
||||
|
||||
function asCodeLenses(items: ls.CodeLens[]): code.CodeLens[] {
|
||||
if (is.undefined(items)) {
|
||||
return undefined;
|
||||
}
|
||||
if (is.nil(items)) {
|
||||
return null;
|
||||
}
|
||||
return items.map(asCodeLens);
|
||||
}
|
||||
|
||||
function asWorkspaceEdit(item: ls.WorkspaceEdit): code.WorkspaceEdit {
|
||||
if (is.undefined(item)) {
|
||||
return undefined;
|
||||
}
|
||||
if (is.nil(item)) {
|
||||
return null;
|
||||
}
|
||||
let result = new code.WorkspaceEdit();
|
||||
let keys = Object.keys(item.changes);
|
||||
keys.forEach(key => result.set(_uriConverter(key), asTextEdits(item.changes[key])));
|
||||
return result;
|
||||
}
|
||||
|
||||
function asDocumentLink(item: ls.DocumentLink): code.DocumentLink {
|
||||
let range = asRange(item.range);
|
||||
let target = is.defined(item.target) && asUri(item.target);
|
||||
return new code.DocumentLink(range, target);
|
||||
}
|
||||
|
||||
function asDocumentLinks(items: ls.DocumentLink[]): code.DocumentLink[] {
|
||||
if (is.undefined(items)) {
|
||||
return undefined;
|
||||
}
|
||||
if (is.nil(items)) {
|
||||
return null;
|
||||
}
|
||||
return items.map(asDocumentLink);
|
||||
}
|
||||
|
||||
function asConnectionSummary(params: ls.ConnectionCompleteParams): data.ConnectionInfoSummary {
|
||||
let connSummary: data.ConnectionInfoSummary = {
|
||||
ownerUri: params.ownerUri,
|
||||
connectionId: params.connectionId,
|
||||
messages: params.messages,
|
||||
errorMessage: params.errorMessage,
|
||||
errorNumber: params.errorNumber,
|
||||
serverInfo: params.serverInfo,
|
||||
connectionSummary: params.connectionSummary
|
||||
};
|
||||
return connSummary;
|
||||
}
|
||||
|
||||
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 asServerCapabilities(result: ls.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: ls.ServiceOption = 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: ls.ServiceOption = 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: ls.ServiceOption = 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: ls.ConnectionOption = 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(srcOption));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
function buildServiceOption(srcOption: ls.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 asProviderMetadata(params: ls.MetadataQueryResult): data.ProviderMetadata {
|
||||
let objectMetadata: data.ObjectMetadata[] = [];
|
||||
|
||||
if (!params.metadata || !params.metadata.length) {
|
||||
return {
|
||||
objectMetadata: objectMetadata
|
||||
};
|
||||
}
|
||||
|
||||
for (let i = 0; i < params.metadata.length; ++i) {
|
||||
let metadata: ls.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 === ls.MetadataType.View) {
|
||||
metadataTypeName = 'View';
|
||||
} else if (metadata.metadataType === ls.MetadataType.SProc) {
|
||||
metadataTypeName = 'StoredProcedure';
|
||||
} else if (metadata.metadataType === ls.MetadataType.Function) {
|
||||
metadataTypeName = 'Function';
|
||||
} else {
|
||||
metadataTypeName = 'Table';
|
||||
}
|
||||
|
||||
objectMetadata.push({
|
||||
metadataTypeName: metadataTypeName,
|
||||
metadataType: metadata.metadataType,
|
||||
name: metadata.name,
|
||||
schema: metadata.schema,
|
||||
urn: metadata.urn
|
||||
});
|
||||
}
|
||||
|
||||
return <data.ProviderMetadata>{
|
||||
objectMetadata: objectMetadata
|
||||
};
|
||||
}
|
||||
|
||||
function asObjectExplorerSession(params: ls.SessionCreatedParameters): data.ObjectExplorerSession {
|
||||
return <data.ObjectExplorerSession>{
|
||||
success: params.success,
|
||||
sessionId: params.sessionId,
|
||||
rootNode: params.rootNode,
|
||||
errorMessage: params.errorMessage
|
||||
};
|
||||
}
|
||||
|
||||
function asObjectExplorerCreateSessionResponse(params: ls.CreateSessionResponse): data.ObjectExplorerSessionResponse {
|
||||
return <data.ObjectExplorerSessionResponse>{
|
||||
sessionId: params.sessionId
|
||||
};
|
||||
}
|
||||
|
||||
function asObjectExplorerNodeInfo(params: ls.ExpandResponse): data.ObjectExplorerExpandInfo {
|
||||
return <data.ObjectExplorerExpandInfo>{
|
||||
sessionId: params.sessionId,
|
||||
nodes: params.nodes,
|
||||
errorMessage: params.errorMessage,
|
||||
nodePath: params.nodePath
|
||||
};
|
||||
}
|
||||
|
||||
function asObjectExplorerCloseSessionResponse(params: ls.CloseSessionResponse): data.ObjectExplorerCloseSessionResponse {
|
||||
return <data.ObjectExplorerCloseSessionResponse>{
|
||||
sessionId: params.sessionId,
|
||||
success: params.success
|
||||
};
|
||||
}
|
||||
|
||||
function asScriptingResult(params: ls.ScriptingResult): data.ScriptingResult {
|
||||
return <data.ScriptingResult>{
|
||||
operationId: params.operationId,
|
||||
script: params.script
|
||||
};
|
||||
}
|
||||
|
||||
function asListTasksResponse(response: ls.ListTasksResponse): data.ListTasksResponse {
|
||||
return <data.ListTasksResponse>{
|
||||
tasks: response.tasks
|
||||
};
|
||||
}
|
||||
|
||||
function asTaskInfo(params: ls.TaskInfo): data.TaskInfo {
|
||||
return <data.TaskInfo>{
|
||||
taskId: params.taskId,
|
||||
status: params.status,
|
||||
taskExecutionMode: params.taskExecutionMode,
|
||||
serverName: params.serverName,
|
||||
name: params.name,
|
||||
databaseName: params.databaseName,
|
||||
description: params.description,
|
||||
providerName: params.providerName,
|
||||
isCancelable: params.isCancelable,
|
||||
};
|
||||
}
|
||||
|
||||
function asRestorePlanResponse(params: ls.RestorePlanResponse): data.RestorePlanResponse {
|
||||
return <data.RestorePlanResponse>{
|
||||
backupSetsToRestore: params.backupSetsToRestore,
|
||||
canRestore: params.canRestore,
|
||||
databaseNamesFromBackupSets: params.databaseNamesFromBackupSets,
|
||||
dbFiles: params.dbFiles,
|
||||
errorMessage: params.errorMessage,
|
||||
planDetails: params.planDetails,
|
||||
sessionId: params.sessionId
|
||||
};
|
||||
}
|
||||
|
||||
function asRestoreResponse(params: ls.RestoreResponse): data.RestoreResponse {
|
||||
return <data.RestoreResponse>{
|
||||
result: params.result,
|
||||
errorMessage: params.errorMessage,
|
||||
taskId: params.taskId
|
||||
};
|
||||
}
|
||||
|
||||
function asRestoreConfigInfo(params: ls.RestoreConfigInfoResponse): data.RestoreConfigInfo {
|
||||
return <data.RestoreConfigInfo>{
|
||||
configInfo: params.configInfo
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
asUri,
|
||||
asDiagnostics,
|
||||
asDiagnostic,
|
||||
asRange,
|
||||
asPosition,
|
||||
asDiagnosticSeverity,
|
||||
asHover,
|
||||
asCompletionResult,
|
||||
asCompletionItem,
|
||||
asTextEdit,
|
||||
asTextEdits,
|
||||
asSignatureHelp,
|
||||
asSignatureInformations,
|
||||
asSignatureInformation,
|
||||
asParameterInformations,
|
||||
asParameterInformation,
|
||||
asDefinitionResult,
|
||||
asLocation,
|
||||
asReferences,
|
||||
asDocumentHighlights,
|
||||
asDocumentHighlight,
|
||||
asDocumentHighlightKind,
|
||||
asSymbolInformations,
|
||||
asSymbolInformation,
|
||||
asCommand,
|
||||
asCommands,
|
||||
asCodeLens,
|
||||
asCodeLenses,
|
||||
asWorkspaceEdit,
|
||||
asDocumentLink,
|
||||
asDocumentLinks,
|
||||
asConnectionSummary,
|
||||
asServerCapabilities,
|
||||
asProviderMetadata,
|
||||
asScriptingResult,
|
||||
asObjectExplorerSession,
|
||||
asObjectExplorerCreateSessionResponse,
|
||||
asObjectExplorerNodeInfo,
|
||||
asObjectExplorerCloseSessionResponse,
|
||||
asListTasksResponse,
|
||||
asTaskInfo,
|
||||
asRestorePlanResponse,
|
||||
asRestoreResponse,
|
||||
asRestoreConfigInfo
|
||||
};
|
||||
}
|
||||
|
||||
// This for backward compatibility since we exported the converter functions as API.
|
||||
const defaultConverter = createConverter();
|
||||
|
||||
export const asDiagnostics: (diagnostics: ls.Diagnostic[]) => code.Diagnostic[] = defaultConverter.asDiagnostics;
|
||||
export const asDiagnostic: (diagnostic: ls.Diagnostic) => code.Diagnostic = defaultConverter.asDiagnostic;
|
||||
export const asRange: (value: ls.Range) => code.Range = defaultConverter.asRange;
|
||||
export const asPosition: (value: ls.Position) => code.Position = defaultConverter.asPosition;
|
||||
export const asDiagnosticSeverity: (value: number) => code.DiagnosticSeverity = defaultConverter.asDiagnosticSeverity;
|
||||
export const asHover: (hover: ls.Hover) => code.Hover = defaultConverter.asHover;
|
||||
export const asCompletionResult: (result: ls.CompletionItem[] | ls.CompletionList) => code.CompletionItem[] | code.CompletionList = defaultConverter.asCompletionResult;
|
||||
export const asCompletionItem: (item: ls.CompletionItem) => ProtocolCompletionItem = defaultConverter.asCompletionItem;
|
||||
export const asTextEdit: (edit: ls.TextEdit) => code.TextEdit = defaultConverter.asTextEdit;
|
||||
export const asTextEdits: (items: ls.TextEdit[]) => code.TextEdit[] = defaultConverter.asTextEdits;
|
||||
export const asSignatureHelp: (item: ls.SignatureHelp) => code.SignatureHelp = defaultConverter.asSignatureHelp;
|
||||
export const asSignatureInformations: (items: ls.SignatureInformation[]) => code.SignatureInformation[] = defaultConverter.asSignatureInformations;
|
||||
export const asSignatureInformation: (item: ls.SignatureInformation) => code.SignatureInformation = defaultConverter.asSignatureInformation;
|
||||
export const asParameterInformations: (item: ls.ParameterInformation[]) => code.ParameterInformation[] = defaultConverter.asParameterInformations;
|
||||
export const asParameterInformation: (item: ls.ParameterInformation) => code.ParameterInformation = defaultConverter.asParameterInformation;
|
||||
export const asDefinitionResult: (item: ls.Definition) => code.Definition = defaultConverter.asDefinitionResult;
|
||||
export const asLocation: (item: ls.Location) => code.Location = defaultConverter.asLocation;
|
||||
export const asReferences: (values: ls.Location[]) => code.Location[] = defaultConverter.asReferences;
|
||||
export const asDocumentHighlights: (values: ls.DocumentHighlight[]) => code.DocumentHighlight[] = defaultConverter.asDocumentHighlights;
|
||||
export const asDocumentHighlight: (item: ls.DocumentHighlight) => code.DocumentHighlight = defaultConverter.asDocumentHighlight;
|
||||
export const asDocumentHighlightKind: (item: ls.DocumentHighlightKind) => code.DocumentHighlightKind = defaultConverter.asDocumentHighlightKind;
|
||||
export const asSymbolInformations: (values: ls.SymbolInformation[], uri?: code.Uri) => code.SymbolInformation[] = defaultConverter.asSymbolInformations;
|
||||
export const asSymbolInformation: (item: ls.SymbolInformation, uri?: code.Uri) => code.SymbolInformation = defaultConverter.asSymbolInformation;
|
||||
export const asCommand: (item: ls.Command) => code.Command = defaultConverter.asCommand;
|
||||
export const asCommands: (items: ls.Command[]) => code.Command[] = defaultConverter.asCommands;
|
||||
export const asCodeLens: (item: ls.CodeLens) => code.CodeLens = defaultConverter.asCodeLens;
|
||||
export const asCodeLenses: (items: ls.CodeLens[]) => code.CodeLens[] = defaultConverter.asCodeLenses;
|
||||
export const asWorkspaceEdit: (item: ls.WorkspaceEdit) => code.WorkspaceEdit = defaultConverter.asWorkspaceEdit;
|
||||
export const asDocumentLink: (item: ls.DocumentLink) => code.DocumentLink = defaultConverter.asDocumentLink;
|
||||
export const asDocumentLinks: (item: ls.DocumentLink[]) => code.DocumentLink[] = defaultConverter.asDocumentLinks;
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": false,
|
||||
"inlineSources": false,
|
||||
"declaration": true,
|
||||
"stripInternal": true,
|
||||
"outDir": "../lib"
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
// Type definitions for es6-promise
|
||||
// Project: https://github.com/jakearchibald/ES6-Promise
|
||||
// Definitions by: François de Campredon <https://github.com/fdecampredon/>, vvakame <https://github.com/vvakame>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
|
||||
interface Thenable<T> {
|
||||
then<U>(onFulfilled?: (value: T) => U | Thenable<U>, onRejected?: (error: any) => U | Thenable<U>): Thenable<U>;
|
||||
then<U>(onFulfilled?: (value: T) => U | Thenable<U>, onRejected?: (error: any) => void): Thenable<U>;
|
||||
}
|
||||
|
||||
declare class Promise<T> implements Thenable<T> {
|
||||
/**
|
||||
* If you call resolve in the body of the callback passed to the constructor,
|
||||
* your promise is fulfilled with result object passed to resolve.
|
||||
* If you call reject your promise is rejected with the object passed to reject.
|
||||
* For consistency and debugging (eg stack traces), obj should be an instanceof Error.
|
||||
* Any errors thrown in the constructor callback will be implicitly passed to reject().
|
||||
*/
|
||||
constructor(callback: (resolve : (value?: T | Thenable<T>) => void, reject: (error?: any) => void) => void);
|
||||
|
||||
/**
|
||||
* onFulfilled is called when/if "promise" resolves. onRejected is called when/if "promise" rejects.
|
||||
* Both are optional, if either/both are omitted the next onFulfilled/onRejected in the chain is called.
|
||||
* Both callbacks have a single parameter , the fulfillment value or rejection reason.
|
||||
* "then" returns a new promise equivalent to the value you return from onFulfilled/onRejected after being passed through Promise.resolve.
|
||||
* If an error is thrown in the callback, the returned promise rejects with that error.
|
||||
*
|
||||
* @param onFulfilled called when/if "promise" resolves
|
||||
* @param onRejected called when/if "promise" rejects
|
||||
*/
|
||||
then<U>(onFulfilled?: (value: T) => U | Thenable<U>, onRejected?: (error: any) => U | Thenable<U>): Promise<U>;
|
||||
then<U>(onFulfilled?: (value: T) => U | Thenable<U>, onRejected?: (error: any) => void): Promise<U>;
|
||||
|
||||
/**
|
||||
* Sugar for promise.then(undefined, onRejected)
|
||||
*
|
||||
* @param onRejected called when/if "promise" rejects
|
||||
*/
|
||||
catch<U>(onRejected?: (error: any) => U | Thenable<U>): Promise<U>;
|
||||
}
|
||||
|
||||
declare namespace Promise {
|
||||
/**
|
||||
* Make a new promise from the thenable.
|
||||
* A thenable is promise-like in as far as it has a "then" method.
|
||||
*/
|
||||
function resolve<T>(value?: T | Thenable<T>): Promise<T>;
|
||||
|
||||
/**
|
||||
* Make a promise that rejects to obj. For consistency and debugging (eg stack traces), obj should be an instanceof Error
|
||||
*/
|
||||
function reject(error: any): Promise<any>;
|
||||
function reject<T>(error: T): Promise<T>;
|
||||
|
||||
/**
|
||||
* Make a promise that fulfills when every item in the array fulfills, and rejects if (and when) any item rejects.
|
||||
* the array passed to all can be a mixture of promise-like objects and other objects.
|
||||
* The fulfillment value is an array (in order) of fulfillment values. The rejection value is the first rejection value.
|
||||
*/
|
||||
function all<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>, T6 | Thenable<T6>, T7 | Thenable<T7>, T8 | Thenable<T8>, T9 | Thenable<T9>, T10 | Thenable<T10>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>;
|
||||
function all<T1, T2, T3, T4, T5, T6, T7, T8, T9>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>, T6 | Thenable<T6>, T7 | Thenable<T7>, T8 | Thenable<T8>, T9 | Thenable<T9>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>;
|
||||
function all<T1, T2, T3, T4, T5, T6, T7, T8>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>, T6 | Thenable<T6>, T7 | Thenable<T7>, T8 | Thenable<T8>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>;
|
||||
function all<T1, T2, T3, T4, T5, T6, T7>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>, T6 | Thenable<T6>, T7 | Thenable<T7>]): Promise<[T1, T2, T3, T4, T5, T6, T7]>;
|
||||
function all<T1, T2, T3, T4, T5, T6>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>, T6 | Thenable<T6>]): Promise<[T1, T2, T3, T4, T5, T6]>;
|
||||
function all<T1, T2, T3, T4, T5>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>]): Promise<[T1, T2, T3, T4, T5]>;
|
||||
function all<T1, T2, T3, T4>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>]): Promise<[T1, T2, T3, T4]>;
|
||||
function all<T1, T2, T3>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>]): Promise<[T1, T2, T3]>;
|
||||
function all<T1, T2>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>]): Promise<[T1, T2]>;
|
||||
function all<T>(values: (T | Thenable<T>)[]): Promise<T[]>;
|
||||
|
||||
/**
|
||||
* Make a Promise that fulfills when any item fulfills, and rejects if any item rejects.
|
||||
*/
|
||||
function race<T>(promises: (T | Thenable<T>)[]): Promise<T>;
|
||||
}
|
||||
|
||||
declare module 'es6-promise' {
|
||||
var foo: typeof Promise; // Temp variable to reference Promise in local context
|
||||
namespace rsvp {
|
||||
export var Promise: typeof foo;
|
||||
export function polyfill(): void;
|
||||
}
|
||||
export = rsvp;
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"lib": [
|
||||
"es5",
|
||||
"dom"
|
||||
],
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"strictNullChecks": false,
|
||||
"baseUrl": "../",
|
||||
"typeRoots": [
|
||||
"../"
|
||||
],
|
||||
"types": [],
|
||||
"noEmit": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"es6-promise-tests.ts"
|
||||
]
|
||||
}
|
||||
@@ -1,82 +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';
|
||||
|
||||
export interface ITask<T> {
|
||||
(): T;
|
||||
}
|
||||
|
||||
export class Delayer<T> {
|
||||
|
||||
public defaultDelay: number;
|
||||
private timeout: NodeJS.Timer;
|
||||
private completionPromise: Promise<T>;
|
||||
private onSuccess: (value?: T | Thenable<T>) => void;
|
||||
private task: ITask<T>;
|
||||
|
||||
constructor(defaultDelay: number) {
|
||||
this.defaultDelay = defaultDelay;
|
||||
this.timeout = null;
|
||||
this.completionPromise = null;
|
||||
this.onSuccess = null;
|
||||
this.task = null;
|
||||
}
|
||||
|
||||
public trigger(task: ITask<T>, delay: number = this.defaultDelay): Promise<T> {
|
||||
this.task = task;
|
||||
if (delay >= 0) {
|
||||
this.cancelTimeout();
|
||||
}
|
||||
|
||||
if (!this.completionPromise) {
|
||||
this.completionPromise = new Promise<T>((resolve) => {
|
||||
this.onSuccess = resolve
|
||||
}).then(() => {
|
||||
this.completionPromise = null;
|
||||
this.onSuccess = null;
|
||||
var result = this.task();
|
||||
this.task = null;
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
if (delay >= 0 || this.timeout === null) {
|
||||
this.timeout = setTimeout(() => {
|
||||
this.timeout = null;
|
||||
this.onSuccess(null);
|
||||
}, delay >= 0 ? delay : this.defaultDelay);
|
||||
}
|
||||
|
||||
return this.completionPromise;
|
||||
}
|
||||
|
||||
public forceDelivery(): T {
|
||||
if (!this.completionPromise) {
|
||||
return null;
|
||||
}
|
||||
this.cancelTimeout();
|
||||
let result: T = this.task();
|
||||
this.completionPromise = null;
|
||||
this.onSuccess = null;
|
||||
this.task = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
public isTriggered(): boolean {
|
||||
return this.timeout !== null;
|
||||
}
|
||||
|
||||
public cancel(): void {
|
||||
this.cancelTimeout();
|
||||
this.completionPromise = null;
|
||||
}
|
||||
|
||||
private cancelTimeout(): void {
|
||||
if (this.timeout !== null) {
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,123 +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 path = require('path');
|
||||
import os = require('os');
|
||||
import net = require('net');
|
||||
import cp = require('child_process');
|
||||
|
||||
export interface IForkOptions {
|
||||
cwd?: string;
|
||||
env?: any;
|
||||
encoding?: string;
|
||||
execArgv?: string[];
|
||||
}
|
||||
|
||||
function makeRandomHexString(length: number): string {
|
||||
let chars = ['0', '1', '2', '3', '4', '5', '6', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
|
||||
let result = '';
|
||||
for (let i = 0; i < length; i++) {
|
||||
let idx = Math.floor(chars.length * Math.random());
|
||||
result += chars[idx];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function generatePipeName(): string {
|
||||
var randomName = 'vscode-' + makeRandomHexString(40);
|
||||
if (process.platform === 'win32') {
|
||||
return '\\\\.\\pipe\\' + randomName + '-sock';
|
||||
}
|
||||
|
||||
// Mac/Unix: use socket file
|
||||
return path.join(os.tmpdir(), randomName + '.sock');
|
||||
}
|
||||
|
||||
function generatePatchedEnv(env: any, stdInPipeName: string, stdOutPipeName: string): any {
|
||||
// Set the two unique pipe names and the electron flag as process env
|
||||
|
||||
var newEnv: any = {};
|
||||
for (var key in env) {
|
||||
newEnv[key] = env[key];
|
||||
}
|
||||
|
||||
newEnv['STDIN_PIPE_NAME'] = stdInPipeName;
|
||||
newEnv['STDOUT_PIPE_NAME'] = stdOutPipeName;
|
||||
newEnv['ATOM_SHELL_INTERNAL_RUN_AS_NODE'] = '1';
|
||||
|
||||
return newEnv;
|
||||
}
|
||||
|
||||
export function fork(modulePath: string, args: string[], options: IForkOptions, callback: (error: any, cp: cp.ChildProcess) => void): void {
|
||||
|
||||
var callbackCalled = false;
|
||||
var resolve = (result: cp.ChildProcess) => {
|
||||
if (callbackCalled) {
|
||||
return;
|
||||
}
|
||||
callbackCalled = true;
|
||||
callback(null, result);
|
||||
};
|
||||
var reject = (err: any) => {
|
||||
if (callbackCalled) {
|
||||
return;
|
||||
}
|
||||
callbackCalled = true;
|
||||
callback(err, null);
|
||||
};
|
||||
|
||||
// Generate two unique pipe names
|
||||
var stdInPipeName = generatePipeName();
|
||||
var stdOutPipeName = generatePipeName();
|
||||
|
||||
var newEnv = generatePatchedEnv(options.env || process.env, stdInPipeName, stdOutPipeName);
|
||||
|
||||
var childProcess: cp.ChildProcess;
|
||||
|
||||
// Begin listening to stdout pipe
|
||||
var server = net.createServer((stream) => {
|
||||
// The child process will write exactly one chunk with content `ready` when it has installed a listener to the stdin pipe
|
||||
|
||||
stream.once('data', (chunk: Buffer) => {
|
||||
// The child process is sending me the `ready` chunk, time to connect to the stdin pipe
|
||||
childProcess.stdin = <any>net.connect(stdInPipeName);
|
||||
|
||||
// From now on the childProcess.stdout is available for reading
|
||||
childProcess.stdout = stream;
|
||||
|
||||
resolve(childProcess);
|
||||
});
|
||||
});
|
||||
server.listen(stdOutPipeName);
|
||||
|
||||
var serverClosed = false;
|
||||
var closeServer = () => {
|
||||
if (serverClosed) {
|
||||
return;
|
||||
}
|
||||
serverClosed = true;
|
||||
server.close();
|
||||
}
|
||||
|
||||
// Create the process
|
||||
let bootstrapperPath = path.join(__dirname, 'electronForkStart');
|
||||
childProcess = cp.fork(bootstrapperPath, [modulePath].concat(args), <any>{
|
||||
silent: true,
|
||||
cwd: options.cwd,
|
||||
env: newEnv,
|
||||
execArgv: options.execArgv
|
||||
});
|
||||
|
||||
childProcess.once('error', (err: Error) => {
|
||||
closeServer();
|
||||
reject(err);
|
||||
});
|
||||
|
||||
childProcess.once('exit', (err: Error) => {
|
||||
closeServer();
|
||||
reject(err);
|
||||
});
|
||||
}
|
||||
@@ -1,183 +0,0 @@
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
var net = require('net'),
|
||||
fs = require('fs'),
|
||||
stream = require('stream'),
|
||||
util = require('util');
|
||||
|
||||
var ENABLE_LOGGING = false;
|
||||
|
||||
var log = (function () {
|
||||
if (!ENABLE_LOGGING) {
|
||||
return function () { };
|
||||
}
|
||||
var isFirst = true;
|
||||
var LOG_LOCATION = 'C:\\stdFork.log';
|
||||
return function log(str) {
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
fs.writeFileSync(LOG_LOCATION, str + '\n');
|
||||
return;
|
||||
}
|
||||
fs.appendFileSync(LOG_LOCATION, str + '\n');
|
||||
}
|
||||
})();
|
||||
|
||||
var stdInPipeName = process.env['STDIN_PIPE_NAME'];
|
||||
var stdOutPipeName = process.env['STDOUT_PIPE_NAME'];
|
||||
|
||||
log('STDIN_PIPE_NAME: ' + stdInPipeName);
|
||||
log('STDOUT_PIPE_NAME: ' + stdOutPipeName);
|
||||
log('ATOM_SHELL_INTERNAL_RUN_AS_NODE: ' + process.env['ATOM_SHELL_INTERNAL_RUN_AS_NODE']);
|
||||
|
||||
// stdout redirection to named pipe
|
||||
(function () {
|
||||
log('Beginning stdout redirection...');
|
||||
|
||||
// Create a writing stream to the stdout pipe
|
||||
var stdOutStream = net.connect(stdOutPipeName);
|
||||
|
||||
// unref stdOutStream to behave like a normal standard out
|
||||
stdOutStream.unref();
|
||||
|
||||
// handle process.stdout
|
||||
(<any>process).__defineGetter__('stdout', function () { return stdOutStream; });
|
||||
|
||||
// handle process.stderr
|
||||
(<any>process).__defineGetter__('stderr', function () { return stdOutStream; });
|
||||
|
||||
var fsWriteSyncString = function (fd, str, position, encoding) {
|
||||
// fs.writeSync(fd, string[, position[, encoding]]);
|
||||
var buf = new Buffer(str, encoding || 'utf8');
|
||||
return fsWriteSyncBuffer(fd, buf, 0, buf.length);
|
||||
};
|
||||
|
||||
var fsWriteSyncBuffer = function (fd, buffer, off, len) {
|
||||
off = Math.abs(off | 0);
|
||||
len = Math.abs(len | 0);
|
||||
|
||||
// fs.writeSync(fd, buffer, offset, length[, position]);
|
||||
var buffer_length = buffer.length;
|
||||
|
||||
if (off > buffer_length) {
|
||||
throw new Error('offset out of bounds');
|
||||
}
|
||||
if (len > buffer_length) {
|
||||
throw new Error('length out of bounds');
|
||||
}
|
||||
if (((off + len) | 0) < off) {
|
||||
throw new Error('off + len overflow');
|
||||
}
|
||||
if (buffer_length - off < len) {
|
||||
// Asking for more than is left over in the buffer
|
||||
throw new Error('off + len > buffer.length');
|
||||
}
|
||||
|
||||
var slicedBuffer = buffer;
|
||||
if (off !== 0 || len !== buffer_length) {
|
||||
slicedBuffer = buffer.slice(off, off + len);
|
||||
}
|
||||
|
||||
stdOutStream.write(slicedBuffer);
|
||||
return slicedBuffer.length;
|
||||
};
|
||||
|
||||
// handle fs.writeSync(1, ...)
|
||||
var originalWriteSync = fs.writeSync;
|
||||
fs.writeSync = function (fd, data, position, encoding) {
|
||||
if (fd !== 1) {
|
||||
return originalWriteSync.apply(fs, arguments);
|
||||
}
|
||||
// usage:
|
||||
// fs.writeSync(fd, buffer, offset, length[, position]);
|
||||
// OR
|
||||
// fs.writeSync(fd, string[, position[, encoding]]);
|
||||
|
||||
if (data instanceof Buffer) {
|
||||
return fsWriteSyncBuffer.apply(null, arguments);
|
||||
}
|
||||
|
||||
// For compatibility reasons with fs.writeSync, writing null will write "null", etc
|
||||
if (typeof data !== 'string') {
|
||||
data += '';
|
||||
}
|
||||
|
||||
return fsWriteSyncString.apply(null, arguments);
|
||||
};
|
||||
|
||||
log('Finished defining process.stdout, process.stderr and fs.writeSync');
|
||||
})();
|
||||
|
||||
// stdin redirection to named pipe
|
||||
(function () {
|
||||
|
||||
// Begin listening to stdin pipe
|
||||
var server = net.createServer(function (stream) {
|
||||
// Stop accepting new connections, keep the existing one alive
|
||||
server.close();
|
||||
|
||||
log('Parent process has connected to my stdin. All should be good now.');
|
||||
|
||||
// handle process.stdin
|
||||
(<any>process).__defineGetter__('stdin', function () {
|
||||
return stream;
|
||||
});
|
||||
|
||||
// Remove myself from process.argv
|
||||
process.argv.splice(1, 1);
|
||||
|
||||
// Load the actual program
|
||||
var program = process.argv[1];
|
||||
log('Loading program: ' + program);
|
||||
|
||||
// Unset the custom environmental variables that should not get inherited
|
||||
delete process.env['STDIN_PIPE_NAME'];
|
||||
delete process.env['STDOUT_PIPE_NAME'];
|
||||
delete process.env['ATOM_SHELL_INTERNAL_RUN_AS_NODE'];
|
||||
|
||||
require(program);
|
||||
|
||||
log('Finished loading program.');
|
||||
|
||||
var stdinIsReferenced = true;
|
||||
var timer = setInterval(function () {
|
||||
var listenerCount = (
|
||||
stream.listeners('data').length +
|
||||
stream.listeners('end').length +
|
||||
stream.listeners('close').length +
|
||||
stream.listeners('error').length
|
||||
);
|
||||
// log('listenerCount: ' + listenerCount);
|
||||
if (listenerCount <= 1) {
|
||||
// No more "actual" listeners, only internal node
|
||||
if (stdinIsReferenced) {
|
||||
stdinIsReferenced = false;
|
||||
// log('unreferencing stream!!!');
|
||||
stream.unref();
|
||||
}
|
||||
} else {
|
||||
// There are "actual" listeners
|
||||
if (!stdinIsReferenced) {
|
||||
stdinIsReferenced = true;
|
||||
stream.ref();
|
||||
}
|
||||
}
|
||||
// log(
|
||||
// '' + stream.listeners('data').length +
|
||||
// ' ' + stream.listeners('end').length +
|
||||
// ' ' + stream.listeners('close').length +
|
||||
// ' ' + stream.listeners('error').length
|
||||
// );
|
||||
}, 1000);
|
||||
timer.unref();
|
||||
});
|
||||
|
||||
|
||||
server.listen(stdInPipeName, function () {
|
||||
// signal via stdout that the parent process can now begin writing to stdin pipe
|
||||
process.stdout.write('ready');
|
||||
});
|
||||
|
||||
})();
|
||||
@@ -1,55 +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 toString = Object.prototype.toString;
|
||||
|
||||
export function defined(value: any): boolean {
|
||||
return typeof value !== 'undefined';
|
||||
}
|
||||
|
||||
export function undefined(value: any): boolean {
|
||||
return typeof value === 'undefined';
|
||||
}
|
||||
|
||||
export function nil(value: any): boolean {
|
||||
return value === null;
|
||||
}
|
||||
|
||||
export function boolean(value: any): value is boolean {
|
||||
return value === true || value === false;
|
||||
}
|
||||
|
||||
export function string(value: any): value is string {
|
||||
return toString.call(value) === '[object String]';
|
||||
}
|
||||
|
||||
export function number(value: any): value is number {
|
||||
return toString.call(value) === '[object Number]';
|
||||
}
|
||||
|
||||
export function error(value: any): value is Error {
|
||||
return toString.call(value) === '[object Error]';
|
||||
}
|
||||
|
||||
export function func(value: any): value is Function {
|
||||
return toString.call(value) === '[object Function]';
|
||||
}
|
||||
|
||||
export function array<T>(value: any): value is T[] {
|
||||
return Array.isArray(value);
|
||||
}
|
||||
|
||||
export function stringArray(value: any): value is string[] {
|
||||
return array(value) && (<any[]>value).every(elem => string(elem));
|
||||
}
|
||||
|
||||
export function typedArray<T>(value: any, check: (value: any) => boolean): value is T[] {
|
||||
return Array.isArray(value) && (<any[]>value).every(check);
|
||||
}
|
||||
|
||||
export function thenable<T>(value: any): value is Thenable<T> {
|
||||
return value && func(value.then);
|
||||
}
|
||||
@@ -1,44 +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 cp from 'child_process';
|
||||
import ChildProcess = cp.ChildProcess;
|
||||
|
||||
import { join } from 'path';
|
||||
|
||||
const isWindows = (process.platform === 'win32');
|
||||
const isMacintosh = (process.platform === 'darwin');
|
||||
const isLinux = (process.platform === 'linux');
|
||||
export function terminate(process: ChildProcess, cwd?: string): boolean {
|
||||
if (isWindows) {
|
||||
try {
|
||||
// This we run in Atom execFileSync is available.
|
||||
// Ignore stderr since this is otherwise piped to parent.stderr
|
||||
// which might be already closed.
|
||||
let options: any = {
|
||||
stdio: ['pipe', 'pipe', 'ignore']
|
||||
};
|
||||
if (cwd) {
|
||||
options.cwd = cwd
|
||||
}
|
||||
(<any>cp).execFileSync('taskkill', ['/T', '/F', '/PID', process.pid.toString()], options);
|
||||
return true;
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
} else if (isLinux || isMacintosh) {
|
||||
try {
|
||||
var cmd = join(__dirname, 'terminateProcess.sh');
|
||||
var result = (<any>cp).spawnSync(cmd, [process.pid.toString()]);
|
||||
return result.error ? false : true;
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
process.kill('SIGKILL');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
#!/bin/bash
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
||||
terminateTree() {
|
||||
for cpid in $(pgrep -P $1); do
|
||||
terminateTree $cpid
|
||||
done
|
||||
kill -9 $1 > /dev/null 2>&1
|
||||
}
|
||||
|
||||
for pid in $*; do
|
||||
terminateTree $pid
|
||||
done
|
||||
@@ -1,31 +0,0 @@
|
||||
THIRD-PARTY SOFTWARE NOTICES AND INFORMATION
|
||||
For Microsoft vscode-languageclient
|
||||
|
||||
This project incorporates material from the project(s) listed below (collectively, “Third Party Code”).
|
||||
Microsoft is not the original author of the Third Party Code. The original copyright notice and license
|
||||
under which Microsoft received such Third Party Code are set out below. This Third Party Code is licensed
|
||||
to you under their original license terms set forth below. Microsoft reserves all other rights not expressly
|
||||
granted, whether by implication, estoppel or otherwise.
|
||||
|
||||
1. DefinitelyTyped version 0.0.1 (https://github.com/borisyankov/DefinitelyTyped)
|
||||
|
||||
This project is licensed under the MIT license.
|
||||
Copyrights are respective of each contributor listed at the beginning of each definition file.
|
||||
|
||||
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.
|
||||
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"rules": {
|
||||
"indent": [
|
||||
2,
|
||||
"tab"
|
||||
],
|
||||
"quotes": [
|
||||
2,
|
||||
"single"
|
||||
],
|
||||
"linebreak-style": [
|
||||
2,
|
||||
"windows"
|
||||
],
|
||||
"semi": [
|
||||
2,
|
||||
"always"
|
||||
]
|
||||
},
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"extends": "eslint:recommended"
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
.vscode/
|
||||
lib/test/
|
||||
lib/*.map
|
||||
src/
|
||||
test/
|
||||
.eslintrc
|
||||
.gitignore
|
||||
gulpfile.js
|
||||
tsd.json
|
||||
32
dataprotocol-node/jsonrpc/.vscode/launch.json
vendored
32
dataprotocol-node/jsonrpc/.vscode/launch.json
vendored
@@ -1,32 +0,0 @@
|
||||
{
|
||||
"version": "0.1.0",
|
||||
// List of configurations. Add new configurations or edit existing ones.
|
||||
// ONLY "node" and "mono" are supported, change "type" to switch.
|
||||
"configurations": [
|
||||
{
|
||||
"request": "launch",
|
||||
// Name of configuration; appears in the launch configuration drop down menu.
|
||||
"name": "Mocha",
|
||||
// Type of configuration. Possible values: "node", "mono".
|
||||
"type": "node",
|
||||
// Workspace relative or absolute path to the program.
|
||||
"program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
|
||||
// Automatically stop program after launch.
|
||||
"stopOnEntry": false,
|
||||
// Command line arguments passed to the program.
|
||||
"args": ["--timeout", "999999"],
|
||||
// Workspace relative or absolute path to the working directory of the program being debugged. Default is the current workspace.
|
||||
"cwd": "${workspaceRoot}",
|
||||
// Workspace relative or absolute path to the runtime executable to be used. Default is the runtime executable on the PATH.
|
||||
"runtimeExecutable": null,
|
||||
// Optional arguments passed to the runtime executable.
|
||||
"runtimeArgs": [],
|
||||
// Environment variables passed to the program.
|
||||
"env": { },
|
||||
// Use JavaScript source maps (if they exist).
|
||||
"sourceMaps": true,
|
||||
// If JavaScript source maps are enabled, the generated code is expected in this directory.
|
||||
"outDir": "${workspaceRoot}/lib"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
// Place your settings in this file to overwrite default and user settings.
|
||||
{
|
||||
"javascript.validate.enable": false,
|
||||
"files.trimTrailingWhitespace": true,
|
||||
"eslint.enable": false,
|
||||
"editor.insertSpaces": false,
|
||||
"editor.tabSize": 4,
|
||||
"typescript.tsdk": "./node_modules/typescript/lib"
|
||||
}
|
||||
9
dataprotocol-node/jsonrpc/.vscode/tasks.json
vendored
9
dataprotocol-node/jsonrpc/.vscode/tasks.json
vendored
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"version": "0.1.0",
|
||||
"command": "npm",
|
||||
"isShellCommand": true,
|
||||
"args": ["run", "watch"],
|
||||
"showOutput": "silent",
|
||||
"isWatching": true,
|
||||
"problemMatcher": "$tsc-watch"
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
# Microsoft Data Management Protocol - Node
|
||||
|
||||
## License
|
||||
[MIT](https://github.com/Microsoft/carbon/blob/dev/license.txt)
|
||||
@@ -1,29 +0,0 @@
|
||||
{
|
||||
"name": "dataprotocol-jsonrpc",
|
||||
"description": "A json rpc implementation over streams",
|
||||
"version": "2.4.0",
|
||||
"author": "Microsoft Corporation",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/vscode-languageserver-node.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/Microsoft/vscode-languageserver-node/issues"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.0.0 || >=6.0.0"
|
||||
},
|
||||
"main": "./lib/main.js",
|
||||
"typings": "./lib/main",
|
||||
"devDependencies": {
|
||||
"mocha": "^3.0.2",
|
||||
"typescript": "2.0.3"
|
||||
},
|
||||
"scripts": {
|
||||
"prepublish": "tsc -p ./src",
|
||||
"compile": "tsc -p ./src",
|
||||
"watch": "tsc -w -p ./src",
|
||||
"test": "mocha"
|
||||
}
|
||||
}
|
||||
@@ -1,97 +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 { Event, Emitter } from './events';
|
||||
|
||||
export interface CancellationToken {
|
||||
/**
|
||||
* Is `true` when the token has been cancelled, `false` otherwise.
|
||||
*/
|
||||
isCancellationRequested: boolean;
|
||||
|
||||
/**
|
||||
* An [event](#Event) which fires upon cancellation.
|
||||
*/
|
||||
onCancellationRequested: Event<any>;
|
||||
}
|
||||
|
||||
export namespace CancellationToken {
|
||||
|
||||
export const None: CancellationToken = Object.freeze({
|
||||
isCancellationRequested: false,
|
||||
onCancellationRequested: Event.None
|
||||
});
|
||||
|
||||
export const Cancelled: CancellationToken = Object.freeze({
|
||||
isCancellationRequested: true,
|
||||
onCancellationRequested: Event.None
|
||||
});
|
||||
}
|
||||
|
||||
const shortcutEvent: Event<any> = Object.freeze(function (callback, context?) {
|
||||
let handle = setTimeout(callback.bind(context), 0);
|
||||
return { dispose() { clearTimeout(handle); } };
|
||||
});
|
||||
|
||||
class MutableToken implements CancellationToken {
|
||||
|
||||
private _isCancelled: boolean = false;
|
||||
private _emitter: Emitter<any>;
|
||||
|
||||
public cancel() {
|
||||
if (!this._isCancelled) {
|
||||
this._isCancelled = true;
|
||||
if (this._emitter) {
|
||||
this._emitter.fire(undefined);
|
||||
this._emitter = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get isCancellationRequested(): boolean {
|
||||
return this._isCancelled;
|
||||
}
|
||||
|
||||
get onCancellationRequested(): Event<any> {
|
||||
if (this._isCancelled) {
|
||||
return shortcutEvent;
|
||||
}
|
||||
if (!this._emitter) {
|
||||
this._emitter = new Emitter<any>();
|
||||
}
|
||||
return this._emitter.event;
|
||||
}
|
||||
}
|
||||
|
||||
export class CancellationTokenSource {
|
||||
|
||||
private _token: CancellationToken;
|
||||
|
||||
get token(): CancellationToken {
|
||||
if (!this._token) {
|
||||
// be lazy and create the token only when
|
||||
// actually needed
|
||||
this._token = new MutableToken();
|
||||
}
|
||||
return this._token;
|
||||
}
|
||||
|
||||
cancel(): void {
|
||||
if (!this._token) {
|
||||
// save an object by returning the default
|
||||
// cancelled token when cancellation happens
|
||||
// before someone asks for the token
|
||||
this._token = CancellationToken.Cancelled;
|
||||
} else {
|
||||
(<MutableToken>this._token).cancel();
|
||||
}
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.cancel();
|
||||
}
|
||||
}
|
||||
@@ -1,213 +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';
|
||||
|
||||
export interface Disposable {
|
||||
/**
|
||||
* Dispose this object.
|
||||
*/
|
||||
dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a typed event.
|
||||
*/
|
||||
export interface Event<T> {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param listener The listener function will be call when the event happens.
|
||||
* @param thisArgs The 'this' which will be used when calling the event listener.
|
||||
* @param disposables An array to which a {{IDisposable}} will be added. The
|
||||
* @return
|
||||
*/
|
||||
(listener: (e: T) => any, thisArgs?: any, disposables?: Disposable[]): Disposable;
|
||||
}
|
||||
|
||||
export namespace Event {
|
||||
const _disposable = { dispose() { } };
|
||||
export const None: Event<any> = function () { return _disposable; };
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a type which can release resources, such
|
||||
* as event listening or a timer.
|
||||
*/
|
||||
class DisposableImpl implements Disposable {
|
||||
|
||||
/**
|
||||
* Combine many disposable-likes into one. Use this method
|
||||
* when having objects with a dispose function which are not
|
||||
* instances of Disposable.
|
||||
*
|
||||
* @return Returns a new disposable which, upon dispose, will
|
||||
* dispose all provides disposable-likes.
|
||||
*/
|
||||
static from(...disposables: { dispose(): any }[]): DisposableImpl {
|
||||
return new DisposableImpl(function () {
|
||||
if (disposables) {
|
||||
for (let disposable of disposables) {
|
||||
disposable.dispose();
|
||||
}
|
||||
disposables = undefined;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private _callOnDispose: Function;
|
||||
|
||||
constructor(callOnDispose: Function) {
|
||||
this._callOnDispose = callOnDispose;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispose this object.
|
||||
*/
|
||||
dispose(): any {
|
||||
if (typeof this._callOnDispose === 'function') {
|
||||
this._callOnDispose();
|
||||
this._callOnDispose = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CallbackList {
|
||||
|
||||
private _callbacks: Function[];
|
||||
private _contexts: any[];
|
||||
|
||||
public add(callback: Function, context: any = null, bucket?: Disposable[]): void {
|
||||
if (!this._callbacks) {
|
||||
this._callbacks = [];
|
||||
this._contexts = [];
|
||||
}
|
||||
this._callbacks.push(callback);
|
||||
this._contexts.push(context);
|
||||
|
||||
if (Array.isArray(bucket)) {
|
||||
bucket.push({ dispose: () => this.remove(callback, context) });
|
||||
}
|
||||
}
|
||||
|
||||
public remove(callback: Function, context: any = null): void {
|
||||
if (!this._callbacks) {
|
||||
return;
|
||||
}
|
||||
|
||||
var foundCallbackWithDifferentContext = false;
|
||||
for (var i = 0, len = this._callbacks.length; i < len; i++) {
|
||||
if (this._callbacks[i] === callback) {
|
||||
if (this._contexts[i] === context) {
|
||||
// callback & context match => remove it
|
||||
this._callbacks.splice(i, 1);
|
||||
this._contexts.splice(i, 1);
|
||||
return;
|
||||
} else {
|
||||
foundCallbackWithDifferentContext = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (foundCallbackWithDifferentContext) {
|
||||
throw new Error('When adding a listener with a context, you should remove it with the same context');
|
||||
}
|
||||
}
|
||||
|
||||
public invoke(...args: any[]): any[] {
|
||||
if (!this._callbacks) {
|
||||
return;
|
||||
}
|
||||
|
||||
var ret: any[] = [],
|
||||
callbacks = this._callbacks.slice(0),
|
||||
contexts = this._contexts.slice(0);
|
||||
|
||||
for (var i = 0, len = callbacks.length; i < len; i++) {
|
||||
try {
|
||||
ret.push(callbacks[i].apply(contexts[i], args));
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public isEmpty(): boolean {
|
||||
return !this._callbacks || this._callbacks.length === 0;
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._callbacks = undefined;
|
||||
this._contexts = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export interface EmitterOptions {
|
||||
onFirstListenerAdd?: Function;
|
||||
onLastListenerRemove?: Function;
|
||||
}
|
||||
|
||||
export class Emitter<T> {
|
||||
|
||||
private static _noop = function () { };
|
||||
|
||||
private _event: Event<T>;
|
||||
private _callbacks: CallbackList;
|
||||
|
||||
constructor(private _options?: EmitterOptions) {
|
||||
}
|
||||
|
||||
/**
|
||||
* For the public to allow to subscribe
|
||||
* to events from this Emitter
|
||||
*/
|
||||
get event(): Event<T> {
|
||||
if (!this._event) {
|
||||
this._event = (listener: (e: T) => any, thisArgs?: any, disposables?: Disposable[]) => {
|
||||
if (!this._callbacks) {
|
||||
this._callbacks = new CallbackList();
|
||||
}
|
||||
if (this._options && this._options.onFirstListenerAdd && this._callbacks.isEmpty()) {
|
||||
this._options.onFirstListenerAdd(this);
|
||||
}
|
||||
this._callbacks.add(listener, thisArgs);
|
||||
|
||||
let result: Disposable;
|
||||
result = {
|
||||
dispose: () => {
|
||||
this._callbacks.remove(listener, thisArgs);
|
||||
result.dispose = Emitter._noop;
|
||||
if (this._options && this._options.onLastListenerRemove && this._callbacks.isEmpty()) {
|
||||
this._options.onLastListenerRemove(this);
|
||||
}
|
||||
}
|
||||
};
|
||||
if (Array.isArray(disposables)) {
|
||||
disposables.push(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
}
|
||||
return this._event;
|
||||
}
|
||||
|
||||
/**
|
||||
* To be kept private to fire an event to
|
||||
* subscribers
|
||||
*/
|
||||
fire(event: T): any {
|
||||
if (this._callbacks) {
|
||||
this._callbacks.invoke.call(this._callbacks, event);
|
||||
}
|
||||
}
|
||||
|
||||
dispose() {
|
||||
if (this._callbacks) {
|
||||
this._callbacks.dispose();
|
||||
this._callbacks = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,47 +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 toString = Object.prototype.toString;
|
||||
|
||||
export function defined(value: any): boolean {
|
||||
return typeof value !== 'undefined';
|
||||
}
|
||||
|
||||
export function undefined(value: any): boolean {
|
||||
return typeof value === 'undefined';
|
||||
}
|
||||
|
||||
export function nil(value: any): boolean {
|
||||
return value === null;
|
||||
}
|
||||
|
||||
export function boolean(value: any): value is boolean {
|
||||
return value === true || value === false;
|
||||
}
|
||||
|
||||
export function string(value: any): value is string {
|
||||
return toString.call(value) === '[object String]';
|
||||
}
|
||||
|
||||
export function number(value: any): value is number {
|
||||
return toString.call(value) === '[object Number]';
|
||||
}
|
||||
|
||||
export function error(value: any): value is Error {
|
||||
return toString.call(value) === '[object Error]';
|
||||
}
|
||||
|
||||
export function func(value: any): value is Function {
|
||||
return toString.call(value) === '[object Function]';
|
||||
}
|
||||
|
||||
export function array<T>(value: any): value is T[] {
|
||||
return Array.isArray(value);
|
||||
}
|
||||
|
||||
export function stringArray(value: any): value is string[] {
|
||||
return array(value) && (<any[]>value).every(elem => string(elem));
|
||||
}
|
||||
@@ -1,576 +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 is from './is';
|
||||
|
||||
import {
|
||||
Message,
|
||||
RequestMessage, RequestType, isRequestMessage,
|
||||
ResponseMessage, isReponseMessage, ResponseError, ErrorCodes,
|
||||
NotificationMessage, NotificationType, isNotificationMessage
|
||||
} from './messages';
|
||||
|
||||
import { MessageReader, DataCallback, StreamMessageReader, IPCMessageReader } from './messageReader';
|
||||
import { MessageWriter, StreamMessageWriter, IPCMessageWriter } from './messageWriter';
|
||||
import { Disposable, Event, Emitter } from './events';
|
||||
import { CancellationTokenSource, CancellationToken } from './cancellation';
|
||||
|
||||
export {
|
||||
Message, ErrorCodes, ResponseError,
|
||||
RequestMessage, RequestType,
|
||||
NotificationMessage, NotificationType,
|
||||
MessageReader, DataCallback, StreamMessageReader, IPCMessageReader,
|
||||
MessageWriter, StreamMessageWriter, IPCMessageWriter,
|
||||
CancellationTokenSource, CancellationToken,
|
||||
Disposable, Event, Emitter
|
||||
}
|
||||
|
||||
interface CancelParams {
|
||||
/**
|
||||
* The request id to cancel.
|
||||
*/
|
||||
id: number | string;
|
||||
}
|
||||
|
||||
namespace CancelNotification {
|
||||
export const type: NotificationType<CancelParams> = { get method() { return '$/cancelRequest'; } };
|
||||
}
|
||||
|
||||
export interface RequestHandler<P, R, E> {
|
||||
(params: P, token: CancellationToken): R | ResponseError<E> | Thenable<R | ResponseError<E>>;
|
||||
}
|
||||
|
||||
export interface NotificationHandler<P> {
|
||||
(params: P): void;
|
||||
}
|
||||
|
||||
export interface Logger {
|
||||
error(message: string): void;
|
||||
warn(message: string): void;
|
||||
info(message: string): void;
|
||||
log(message: string): void;
|
||||
}
|
||||
|
||||
export enum Trace {
|
||||
Off, Messages, Verbose
|
||||
}
|
||||
|
||||
export type TraceValues = 'off' | 'messages' | 'verbose';
|
||||
export namespace Trace {
|
||||
export function fromString(value: string): Trace {
|
||||
value = value.toLowerCase();
|
||||
switch (value) {
|
||||
case 'off':
|
||||
return Trace.Off;
|
||||
case 'messages':
|
||||
return Trace.Messages;
|
||||
case 'verbose':
|
||||
return Trace.Verbose;
|
||||
default:
|
||||
return Trace.Off;
|
||||
}
|
||||
}
|
||||
|
||||
export function toString(value: Trace): TraceValues {
|
||||
switch (value) {
|
||||
case Trace.Off:
|
||||
return 'off';
|
||||
case Trace.Messages:
|
||||
return 'messages';
|
||||
case Trace.Verbose:
|
||||
return 'verbose';
|
||||
default:
|
||||
return 'off';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface SetTraceParams {
|
||||
value: TraceValues;
|
||||
}
|
||||
|
||||
export namespace SetTraceNotification {
|
||||
export const type: NotificationType<SetTraceParams> = { get method() { return '$/setTraceNotification'; } };
|
||||
}
|
||||
|
||||
export interface LogTraceParams {
|
||||
message: string;
|
||||
verbose?: string;
|
||||
}
|
||||
|
||||
export namespace LogTraceNotification {
|
||||
export const type: NotificationType<LogTraceParams> = { get method() { return '$/logTraceNotification'; } };
|
||||
}
|
||||
|
||||
export interface Tracer {
|
||||
log(message: string, data?: string): void;
|
||||
}
|
||||
|
||||
export interface MessageConnection {
|
||||
sendRequest<P, R, E>(type: RequestType<P, R, E>, params: P, token?: CancellationToken): Thenable<R>;
|
||||
onRequest<P, R, E>(type: RequestType<P, R, E>, handler: RequestHandler<P, R, E>): void;
|
||||
sendNotification<P>(type: NotificationType<P>, params?: P): void;
|
||||
onNotification<P>(type: NotificationType<P>, handler: NotificationHandler<P>): void;
|
||||
trace(value: Trace, tracer: Tracer, sendNotification?: boolean): void;
|
||||
onError: Event<[Error, Message, number]>;
|
||||
onClose: Event<void>;
|
||||
onUnhandledNotification: Event<NotificationMessage>;
|
||||
listen();
|
||||
onDispose: Event<void>;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export interface ServerMessageConnection extends MessageConnection {
|
||||
}
|
||||
|
||||
export interface ClientMessageConnection extends MessageConnection {
|
||||
}
|
||||
|
||||
interface ResponsePromise {
|
||||
method: string;
|
||||
timerStart: number;
|
||||
resolve: (response) => void;
|
||||
reject: (error: any) => void
|
||||
}
|
||||
|
||||
enum ConnectionState {
|
||||
New = 1,
|
||||
Listening = 2,
|
||||
Closed = 3,
|
||||
Disposed = 4
|
||||
}
|
||||
|
||||
function createMessageConnection<T extends MessageConnection>(messageReader: MessageReader, messageWriter: MessageWriter, logger: Logger, client: boolean = false): T {
|
||||
let sequenceNumber = 0;
|
||||
const version: string = '2.0';
|
||||
|
||||
let requestHandlers: { [name: string]: RequestHandler<any, any, any> } = Object.create(null);
|
||||
let eventHandlers: { [name: string]: NotificationHandler<any> } = Object.create(null);
|
||||
|
||||
let responsePromises: { [name: string]: ResponsePromise } = Object.create(null);
|
||||
let requestTokens: { [id: string]: CancellationTokenSource } = Object.create(null);
|
||||
|
||||
let trace: Trace = Trace.Off;
|
||||
let tracer: Tracer;
|
||||
|
||||
let state: ConnectionState = ConnectionState.New;
|
||||
let errorEmitter: Emitter<[Error, Message, number]> = new Emitter<[Error, Message, number]>();
|
||||
let closeEmitter: Emitter<void> = new Emitter<void>();
|
||||
let unhandledNotificationEmitter: Emitter<NotificationMessage> = new Emitter<NotificationMessage>();
|
||||
let disposeEmitter: Emitter<void> = new Emitter<void>();
|
||||
|
||||
function isListening(): boolean {
|
||||
return state === ConnectionState.Listening;
|
||||
}
|
||||
|
||||
function isClosed(): boolean {
|
||||
return state === ConnectionState.Closed;
|
||||
}
|
||||
|
||||
function isDisposed(): boolean {
|
||||
return state === ConnectionState.Disposed;
|
||||
}
|
||||
|
||||
function closeHandler(): void {
|
||||
if (state === ConnectionState.New || state === ConnectionState.Listening) {
|
||||
state = ConnectionState.Closed;
|
||||
closeEmitter.fire(undefined);
|
||||
}
|
||||
// If the connection is disposed don't sent close events.
|
||||
};
|
||||
|
||||
function readErrorHandler(error: Error): void {
|
||||
errorEmitter.fire([error, undefined, undefined]);
|
||||
}
|
||||
|
||||
function writeErrorHandler(data: [Error, Message, number]): void {
|
||||
errorEmitter.fire(data);
|
||||
}
|
||||
|
||||
messageReader.onClose(closeHandler);
|
||||
messageReader.onError(readErrorHandler);
|
||||
|
||||
messageWriter.onClose(closeHandler);
|
||||
messageWriter.onError(writeErrorHandler);
|
||||
|
||||
function handleRequest(requestMessage: RequestMessage) {
|
||||
if (isDisposed()) {
|
||||
// we return here silently since we fired an event when the
|
||||
// connection got disposed.
|
||||
return;
|
||||
}
|
||||
|
||||
function reply(resultOrError: any | ResponseError<any>): void {
|
||||
let message: ResponseMessage = {
|
||||
jsonrpc: version,
|
||||
id: requestMessage.id
|
||||
};
|
||||
if (resultOrError instanceof ResponseError) {
|
||||
message.error = (<ResponseError<any>>resultOrError).toJson();
|
||||
} else {
|
||||
message.result = is.undefined(resultOrError) ? null : resultOrError;
|
||||
}
|
||||
messageWriter.write(message);
|
||||
}
|
||||
function replyError(error: ResponseError<any>) {
|
||||
let message: ResponseMessage = {
|
||||
jsonrpc: version,
|
||||
id: requestMessage.id,
|
||||
error: error.toJson()
|
||||
};
|
||||
messageWriter.write(message);
|
||||
}
|
||||
function replySuccess(result: any) {
|
||||
// The JSON RPC defines that a response must either have a result or an error
|
||||
// So we can't treat undefined as a valid response result.
|
||||
if (is.undefined(result)) {
|
||||
result = null;
|
||||
}
|
||||
let message: ResponseMessage = {
|
||||
jsonrpc: version,
|
||||
id: requestMessage.id,
|
||||
result: result
|
||||
};
|
||||
messageWriter.write(message);
|
||||
}
|
||||
|
||||
let requestHandler = requestHandlers[requestMessage.method];
|
||||
if (requestHandler) {
|
||||
let cancellationSource = new CancellationTokenSource();
|
||||
let tokenKey = String(requestMessage.id);
|
||||
requestTokens[tokenKey] = cancellationSource;
|
||||
try {
|
||||
let handlerResult = requestHandler(requestMessage.params, cancellationSource.token);
|
||||
let promise = <Thenable<any | ResponseError<any>>>handlerResult;
|
||||
if (!handlerResult) {
|
||||
delete requestTokens[tokenKey];
|
||||
replySuccess(handlerResult);
|
||||
} else if (promise.then) {
|
||||
promise.then((resultOrError): any | ResponseError<any> => {
|
||||
delete requestTokens[tokenKey];
|
||||
reply(resultOrError);
|
||||
}, error => {
|
||||
delete requestTokens[tokenKey];
|
||||
if (error instanceof ResponseError) {
|
||||
replyError(<ResponseError<any>>error);
|
||||
} else if (error && is.string(error.message)) {
|
||||
replyError(new ResponseError<void>(ErrorCodes.InternalError, `Request ${requestMessage.method} failed with message: ${error.message}`));
|
||||
} else {
|
||||
replyError(new ResponseError<void>(ErrorCodes.InternalError, `Request ${requestMessage.method} failed unexpectedly without providing any details.`));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
delete requestTokens[tokenKey];
|
||||
reply(handlerResult);
|
||||
}
|
||||
} catch (error) {
|
||||
delete requestTokens[tokenKey];
|
||||
if (error instanceof ResponseError) {
|
||||
reply(<ResponseError<any>>error);
|
||||
} else if (error && is.string(error.message)) {
|
||||
replyError(new ResponseError<void>(ErrorCodes.InternalError, `Request ${requestMessage.method} failed with message: ${error.message}`));
|
||||
} else {
|
||||
replyError(new ResponseError<void>(ErrorCodes.InternalError, `Request ${requestMessage.method} failed unexpectedly without providing any details.`));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
replyError(new ResponseError<void>(ErrorCodes.MethodNotFound, `Unhandled method ${requestMessage.method}`));
|
||||
}
|
||||
}
|
||||
|
||||
function handleResponse(responseMessage: ResponseMessage) {
|
||||
if (isDisposed()) {
|
||||
// See handle request.
|
||||
return;
|
||||
}
|
||||
|
||||
let key = String(responseMessage.id);
|
||||
let responsePromise = responsePromises[key];
|
||||
if (trace != Trace.Off && tracer) {
|
||||
traceResponse(responseMessage, responsePromise);
|
||||
}
|
||||
if (responsePromise) {
|
||||
delete responsePromises[key];
|
||||
try {
|
||||
if (is.defined(responseMessage.error)) {
|
||||
let error = responseMessage.error;
|
||||
responsePromise.reject(new ResponseError(error.code, error.message, error.data));
|
||||
} else if (is.defined(responseMessage.result)) {
|
||||
responsePromise.resolve(responseMessage.result);
|
||||
} else {
|
||||
throw new Error('Should never happen.');
|
||||
}
|
||||
} catch (error) {
|
||||
if (error.message) {
|
||||
logger.error(`Response handler '${responsePromise.method}' failed with message: ${error.message}`);
|
||||
} else {
|
||||
logger.error(`Response handler '${responsePromise.method}' failed unexpectedly.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleNotification(message: NotificationMessage) {
|
||||
if (isDisposed()) {
|
||||
// See handle request.
|
||||
return;
|
||||
}
|
||||
let eventHandler: NotificationHandler<any>;
|
||||
if (message.method === CancelNotification.type.method) {
|
||||
eventHandler = (params: CancelParams) => {
|
||||
let id = params.id;
|
||||
let source = requestTokens[String(id)];
|
||||
if (source) {
|
||||
source.cancel();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
eventHandler = eventHandlers[message.method];
|
||||
}
|
||||
if (eventHandler) {
|
||||
try {
|
||||
if (trace != Trace.Off && tracer) {
|
||||
traceReceivedNotification(message);
|
||||
}
|
||||
eventHandler(message.params);
|
||||
} catch (error) {
|
||||
if (error.message) {
|
||||
logger.error(`Notification handler '${message.method}' failed with message: ${error.message}`);
|
||||
} else {
|
||||
logger.error(`Notification handler '${message.method}' failed unexpectedly.`);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unhandledNotificationEmitter.fire(message);
|
||||
}
|
||||
}
|
||||
|
||||
function handleInvalidMessage(message: Message) {
|
||||
if (!message) {
|
||||
logger.error('Received empty message.');
|
||||
return;
|
||||
}
|
||||
logger.error(`Received message which is neither a response nor a notification message:\n${JSON.stringify(message, null, 4)}`);
|
||||
// Test whether we find an id to reject the promise
|
||||
let responseMessage: ResponseMessage = message as ResponseMessage;
|
||||
if (is.string(responseMessage.id) || is.number(responseMessage.id)) {
|
||||
let key = String(responseMessage.id);
|
||||
let responseHandler = responsePromises[key];
|
||||
if (responseHandler) {
|
||||
responseHandler.reject(new Error('The received response has neither a result nor an error property.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function traceRequest(message: RequestMessage): void {
|
||||
let data: string = undefined;
|
||||
if (trace === Trace.Verbose && message.params) {
|
||||
data = `Params: ${JSON.stringify(message.params, null, 4)}\n\n`;
|
||||
}
|
||||
tracer.log(`Sending request '${message.method} - (${message.id})'.`, data);
|
||||
}
|
||||
|
||||
function traceSendNotification(message: NotificationMessage): void {
|
||||
let data: string = undefined;
|
||||
if (trace === Trace.Verbose) {
|
||||
if (message.params) {
|
||||
data = `Params: ${JSON.stringify(message.params, null, 4)}\n\n`;
|
||||
} else {
|
||||
data = 'No parameters provided.\n\n';
|
||||
}
|
||||
}
|
||||
tracer.log(`Sending notification '${message.method}'.`, data);
|
||||
}
|
||||
|
||||
function traceReceivedNotification(message: NotificationMessage): void {
|
||||
if (message.method === LogTraceNotification.type.method) {
|
||||
return;
|
||||
}
|
||||
let data: string = undefined;
|
||||
if (trace === Trace.Verbose) {
|
||||
if (message.params) {
|
||||
data = `Params: ${JSON.stringify(message.params, null, 4)}\n\n`;
|
||||
} else {
|
||||
data = 'No parameters provided.\n\n';
|
||||
}
|
||||
}
|
||||
tracer.log(`Received notification '${message.method}'.`, data);
|
||||
}
|
||||
|
||||
function traceResponse(message: ResponseMessage, responsePromise: ResponsePromise): void {
|
||||
let data: string = undefined;
|
||||
if (trace === Trace.Verbose) {
|
||||
if (message.error && message.error.data) {
|
||||
data = `Error data: ${JSON.stringify(message.error.data, null, 4)}\n\n`;
|
||||
} else {
|
||||
if (message.result) {
|
||||
data = `Result: ${JSON.stringify(message.result, null, 4)}\n\n`;
|
||||
} else if (is.undefined(message.error)) {
|
||||
data = 'No result returned.\n\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
if (responsePromise) {
|
||||
let error = message.error ? ` Request failed: ${message.error.message} (${message.error.code}).` : '';
|
||||
tracer.log(`Received response '${responsePromise.method} - (${message.id})' in ${Date.now() - responsePromise.timerStart}ms.${error}`, data);
|
||||
} else {
|
||||
tracer.log(`Received response ${message.id} without active response promise.`, data);
|
||||
}
|
||||
}
|
||||
|
||||
let callback: DataCallback = (message) => {
|
||||
if (isRequestMessage(message)) {
|
||||
handleRequest(message);
|
||||
} else if (isReponseMessage(message)) {
|
||||
handleResponse(message)
|
||||
} else if (isNotificationMessage(message)) {
|
||||
handleNotification(message);
|
||||
} else {
|
||||
handleInvalidMessage(message);
|
||||
}
|
||||
};
|
||||
|
||||
function throwIfClosedOrDisposed() {
|
||||
if (isClosed()) {
|
||||
throw new Error('Connection is closed.');
|
||||
}
|
||||
if (isDisposed()) {
|
||||
throw new Error('Connection is disposed.');
|
||||
}
|
||||
}
|
||||
|
||||
function throwIfListening() {
|
||||
if (isListening()) {
|
||||
throw new Error('Connection is already listening');
|
||||
}
|
||||
}
|
||||
|
||||
let connection: MessageConnection = {
|
||||
sendNotification: <P>(type: NotificationType<P>, params): void => {
|
||||
throwIfClosedOrDisposed();
|
||||
|
||||
let notificatioMessage: NotificationMessage = {
|
||||
jsonrpc: version,
|
||||
method: type.method,
|
||||
params: params
|
||||
}
|
||||
if (trace != Trace.Off && tracer) {
|
||||
traceSendNotification(notificatioMessage);
|
||||
}
|
||||
messageWriter.write(notificatioMessage);
|
||||
},
|
||||
onNotification: <P>(type: NotificationType<P>, handler: NotificationHandler<P>) => {
|
||||
throwIfClosedOrDisposed();
|
||||
|
||||
eventHandlers[type.method] = handler;
|
||||
},
|
||||
sendRequest: <P, R, E>(type: RequestType<P, R, E>, params: P, token?: CancellationToken) => {
|
||||
throwIfClosedOrDisposed();
|
||||
|
||||
let id = sequenceNumber++;
|
||||
let result = new Promise<R | ResponseError<E>>((resolve, reject) => {
|
||||
let requestMessage: RequestMessage = {
|
||||
jsonrpc: version,
|
||||
id: id,
|
||||
method: type.method,
|
||||
params: params
|
||||
}
|
||||
let responsePromise: ResponsePromise = { method: type.method, timerStart: Date.now(), resolve, reject };
|
||||
if (trace != Trace.Off && tracer) {
|
||||
traceRequest(requestMessage);
|
||||
}
|
||||
try {
|
||||
messageWriter.write(requestMessage);
|
||||
} catch (e) {
|
||||
// Writing the message failed. So we need to reject the promise.
|
||||
responsePromise.reject(new ResponseError<void>(ErrorCodes.MessageWriteError, e.message ? e.message : 'Unknown reason'));
|
||||
responsePromise = null;
|
||||
}
|
||||
if (responsePromise) {
|
||||
responsePromises[String(id)] = responsePromise;
|
||||
}
|
||||
});
|
||||
if (token) {
|
||||
token.onCancellationRequested((event) => {
|
||||
connection.sendNotification(CancelNotification.type, { id });
|
||||
});
|
||||
}
|
||||
return result;
|
||||
},
|
||||
onRequest: <P, R, E>(type: RequestType<P, R, E>, handler: RequestHandler<P, R, E>) => {
|
||||
throwIfClosedOrDisposed();
|
||||
|
||||
requestHandlers[type.method] = handler;
|
||||
},
|
||||
trace: (_value: Trace, _tracer: Tracer, sendNotification: boolean = false) => {
|
||||
trace = _value;
|
||||
if (trace === Trace.Off) {
|
||||
tracer = null;
|
||||
} else {
|
||||
tracer = _tracer;
|
||||
}
|
||||
if (sendNotification && !isClosed() && !isDisposed()) {
|
||||
connection.sendNotification(SetTraceNotification.type, { value: Trace.toString(_value) });
|
||||
}
|
||||
},
|
||||
onError: errorEmitter.event,
|
||||
onClose: closeEmitter.event,
|
||||
onUnhandledNotification: unhandledNotificationEmitter.event,
|
||||
onDispose: disposeEmitter.event,
|
||||
dispose: () => {
|
||||
if (isDisposed()) {
|
||||
return;
|
||||
}
|
||||
state = ConnectionState.Disposed;
|
||||
disposeEmitter.fire(undefined);
|
||||
let error = new Error('Connection got disposed.');
|
||||
Object.keys(responsePromises).forEach((key) => {
|
||||
responsePromises[key].reject(error);
|
||||
});
|
||||
responsePromises = Object.create(null);
|
||||
requestTokens = Object.create(null);
|
||||
},
|
||||
listen: () => {
|
||||
throwIfClosedOrDisposed();
|
||||
throwIfListening();
|
||||
|
||||
state = ConnectionState.Listening;
|
||||
messageReader.listen(callback);
|
||||
}
|
||||
};
|
||||
|
||||
connection.onNotification(LogTraceNotification.type, (params) => {
|
||||
if (trace === Trace.Off) {
|
||||
return;
|
||||
}
|
||||
tracer.log(params.message, trace === Trace.Verbose ? params.verbose : undefined);
|
||||
});
|
||||
return connection as T;
|
||||
}
|
||||
|
||||
function isMessageReader(value: any): value is MessageReader {
|
||||
return is.defined(value.listen) && is.undefined(value.read);
|
||||
}
|
||||
|
||||
function isMessageWriter(value: any): value is MessageWriter {
|
||||
return is.defined(value.write) && is.undefined(value.end);
|
||||
}
|
||||
|
||||
export function createServerMessageConnection(reader: MessageReader, writer: MessageWriter, logger: Logger): ServerMessageConnection;
|
||||
export function createServerMessageConnection(inputStream: NodeJS.ReadableStream, outputStream: NodeJS.WritableStream, logger: Logger): ServerMessageConnection;
|
||||
export function createServerMessageConnection(input: MessageReader | NodeJS.ReadableStream, output: MessageWriter | NodeJS.WritableStream, logger: Logger): ServerMessageConnection {
|
||||
let reader = isMessageReader(input) ? input : new StreamMessageReader(input);
|
||||
let writer = isMessageWriter(output) ? output : new StreamMessageWriter(output);
|
||||
return createMessageConnection<ServerMessageConnection>(reader, writer, logger);
|
||||
}
|
||||
|
||||
export function createClientMessageConnection(reader: MessageReader, writer: MessageWriter, logger: Logger): ClientMessageConnection;
|
||||
export function createClientMessageConnection(inputStream: NodeJS.ReadableStream, outputStream: NodeJS.WritableStream, logger: Logger): ClientMessageConnection;
|
||||
export function createClientMessageConnection(input: MessageReader | NodeJS.ReadableStream, output: MessageWriter | NodeJS.WritableStream, logger: Logger): ClientMessageConnection {
|
||||
let reader = isMessageReader(input) ? input : new StreamMessageReader(input);
|
||||
let writer = isMessageWriter(output) ? output : new StreamMessageWriter(output);
|
||||
return createMessageConnection<ClientMessageConnection>(reader, writer, logger, true);
|
||||
}
|
||||
@@ -1,265 +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 { ChildProcess } from 'child_process';
|
||||
|
||||
import { Message } from './messages';
|
||||
import { Event, Emitter } from './events';
|
||||
import * as is from './is';
|
||||
|
||||
let DefaultSize: number = 8192;
|
||||
let CR: number = new Buffer('\r', 'ascii')[0];
|
||||
let LF: number = new Buffer('\n', 'ascii')[0];
|
||||
let CRLF: string = '\r\n';
|
||||
|
||||
class MessageBuffer {
|
||||
|
||||
private encoding: string;
|
||||
private index: number;
|
||||
private buffer: Buffer;
|
||||
|
||||
constructor(encoding: string = 'utf-8') {
|
||||
this.encoding = encoding;
|
||||
this.index = 0;
|
||||
this.buffer = new Buffer(DefaultSize);
|
||||
}
|
||||
|
||||
public append(chunk: Buffer | String): void {
|
||||
var toAppend: Buffer = <Buffer>chunk;
|
||||
if (typeof (chunk) == 'string') {
|
||||
var str = <string>chunk;
|
||||
toAppend = new Buffer(str.length);
|
||||
toAppend.write(str, 0, str.length, this.encoding);
|
||||
}
|
||||
if (this.buffer.length - this.index >= toAppend.length) {
|
||||
toAppend.copy(this.buffer, this.index, 0, toAppend.length);
|
||||
} else {
|
||||
var newSize = (Math.ceil((this.index + toAppend.length) / DefaultSize) + 1) * DefaultSize;
|
||||
if (this.index === 0) {
|
||||
this.buffer = new Buffer(newSize);
|
||||
toAppend.copy(this.buffer, 0, 0, toAppend.length);
|
||||
} else {
|
||||
this.buffer = Buffer.concat([this.buffer.slice(0, this.index), toAppend], newSize);
|
||||
}
|
||||
}
|
||||
this.index += toAppend.length;
|
||||
}
|
||||
|
||||
public tryReadHeaders(): { [key: string]: string; } {
|
||||
let result: { [key: string]: string; } = undefined;
|
||||
let current = 0;
|
||||
while (current + 3 < this.index && (this.buffer[current] !== CR || this.buffer[current + 1] !== LF || this.buffer[current + 2] !== CR || this.buffer[current + 3] !== LF)) {
|
||||
current++;
|
||||
}
|
||||
// No header / body separator found (e.g CRLFCRLF)
|
||||
if (current + 3 >= this.index) {
|
||||
return result;
|
||||
}
|
||||
result = Object.create(null);
|
||||
let headers = this.buffer.toString('ascii', 0, current).split(CRLF);
|
||||
headers.forEach((header) => {
|
||||
let index: number = header.indexOf(':');
|
||||
if (index === -1) {
|
||||
throw new Error('Message header must separate key and value using :');
|
||||
}
|
||||
let key = header.substr(0, index);
|
||||
let value = header.substr(index + 1).trim();
|
||||
result[key] = value;
|
||||
})
|
||||
|
||||
let nextStart = current + 4;
|
||||
this.buffer = this.buffer.slice(nextStart);
|
||||
this.index = this.index - nextStart;
|
||||
return result;
|
||||
}
|
||||
|
||||
public tryReadContent(length: number): string {
|
||||
if (this.index < length) {
|
||||
return null;
|
||||
}
|
||||
let result = this.buffer.toString(this.encoding, 0, length);
|
||||
let nextStart = length;
|
||||
this.buffer.copy(this.buffer, 0, nextStart);
|
||||
this.index = this.index - nextStart;
|
||||
return result;
|
||||
}
|
||||
|
||||
public get numberOfBytes(): number {
|
||||
return this.index;
|
||||
}
|
||||
}
|
||||
|
||||
export interface DataCallback {
|
||||
(data: Message): void;
|
||||
}
|
||||
|
||||
export interface PartialMessageInfo {
|
||||
messageToken: number;
|
||||
waitingTime: number;
|
||||
}
|
||||
|
||||
export interface MessageReader {
|
||||
onError: Event<Error>;
|
||||
onClose: Event<void>;
|
||||
onPartialMessage: Event<PartialMessageInfo>;
|
||||
listen(callback: DataCallback): void;
|
||||
}
|
||||
|
||||
export abstract class AbstractMessageReader {
|
||||
|
||||
private errorEmitter: Emitter<Error>;
|
||||
private closeEmitter: Emitter<void>;
|
||||
|
||||
private partialMessageEmitter: Emitter<PartialMessageInfo>;
|
||||
|
||||
constructor() {
|
||||
this.errorEmitter = new Emitter<Error>();
|
||||
this.closeEmitter = new Emitter<void>();
|
||||
this.partialMessageEmitter = new Emitter<PartialMessageInfo>();
|
||||
}
|
||||
|
||||
public get onError(): Event<Error> {
|
||||
return this.errorEmitter.event;
|
||||
}
|
||||
|
||||
protected fireError(error: any): void {
|
||||
this.errorEmitter.fire(this.asError(error));
|
||||
}
|
||||
|
||||
public get onClose(): Event<void> {
|
||||
return this.closeEmitter.event;
|
||||
}
|
||||
|
||||
protected fireClose(): void {
|
||||
this.closeEmitter.fire(undefined);
|
||||
}
|
||||
|
||||
public get onPartialMessage(): Event<PartialMessageInfo> {
|
||||
return this.partialMessageEmitter.event;
|
||||
}
|
||||
|
||||
protected firePartialMessage(info: PartialMessageInfo): void {
|
||||
this.partialMessageEmitter.fire(info);
|
||||
}
|
||||
|
||||
private asError(error: any): Error {
|
||||
if (error instanceof Error) {
|
||||
return error;
|
||||
} else {
|
||||
return new Error(`Reader recevied error. Reason: ${is.string(error.message) ? error.message : 'unknown'}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class StreamMessageReader extends AbstractMessageReader implements MessageReader {
|
||||
|
||||
private readable: NodeJS.ReadableStream;
|
||||
private callback: DataCallback;
|
||||
private buffer: MessageBuffer;
|
||||
private nextMessageLength: number;
|
||||
private messageToken: number;
|
||||
private partialMessageTimer: NodeJS.Timer;
|
||||
private _partialMessageTimeout: number;
|
||||
|
||||
public constructor(readable: NodeJS.ReadableStream, encoding: string = 'utf-8') {
|
||||
super();
|
||||
this.readable = readable;
|
||||
this.buffer = new MessageBuffer(encoding);
|
||||
this._partialMessageTimeout = 10000;
|
||||
}
|
||||
|
||||
public set partialMessageTimeout(timeout: number) {
|
||||
this._partialMessageTimeout = timeout;
|
||||
}
|
||||
|
||||
public get partialMessageTimeout(): number {
|
||||
return this._partialMessageTimeout;
|
||||
}
|
||||
|
||||
public listen(callback: DataCallback): void {
|
||||
this.nextMessageLength = -1;
|
||||
this.messageToken = 0;
|
||||
this.partialMessageTimer = undefined;
|
||||
this.callback = callback;
|
||||
this.readable.on('data', (data: Buffer) => {
|
||||
this.onData(data);
|
||||
});
|
||||
this.readable.on('error', (error: any) => this.fireError(error));
|
||||
this.readable.on('close', () => this.fireClose());
|
||||
}
|
||||
|
||||
private onData(data: Buffer | String): void {
|
||||
this.buffer.append(data);
|
||||
while (true) {
|
||||
if (this.nextMessageLength === -1) {
|
||||
let headers = this.buffer.tryReadHeaders();
|
||||
if (!headers) {
|
||||
return;
|
||||
}
|
||||
let contentLength = headers['Content-Length'];
|
||||
if (!contentLength) {
|
||||
throw new Error('Header must provide a Content-Length property.');
|
||||
}
|
||||
let length = parseInt(contentLength);
|
||||
if (isNaN(length)) {
|
||||
throw new Error('Content-Length value must be a number.');
|
||||
}
|
||||
this.nextMessageLength = length;
|
||||
}
|
||||
var msg = this.buffer.tryReadContent(this.nextMessageLength);
|
||||
if (msg === null) {
|
||||
/** We haven't recevied the full message yet. */
|
||||
this.setPartialMessageTimer();
|
||||
return;
|
||||
}
|
||||
this.clearPartialMessageTimer();
|
||||
this.nextMessageLength = -1;
|
||||
this.messageToken++;
|
||||
var json = JSON.parse(msg);
|
||||
this.callback(json);
|
||||
}
|
||||
}
|
||||
|
||||
private clearPartialMessageTimer(): void {
|
||||
if (this.partialMessageTimer) {
|
||||
clearTimeout(this.partialMessageTimer);
|
||||
this.partialMessageTimer = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
private setPartialMessageTimer(): void {
|
||||
this.clearPartialMessageTimer();
|
||||
if (this._partialMessageTimeout <= 0) {
|
||||
return;
|
||||
}
|
||||
this.partialMessageTimer = setTimeout((token, timeout) => {
|
||||
this.partialMessageTimer = undefined;
|
||||
if (token === this.messageToken) {
|
||||
this.firePartialMessage({ messageToken: token, waitingTime: timeout });
|
||||
this.setPartialMessageTimer();
|
||||
}
|
||||
}, this._partialMessageTimeout, this.messageToken, this._partialMessageTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
export class IPCMessageReader extends AbstractMessageReader implements MessageReader {
|
||||
|
||||
private process: NodeJS.Process | ChildProcess;
|
||||
|
||||
public constructor(process: NodeJS.Process | ChildProcess) {
|
||||
super();
|
||||
this.process = process;
|
||||
|
||||
let eventEmitter: NodeJS.EventEmitter = <NodeJS.EventEmitter>this.process;
|
||||
eventEmitter.on('error', (error: any) => this.fireError(error));
|
||||
eventEmitter.on('close', () => this.fireClose());
|
||||
}
|
||||
|
||||
public listen(callback: DataCallback): void {
|
||||
let eventEmitter: NodeJS.EventEmitter = <NodeJS.EventEmitter>this.process;
|
||||
eventEmitter.on('message', callback);
|
||||
}
|
||||
}
|
||||
@@ -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';
|
||||
|
||||
import { ChildProcess } from 'child_process';
|
||||
|
||||
import { Message } from './messages';
|
||||
import { Event, Emitter } from './events';
|
||||
import * as is from './is';
|
||||
|
||||
let ContentLength: string = 'Content-Length: ';
|
||||
let CRLF = '\r\n';
|
||||
|
||||
export interface MessageWriter {
|
||||
onError: Event<[Error, Message, number]>;
|
||||
onClose: Event<void>;
|
||||
write(msg: Message): void;
|
||||
}
|
||||
|
||||
export abstract class AbstractMessageWriter {
|
||||
|
||||
private errorEmitter: Emitter<[Error, Message, number]>;
|
||||
private closeEmitter: Emitter<void>;
|
||||
|
||||
constructor() {
|
||||
this.errorEmitter = new Emitter<[Error, Message, number]>();
|
||||
this.closeEmitter = new Emitter<void>();
|
||||
}
|
||||
|
||||
public get onError(): Event<[Error, Message, number]> {
|
||||
return this.errorEmitter.event;
|
||||
}
|
||||
|
||||
protected fireError(error: any, message?: Message, count?: number): void {
|
||||
this.errorEmitter.fire([this.asError(error), message, count]);
|
||||
}
|
||||
|
||||
public get onClose(): Event<void> {
|
||||
return this.closeEmitter.event;
|
||||
}
|
||||
|
||||
protected fireClose(): void {
|
||||
this.closeEmitter.fire(undefined);
|
||||
}
|
||||
|
||||
private asError(error: any): Error {
|
||||
if (error instanceof Error) {
|
||||
return error;
|
||||
} else {
|
||||
return new Error(`Writer recevied error. Reason: ${is.string(error.message) ? error.message : 'unknown'}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class StreamMessageWriter extends AbstractMessageWriter implements MessageWriter {
|
||||
|
||||
private writable: NodeJS.WritableStream;
|
||||
private encoding: string;
|
||||
private errorCount: number;
|
||||
|
||||
public constructor(writable: NodeJS.WritableStream, encoding: string = 'utf8') {
|
||||
super();
|
||||
this.writable = writable;
|
||||
this.encoding = encoding;
|
||||
this.errorCount = 0;
|
||||
this.writable.on('error', (error) => this.fireError(error));
|
||||
this.writable.on('close', () => this.fireClose());
|
||||
}
|
||||
|
||||
public write(msg: Message): void {
|
||||
let json = JSON.stringify(msg);
|
||||
let contentLength = Buffer.byteLength(json, this.encoding);
|
||||
|
||||
let headers: string[] = [
|
||||
ContentLength, contentLength.toString(), CRLF,
|
||||
CRLF
|
||||
];
|
||||
try {
|
||||
// Header must be written in ASCII encoding
|
||||
this.writable.write(headers.join(''), 'ascii');
|
||||
|
||||
// Now write the content. This can be written in any encoding
|
||||
this.writable.write(json, this.encoding);
|
||||
this.errorCount = 0;
|
||||
} catch (error) {
|
||||
this.errorCount++;
|
||||
this.fireError(error, msg, this.errorCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class IPCMessageWriter extends AbstractMessageWriter implements MessageWriter {
|
||||
|
||||
private process: NodeJS.Process | ChildProcess;
|
||||
private errorCount: number;
|
||||
|
||||
public constructor(process: NodeJS.Process | ChildProcess) {
|
||||
super();
|
||||
this.process = process;
|
||||
this.errorCount = 0;
|
||||
|
||||
let eventEmitter: NodeJS.EventEmitter = <NodeJS.EventEmitter>this.process;
|
||||
eventEmitter.on('error', (error) => this.fireError(error));
|
||||
eventEmitter.on('close', () => this.fireClose);
|
||||
}
|
||||
|
||||
public write(msg: Message): void {
|
||||
try {
|
||||
(this.process.send as Function)(msg);
|
||||
this.errorCount = 0;
|
||||
} catch (error) {
|
||||
this.errorCount++;
|
||||
this.fireError(error, msg, this.errorCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,175 +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 is from './is';
|
||||
|
||||
/**
|
||||
* A language server message
|
||||
*/
|
||||
export interface Message {
|
||||
jsonrpc: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request message
|
||||
*/
|
||||
export interface RequestMessage extends Message {
|
||||
|
||||
/**
|
||||
* The request id.
|
||||
*/
|
||||
id: number | string;
|
||||
|
||||
/**
|
||||
* The method to be invoked.
|
||||
*/
|
||||
method: string;
|
||||
|
||||
/**
|
||||
* The method's params.
|
||||
*/
|
||||
params?: any
|
||||
}
|
||||
|
||||
/**
|
||||
* Predefined error codes.
|
||||
*/
|
||||
export namespace ErrorCodes {
|
||||
// Defined by JSON RPC
|
||||
export const ParseError: number = -32700;
|
||||
export const InvalidRequest: number = -32600;
|
||||
export const MethodNotFound: number = -32601;
|
||||
export const InvalidParams: number = -32602;
|
||||
export const InternalError: number = -32603;
|
||||
export const serverErrorStart: number = -32099
|
||||
export const serverErrorEnd: number = -32000;
|
||||
|
||||
// Defined by VSCode.
|
||||
export const MessageWriteError: number = 1;
|
||||
export const MessageReadError: number = 2;
|
||||
}
|
||||
|
||||
export interface ResponseErrorLiteral<D> {
|
||||
/**
|
||||
* A number indicating the error type that occured.
|
||||
*/
|
||||
code: number;
|
||||
|
||||
/**
|
||||
* A string providing a short decription of the error.
|
||||
*/
|
||||
message: string;
|
||||
|
||||
/**
|
||||
* A Primitive or Structured value that contains additional
|
||||
* information about the error. Can be omitted.
|
||||
*/
|
||||
data?: D;
|
||||
}
|
||||
|
||||
/**
|
||||
* A error object return in a response in case a request
|
||||
* has failed.
|
||||
*/
|
||||
export class ResponseError<D> extends Error {
|
||||
|
||||
public code: number;
|
||||
|
||||
public message: string;
|
||||
|
||||
public data: D;
|
||||
|
||||
constructor(code: number, message: string, data?: D) {
|
||||
super(message);
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
if (is.defined(data)) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
||||
public toJson(): ResponseErrorLiteral<D> {
|
||||
let result: ResponseErrorLiteral<D> = {
|
||||
code: this.code,
|
||||
message: this.message
|
||||
};
|
||||
if (is.defined(this.data)) {
|
||||
result.data = this.data
|
||||
};
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A response message.
|
||||
*/
|
||||
export interface ResponseMessage extends Message {
|
||||
/**
|
||||
* The request id.
|
||||
*/
|
||||
id: number | string;
|
||||
|
||||
/**
|
||||
* The result of a request. This can be omitted in
|
||||
* the case of an error.
|
||||
*/
|
||||
result?: any;
|
||||
|
||||
/**
|
||||
* The error object in case a request fails.
|
||||
*/
|
||||
error?: ResponseErrorLiteral<any>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A interface to type the request parameter / response pair
|
||||
*/
|
||||
export interface RequestType<P, R, E> {
|
||||
method: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Message
|
||||
*/
|
||||
export interface NotificationMessage extends Message {
|
||||
/**
|
||||
* The method to be invoked.
|
||||
*/
|
||||
method: string;
|
||||
|
||||
/**
|
||||
* The notification's params.
|
||||
*/
|
||||
params?: any
|
||||
}
|
||||
|
||||
export interface NotificationType<P> {
|
||||
method: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the given message is a request message
|
||||
*/
|
||||
export function isRequestMessage(message: Message): message is RequestMessage {
|
||||
let candidate = <RequestMessage>message;
|
||||
return candidate && is.string(candidate.method) && (is.string(candidate.id) || is.number(candidate.id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the given message is a notification message
|
||||
*/
|
||||
export function isNotificationMessage(message: Message): message is NotificationMessage {
|
||||
let candidate = <NotificationMessage>message;
|
||||
return candidate && is.string(candidate.method) && is.undefined((<any>message).id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the given message is a response message
|
||||
*/
|
||||
export function isReponseMessage(message: Message): message is ResponseMessage {
|
||||
let candidate = <ResponseMessage>message;
|
||||
return candidate && (is.defined(candidate.result) || is.defined(candidate.error)) && (is.string(candidate.id) || is.number(candidate.id));
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES5",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"declaration": true,
|
||||
"stripInternal": true,
|
||||
"outDir": "../lib"
|
||||
}
|
||||
}
|
||||
112
dataprotocol-node/jsonrpc/src/typings/promise.d.ts
vendored
112
dataprotocol-node/jsonrpc/src/typings/promise.d.ts
vendored
@@ -1,112 +0,0 @@
|
||||
/*! *****************************************************************************
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
this file except in compliance with the License. You may obtain a copy of the
|
||||
License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
||||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
||||
MERCHANTABLITY OR NON-INFRINGEMENT.
|
||||
|
||||
See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
/**
|
||||
* The Thenable (E.g. PromiseLike) and Promise declarions are taken from TypeScript's
|
||||
* lib.core.es6.d.ts file. See above Copyright notice.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Thenable is a common denominator between ES6 promises, Q, jquery.Deferred, WinJS.Promise,
|
||||
* and others. This API makes no assumption about what promise libary is being used which
|
||||
* enables reusing existing code without migrating to a specific promise implementation. Still,
|
||||
* we recommand the use of native promises which are available in VS Code.
|
||||
*/
|
||||
interface Thenable<R> {
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult>(onfulfilled?: (value: R) => TResult | Thenable<TResult>, onrejected?: (reason: any) => TResult | Thenable<TResult>): Thenable<TResult>;
|
||||
then<TResult>(onfulfilled?: (value: R) => TResult | Thenable<TResult>, onrejected?: (reason: any) => void): Thenable<TResult>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the completion of an asynchronous operation
|
||||
*/
|
||||
interface Promise<T> extends Thenable<T> {
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => TResult | Thenable<TResult>): Promise<TResult>;
|
||||
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => void): Promise<TResult>;
|
||||
|
||||
/**
|
||||
* Attaches a callback for only the rejection of the Promise.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of the callback.
|
||||
*/
|
||||
catch(onrejected?: (reason: any) => T | Thenable<T>): Promise<T>;
|
||||
}
|
||||
|
||||
interface PromiseConstructor {
|
||||
/**
|
||||
* Creates a new Promise.
|
||||
* @param executor A callback used to initialize the promise. This callback is passed two arguments:
|
||||
* a resolve callback used resolve the promise with a value or the result of another promise,
|
||||
* and a reject callback used to reject the promise with a provided reason or error.
|
||||
*/
|
||||
new <T>(executor: (resolve: (value?: T | Thenable<T>) => void, reject: (reason?: any) => void) => void): Promise<T>;
|
||||
|
||||
/**
|
||||
* Creates a Promise that is resolved with an array of results when all of the provided Promises
|
||||
* resolve, or rejected when any Promise is rejected.
|
||||
* @param values An array of Promises.
|
||||
* @returns A new Promise.
|
||||
*/
|
||||
all<T>(values: Array<T | Thenable<T>>): Promise<T[]>;
|
||||
|
||||
/**
|
||||
* Creates a Promise that is resolved or rejected when any of the provided Promises are resolved
|
||||
* or rejected.
|
||||
* @param values An array of Promises.
|
||||
* @returns A new Promise.
|
||||
*/
|
||||
race<T>(values: Array<T | Thenable<T>>): Promise<T>;
|
||||
|
||||
/**
|
||||
* Creates a new rejected promise for the provided reason.
|
||||
* @param reason The reason the promise was rejected.
|
||||
* @returns A new rejected Promise.
|
||||
*/
|
||||
reject(reason: any): Promise<void>;
|
||||
|
||||
/**
|
||||
* Creates a new rejected promise for the provided reason.
|
||||
* @param reason The reason the promise was rejected.
|
||||
* @returns A new rejected Promise.
|
||||
*/
|
||||
reject<T>(reason: any): Promise<T>;
|
||||
|
||||
/**
|
||||
* Creates a new resolved promise for the provided value.
|
||||
* @param value A promise.
|
||||
* @returns A promise whose internal state matches the provided promise.
|
||||
*/
|
||||
resolve<T>(value: T | Thenable<T>): Promise<T>;
|
||||
|
||||
/**
|
||||
* Creates a new resolved promise .
|
||||
* @returns A resolved promise.
|
||||
*/
|
||||
resolve(): Promise<void>;
|
||||
}
|
||||
|
||||
declare var Promise: PromiseConstructor;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user