diff --git a/.editorconfig b/.editorconfig index ab16c8e6c..b86aeccc2 100644 --- a/.editorconfig +++ b/.editorconfig @@ -9,11 +9,7 @@ indent_style = space indent_size = 4 trim_trailing_whitespace = true -# 2 space indentation for .travis.yml and package.json -[{.travis.yml},package.json] -indent_style = space +# 2 space indentation and utf-8 for for .travis.yml, package.json, and .json files under src +[{.travis.yml,package.json,src/**/*.json}] indent_size = 2 - -[syntaxes/csharp.json] -indent_style = space -indent_size = 2 \ No newline at end of file +charset = utf-8 diff --git a/.gitignore b/.gitignore index cc32df3ad..57cd8b1b7 100644 --- a/.gitignore +++ b/.gitignore @@ -14,5 +14,10 @@ obj/ bin/ test/**/.vscode .logs/ +.nyc_output/ +coverage/ -\.DS_Store \ No newline at end of file +\.DS_Store +vsix/ + +\.vscodeignore diff --git a/.travis.yml b/.travis.yml index c3fa0b49d..39b5f4018 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,7 @@ before_install: sh -e /etc/init.d/xvfb start; sleep 3; fi + - dpkg --compare-versions `npm -v` ge 5.8 || npm i -g npm@^5.8 addons: apt: @@ -25,13 +26,17 @@ addons: - dotnet-sdk-2.0.2 install: -- npm install -- npm run compile -- npm install -g vsce -- vsce package +- npm ci +- npm i -g gulp +- gulp 'vsix:release:package' script: - - npm test --silent + - gulp 'vsix:release:unpackage' + - gulp cov:instrument --codeExtensionPath ./vsix/extension + - gulp test --codeExtensionPath ./vsix/extension + - gulp cov:report --codeExtensionPath ./vsix/extension + - npm run test:artifacts + - 'if [[ "$TRAVIS_BRANCH" != "master" && "$TRAVIS_PULL_REQUEST" = "false" ]]; then npm run test:release; fi' after_failure: - ./.travis/printLogs.sh diff --git a/.vscode/launch.json b/.vscode/launch.json index c094fe619..c2006f78b 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -16,14 +16,39 @@ ] }, { - "name": "Launch Unit Tests", + "type": "node", + "request": "launch", + "name": "Launch Unit tests", + "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", + "args": [ + "-u", + "tdd", + "--timeout", + "999999", + "--colors", + "${workspaceFolder}/out/test/unitTests/**/*.test.js" + ], + "sourceMaps": true, + "internalConsoleOptions": "openOnSessionStart", + "outFiles": [ + "${workspaceRoot}/out/test/**/*.js" + ] + }, + { + "name": "Launch Feature Tests", "type": "extensionHost", "request": "launch", "runtimeExecutable": "${execPath}", "args": [ "--extensionDevelopmentPath=${workspaceRoot}", - "--extensionTestsPath=${workspaceRoot}/out/test/unitTests" + "--extensionTestsPath=${workspaceRoot}/out/test/featureTests" ], + "env": { + "CODE_WORKSPACE_ROOT": "${workspaceRoot}", + "CODE_TESTS_PATH": "${workspaceRoot}/out/test/featureTests", + "CODE_EXTENSIONS_PATH": "${workspaceRoot}", + "OSVC_SUITE": "featureTests" + }, "stopOnEntry": false, "sourceMaps": true, "outFiles": [ @@ -40,6 +65,13 @@ "--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test/integrationTests" ], + "env": { + "CODE_WORKSPACE_ROOT": "${workspaceRoot}", + "CODE_TESTS_PATH": "${workspaceRoot}/out/test/integrationTests", + "CODE_TESTS_WORKSPACE": "${workspaceRoot}/test/integrationTests/testAssets/singleCsproj", + "CODE_EXTENSIONS_PATH": "${workspaceRoot}", + "OSVC_SUITE": "singleCsproj" + }, "stopOnEntry": false, "sourceMaps": true, "outFiles": [ @@ -56,6 +88,13 @@ "--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test/integrationTests" ], + "env": { + "CODE_WORKSPACE_ROOT": "${workspaceRoot}", + "CODE_TESTS_PATH": "${workspaceRoot}/out/test/integrationTests", + "CODE_TESTS_WORKSPACE": "${workspaceRoot}/test/integrationTests/testAssets/slnWithCsproj", + "CODE_EXTENSIONS_PATH": "${workspaceRoot}", + "OSVC_SUITE": "slnWithCsproj" + }, "stopOnEntry": false, "sourceMaps": true, "outFiles": [ @@ -63,4 +102,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index cbd3c5501..bf86be1b4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,16 +4,18 @@ "files.exclude": { "out": true, - "typings": false + "typings": false, + "vsix": true }, "search.exclude": { "**/node_modules": true, - "out/": true + "out/": true, + "vsix/": true }, "csharp.suppressDotnetRestoreNotification": true, - + "tslint.rulesDirectory": "node_modules/tslint-microsoft-contrib", "typescript.tsdk": "./node_modules/typescript/lib", "mocha.enabled": true diff --git a/.vscodeignore b/.vscodeignore deleted file mode 100644 index 72116c06e..000000000 --- a/.vscodeignore +++ /dev/null @@ -1,19 +0,0 @@ -.vscode/** -typings/** -out/test/** -test/** -src/** -**/*.map - -.gitignore -.travis.yml -tsconfig.json -ISSUE_TEMPLATE -tslint.json -gulpfile.js - -**/.nyc_output/** -**/coverage/** - -+RuntimeLicenses/dependencies/* -coreclr-debug/install.log \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a409cd3f..cd99b7cd6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,39 @@ * There currently is no completion support for package references in csproj files. ([#1156](https://github.com/OmniSharp/omnisharp-vscode/issues/1156)) * As an alternative, consider installing the [MSBuild Project Tools](https://marketplace.visualstudio.com/items?itemName=tintoy.msbuild-project-tools) extension by @tintoy. -## 1.14.0 (February 14, 2017) +## 1.15.0 _(Not Yet Released)_ + +#### Debugger + +* New features: + * Adds support for [Source Link](https://aka.ms/SourceLinkSpec), Symbol Servers and other more advanced symbol options ([#373](https://github.com/OmniSharp/omnisharp-vscode/issues/373)) + * Adds launch.json option to suppress Just-In-Time compiler optimizations. + * Due to the previous two items and work from the .NET Team, it is now possible to easily debug into ASP.NET itself in projects running against .NET Core 2.1. Instructions are in the [wiki](https://github.com/OmniSharp/omnisharp-vscode/wiki/Debugging-into-the-.NET-Framework-itself). + * Adds support for pulling in environment variables from `${cwd}/Properties/launchSettings.json`. This means that if you add environment variable configuration to your launchSettings.json file, they will now be used when you start your app from Visual Studio Code like they previously would be used from the command line (`dotnet run`), and from Visual Studio. ([#2017](https://github.com/OmniSharp/omnisharp-vscode/issues/2017)) + * Adds a Code Lens indicator for running and debugging all tests in a class. ([#420](https://github.com/OmniSharp/omnisharp-vscode/issues/420), PR: [#1961](https://github.com/OmniSharp/omnisharp-vscode/pull/1961); PR: [omnisharp-roslyn#1089](https://github.com/OmniSharp/omnisharp-roslyn/pull/1089)) + +* Bug fixes: + * On Linux, this reduces the native dependencies of the debugger to match the .NET Core 2.1 runtime. The Linux .NET Core 2.1 runtime reduced its native dependencies over all the previous versions, but the debugger still had the same dependencies as .NET Core 2.0. With this fix, the debugger will now continue to work on Linux after installing the .NET Core runtime and nothing else. ([#2199](https://github.com/OmniSharp/omnisharp-vscode/issues/2199)) + * Fixes async call stacks with the .NET Core 2.1 runtime. ([#1892](https://github.com/OmniSharp/omnisharp-vscode/issues/1892)) + * Fixes the debugger's browser launch code when launching projects configured to use Application Insights. ([2177](https://github.com/OmniSharp/omnisharp-vscode/issues/2177)) + +#### Specify OmniSharp Version +Enables the use of pre-release builds of Omnisharp. Downloading a pre-release build of Omnisharp allows the C# extension for VS Code to use features that have been merged into the "master" branch of omnisharp-roslyn(https://github.com/OmniSharp/omnisharp-roslyn) but that have not been officially released +* Adds support to use the "omnisharp.path" option to download a specific copy of OmniSharp. The possible values for this option are: + * `` - Use a local copy of OmniSharp. The value must point to a directory which contains OmniSharp, typically a user's build output directory for the OmniSharp-Roslyn project. Example: C:\omnisharp-roslyn\artifacts\publish\OmniSharp.Stdio\win7-x64\OmniSharp.exe. + * `latest` - Use the latest CI build + * `` - Use a specific version of OmniSharp. Example: `1.29.2-beta.60` + +#### Editor + +* Splits the OmniSharp status bar item into two parts, both of which appear on the left and have specific responsibilities. ([#2146](https://github.com/OmniSharp/omnisharp-vscode/issues/2146), PR: [@2133](https://github.com/OmniSharp/omnisharp-vscode/pull/2133)) + * OmniSharp server status bar item - Shows the various stages that the OmniSharp server initialization might be in (eg: Downloading, Installing, etc). The flame icon is green when the server is initialized and running properly, or red if there is an error. + * Project Information status bar item - + * Displays the name of the selected project regardless of the currently active document. + * If a project is already selected, it displays the name of the selected project. Clicking on it displays a menu to switch to other projects in the workspace. + * If there are multiple possible launch targets, it displays 'Select Project'. Clicking on it displays a menu to select one. + +## 1.14.0 (February 14, 2018) #### C# Language Support diff --git a/README.md b/README.md index ca48e4eef..131ffb46f 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,13 @@ |:--:|:--:| |[![Master Build Status](https://travis-ci.org/OmniSharp/omnisharp-vscode.svg?branch=master)](https://travis-ci.org/OmniSharp/omnisharp-vscode)|[![Release Build Status](https://travis-ci.org/OmniSharp/omnisharp-vscode.svg?branch=release)](https://travis-ci.org/OmniSharp/omnisharp-vscode)| -Welcome to the C# extension for Visual Studio Code! This preview provides the following features inside VS Code: +[![Wallaby.js](https://img.shields.io/badge/wallaby.js-configured-green.svg)](https://wallabyjs.com) + +Welcome to the C# extension for Visual Studio Code! This extension provides the following features inside VS Code: * Lightweight development tools for [.NET Core](https://dotnet.github.io). * Great C# editing support, including Syntax Highlighting, IntelliSense, Go to Definition, Find All References, etc. -* Debugging support for .NET Core (CoreCLR). NOTE: Mono and Desktop CLR debugging is not supported. +* Debugging support for .NET Core (CoreCLR). NOTE: Mono debugging is not supported. Desktop CLR debugging has [limited support](https://github.com/OmniSharp/omnisharp-vscode/wiki/Desktop-.NET-Framework). * Support for project.json and csproj projects on Windows, macOS and Linux. The C# extension is powered by [OmniSharp](https://github.com/OmniSharp/omnisharp-roslyn). diff --git a/RuntimeLicenses/license.txt b/RuntimeLicenses/license.txt index 8966b23d0..042c4c4ea 100644 --- a/RuntimeLicenses/license.txt +++ b/RuntimeLicenses/license.txt @@ -1,116 +1,141 @@ -MICROSOFT PRE-RELEASE SOFTWARE LICENSE TERMS +MICROSOFT SOFTWARE LICENSE TERMS MICROSOFT C# EXTENSION FOR VISUAL STUDIO CODE -These license terms are an agreement between Microsoft Corporation (or based on where you live, one of its affiliates) and you. -They apply to the pre-release software named above. The terms also apply to any Microsoft services or updates for the software, -except to the extent those have additional terms. +These license terms are an agreement between Microsoft Corporation (or based on where you live, one +of its affiliates) and you. They apply to the software named above. The terms also apply to any Microsoft +services or updates for the software, except to the extent those have additional terms. IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW. -1. INSTALLATION AND USE RIGHTS. -You may only use the C# Extension for Visual Studio Code with Visual Studio Code, Visual Studio or Xamarin Studio software to -help you develop and test your applications. +1. INSTALLATION AND USE RIGHTS. You may only use the C# Extension for Visual Studio Code +with Visual Studio Code, Visual Studio or Xamarin Studio software to help you develop and test your +applications. 2. TERMS FOR SPECIFIC COMPONENTS. -a. Third Party components. The software may include third party components with separate legal notices or governed by other -agreements, as described in the ThirdPartyNotices file accompanying the software. Even if such components are governed by other -agreements, the disclaimers and the limitations on and exclusions of damages below also apply. - -3. DATA. The software may collect information about you and your use of the software, and send that to Microsoft. Microsoft may -use this information to provide services and improve our products and services. You may opt-out of many of these scenarios, but -not all, as described in the product documentation. There are also some features in the software that may enable you to collect -data from users of your applications. If you use these features to enable data collection in your applications, you must comply -with applicable law, including providing appropriate notices to users of your applications. You can learn more about data -collection and use in the help documentation and the privacy statement at http://go.microsoft.com/fwlink/?LinkID=528096. Your -use of the software operates as your consent to these practices. - -4. PRE-RELEASE SOFTWARE. This software is a pre-release version. It may not work the way a final version of the software will. -We may change it for the final, commercial version. We also may not release a commercial version. - -5. FEEDBACK. If you give feedback about the software to Microsoft, you give to Microsoft, without charge, the right to use, -share and commercialize your feedback in any way and for any purpose. You will not give feedback that is subject to a license -that requires Microsoft to license its software or documentation to third parties because we include your feedback in them. -These rights survive this agreement. - -6. SCOPE OF LICENSE. The software is licensed, not sold. This agreement only gives you some rights to use the software. -Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the -software only as expressly permitted in this agreement. In doing so, you must comply with any technical limitations in the -software that only allow you to use it in certain ways. For more information, see www.microsoft.com/licensing/userights. You -may not +a. Third Party Components. The software may include third party components with separate +legal notices or governed by other agreements, as may be described in the ThirdPartyNotices +file(s) accompanying the software. + +3. DATA. +a. Data Collection. The software may collect information about you and your use of the software, +and send that to Microsoft. Microsoft may use this information to provide services and improve +our products and services. You may opt-out of many of these scenarios, but not all, as described +in the product documentation. There are also some features in the software that may enable +you and Microsoft to collect data from users of your applications. If you use these features, you +must comply with applicable law, including providing appropriate notices to users of your +applications together with a copy of Microsoft’s privacy statement. Our privacy statement is +located at https://go.microsoft.com/fwlink/?LinkID=824704. You can learn more about data +collection and use in the help documentation and our privacy statement. Your use of the software +operates as your consent to these practices. +b. Processing of Personal Data. To the extent Microsoft is a processor or subprocessor of +personal data in connection with the software, Microsoft makes the commitments in the +European Union General Data Protection Regulation Terms of the Online Services Terms to all +customers effective May 25, 2018, at http://go.microsoft.com/?linkid=9840733. + +4. SCOPE OF LICENSE. The software is licensed, not sold. This agreement only gives you some rights +to use the software. Microsoft reserves all other rights. Unless applicable law gives you more rights +despite this limitation, you may use the software only as expressly permitted in this agreement. In +doing so, you must comply with any technical limitations in the software that only allow you to use it +in certain ways. For more information, see www.microsoft.com/licensing/userights. You may not * work around any technical limitations in the software; -* reverse engineer, decompile or disassemble the software, or attempt to do so, except and only to the extent required by third -party licensing terms governing use of certain open-source components that may be included with the software; +* reverse engineer, decompile or disassemble the software, or attempt to do so, except and only to +the extent required by third party licensing terms governing use of certain open-source +components that may be included with the software; * remove, minimize, block or modify any notices of Microsoft or its suppliers in the software; * use the software in any way that is against the law; or -* share, publish, rent, or lease the software, or provide the software as a stand-alone hosted as solution for others to use. - -7. EXPORT RESTRICTIONS. You must comply with all domestic and international export laws and regulations that apply to the -software, which include restrictions on destinations, end users and end use. For further information on export restrictions, -visit (aka.ms/exporting). - -8. SUPPORT SERVICES. Because this software is “as is,” we may not provide support services for it. - -9. ENTIRE AGREEMENT. This agreement, and the terms for supplements, updates, Internet-based services and support services that -you use, are the entire agreement for the software and support services. - -10. APPLICABLE LAW. If you acquired the software in the United States, Washington law applies to interpretation of and claims -for breach of this agreement, and the laws of the state where you live apply to all other claims. If you acquired the software -in any other country, its laws apply. - -11. CONSUMER RIGHTS; REGIONAL VARIATIONS. This agreement describes certain legal rights. You may have other rights, including -consumer rights, under the laws of your state or country. Separate and apart from your relationship with Microsoft, you may -also have rights with respect to the party from which you acquired the software. This agreement does not change those other -rights if the laws of your state or country do not permit it to do so. For example, if you acquired the software in one of the -below regions, or mandatory country law applies, then the following provisions apply to you: -a. Australia. You have statutory guarantees under the Australian Consumer Law and nothing in this agreement is intended to -affect those rights. -b. Canada. If you acquired this software in Canada, you may stop receiving updates by turning off the automatic update feature, -disconnecting your device from the Internet (if and when you re-connect to the Internet, however, the software will resume -checking for and installing updates), or uninstalling the software. The product documentation, if any, may also specify how to -turn off updates for your specific device or software. +* share, publish, rent, or lease the software, or provide the software as a stand-alone offering for +others to use. + +5. EXPORT RESTRICTIONS. You must comply with all domestic and international export laws and +regulations that apply to the software, which include restrictions on destinations, end users and end +use. For further information on export restrictions, visit (aka.ms/exporting). + +6. SUPPORT SERVICES. Because this software is “as is,” we may not provide support services for it. + +7. ENTIRE AGREEMENT. This agreement, and the terms for supplements, updates, Internet-based +services and support services that you use, are the entire agreement for the software and support +services. + +8. APPLICABLE LAW. If you acquired the software in the United States, Washington law applies to +interpretation of and claims for breach of this agreement, and the laws of the state where you live +apply to all other claims. If you acquired the software in any other country, its laws apply. + +9. CONSUMER RIGHTS; REGIONAL VARIATIONS. This agreement describes certain legal rights. +You may have other rights, including consumer rights, under the laws of your state or country. +Separate and apart from your relationship with Microsoft, you may also have rights with respect to +the party from which you acquired the software. This agreement does not change those other rights +if the laws of your state or country do not permit it to do so. For example, if you acquired the +software in one of the below regions, or mandatory country law applies, then the following provisions +apply to you: +a. Australia. You have statutory guarantees under the Australian Consumer Law and nothing in +this agreement is intended to affect those rights. +b. Canada. If you acquired this software in Canada, you may stop receiving updates by turning off +the automatic update feature, disconnecting your device from the Internet (if and when you re- +connect to the Internet, however, the software will resume checking for and installing updates), +or uninstalling the software. The product documentation, if any, may also specify how to turn off +updates for your specific device or software. c. Germany and Austria. -(i) Warranty. The properly licensed software will perform substantially as described in any Microsoft materials that accompany -the software. However, Microsoft gives no contractual guarantee in relation to the licensed software. -(ii) Limitation of Liability. In case of intentional conduct, gross negligence, claims based on the Product Liability Act, as -well as, in case of death or personal or physical injury, Microsoft is liable according to the statutory law. -Subject to the foregoing clause (ii), Microsoft will only be liable for slight negligence if Microsoft is in breach of such -material contractual obligations, the fulfillment of which facilitate the due performance of this agreement, the breach of -which would endanger the purpose of this agreement and the compliance with which a party may constantly trust in (so-called -"cardinal obligations"). In other cases of slight negligence, Microsoft will not be liable for slight negligence. - -12. DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED "AS-IS." YOU BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS -WARRANTIES, GUARANTEES OR CONDITIONS. TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES THE IMPLIED WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - -13. LIMITATION ON AND EXCLUSION OF DAMAGES. YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. -$5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES. -This limitation applies to (a) anything related to the software, services, content (including code) on third party Internet -sites, or third party applications; and (b) claims for breach of contract, breach of warranty, guarantee or condition, strict -liability, negligence, or other tort to the extent permitted by applicable law. -It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or -exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or -other damages. -Please note: As this software is distributed in Quebec, Canada, some of the clauses in this agreement are provided below in -French. -Remarque : Ce logiciel étant distribué au Québec, Canada, certaines des clauses dans ce contrat sont fournies ci-dessous en -français. -EXONÉRATION DE GARANTIE. Le logiciel visé par une licence est offert « tel quel ». Toute utilisation de ce logiciel est à votre -seule risque et péril. Microsoft n’accorde aucune autre garantie expresse. Vous pouvez bénéficier de droits additionnels en -vertu du droit local sur la protection des consommateurs, que ce contrat ne peut modifier. La ou elles sont permises par le -droit locale, les garanties implicites de qualité marchande, d’adéquation à un usage particulier et d’absence de contrefaçon -sont exclues. -LIMITATION DES DOMMAGES-INTÉRÊTS ET EXCLUSION DE RESPONSABILITÉ POUR LES DOMMAGES. Vous pouvez obtenir de Microsoft et de ses -fournisseurs une indemnisation en cas de dommages directs uniquement à hauteur de 5,00 $ US. Vous ne pouvez prétendre à aucune -indemnisation pour les autres dommages, y compris les dommages spéciaux, indirects ou accessoires et pertes de bénéfices. +(i) Warranty. The properly licensed software will perform substantially as described in any +Microsoft materials that accompany the software. However, Microsoft gives no contractual +guarantee in relation to the licensed software. +(ii) Limitation of Liability. In case of intentional conduct, gross negligence, claims based +on the Product Liability Act, as well as, in case of death or personal or physical injury, Microsoft is +liable according to the statutory law. +Subject to the foregoing clause (ii), Microsoft will only be liable for slight negligence if Microsoft is +in breach of such material contractual obligations, the fulfillment of which facilitate the due +performance of this agreement, the breach of which would endanger the purpose of this +agreement and the compliance with which a party may constantly trust in (so-called "cardinal +obligations"). In other cases of slight negligence, Microsoft will not be liable for slight negligence. + +10. DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED “AS-IS.” YOU BEAR THE RISK +OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES OR +CONDITIONS. TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS, MICROSOFT +EXCLUDES THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NON-INFRINGEMENT. + +11. LIMITATION ON AND EXCLUSION OF DAMAGES. YOU CAN RECOVER FROM MICROSOFT +AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER +ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, +INDIRECT OR INCIDENTAL DAMAGES. + +This limitation applies to (a) anything related to the software, services, content (including code) on +third party Internet sites, or third party applications; and (b) claims for breach of contract, breach of +warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by +applicable law. + +It also applies even if Microsoft knew or should have known about the possibility of the damages. +The above limitation or exclusion may not apply to you because your country may not allow the +exclusion or limitation of incidental, consequential or other damages. + +Please note: As this software is distributed in Quebec, Canada, some of the clauses in this +agreement are provided below in French. + +Remarque : Ce logiciel étant distribué au Québec, Canada, certaines des clauses dans ce +contrat sont fournies ci-dessous en français. + +EXONÉRATION DE GARANTIE. Le logiciel visé par une licence est offert « tel quel ». Toute utilisation +de ce logiciel est à votre seule risque et péril. Microsoft n’accorde aucune autre garantie expresse. Vous +pouvez bénéficier de droits additionnels en vertu du droit local sur la protection des consommateurs, que +ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de +qualité marchande, d’adéquation à un usage particulier et d’absence de contrefaçon sont exclues. + +LIMITATION DES DOMMAGES-INTÉRÊTS ET EXCLUSION DE RESPONSABILITÉ POUR LES +DOMMAGES. Vous pouvez obtenir de Microsoft et de ses fournisseurs une indemnisation en cas de +dommages directs uniquement à hauteur de 5,00 $ US. Vous ne pouvez prétendre à aucune +indemnisation pour les autres dommages, y compris les dommages spéciaux, indirects ou accessoires et +pertes de bénéfices. Cette limitation concerne: -·     tout ce qui est relié au logiciel, aux services ou au contenu (y compris le code) figurant sur des sites Internet tiers ou -dans des programmes tiers ; et -·     les réclamations au titre de violation de contrat ou de garantie, ou au titre de responsabilité stricte, de négligence ou -d’une autre faute dans la limite autorisée par la loi en vigueur. -Elle s’applique également, même si Microsoft connaissait ou devrait connaître l’éventualité d’un tel dommage. Si votre pays -n’autorise pas l’exclusion ou la limitation de responsabilité pour les dommages indirects, accessoires ou de quelque nature que -ce soit, il se peut que la limitation ou l’exclusion ci-dessus ne s’appliquera pas à votre égard. -EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous pourriez avoir d’autres droits prévus par les lois -de votre pays. Le présent contrat ne modifie pas les droits que vous confèrent les lois de votre pays si celles-ci ne le -permettent pas. +* tout ce qui est relié au logiciel, aux services ou au contenu (y compris le code) figurant sur des sites +Internet tiers ou dans des programmes tiers ; et +* les réclamations au titre de violation de contrat ou de garantie, ou au titre de responsabilité stricte, +de négligence ou d’une autre faute dans la limite autorisée par la loi en vigueur. + +Elle s’applique également, même si Microsoft connaissait ou devrait connaître l’éventualité d’un tel +dommage. Si votre pays n’autorise pas l’exclusion ou la limitation de responsabilité pour les dommages +indirects, accessoires ou de quelque nature que ce soit, il se peut que la limitation ou l’exclusion ci-dessus +ne s’appliquera pas à votre égard. + +EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous pourriez avoir d’autres +droits prévus par les lois de votre pays. Le présent contrat ne modifie pas les droits que vous confèrent +les lois de votre pays si celles-ci ne le permettent pas. diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 000000000..35a6da47e --- /dev/null +++ b/codecov.yml @@ -0,0 +1,5 @@ +coverage: + status: + project: + default: + threshold: 100% \ No newline at end of file diff --git a/debugger-launchjson.md b/debugger-launchjson.md index 644aee9be..1ed13a03c 100644 --- a/debugger-launchjson.md +++ b/debugger-launchjson.md @@ -50,6 +50,23 @@ Environment variables may be passed to your program using this schema: "myVariableName":"theValueGoesHere" } +NOTE: Environment variables can also be configured through a `${cwd}/Properties/launchSettings.json` file, which is useful for environment variables that should be set in all development scenarios -- when the project is started from the command line (`dotnet run`), from Visual Studio Code, or Visual Studio. + +Example Properties/launchSettings.json file: + +```json +{ + "profiles": { + "ProfileNameGoesHere": { + "commandName": "Project", + "environmentVariables": { + "myVariableName":"theValueGoesHere" + } + } + } +} +``` + ## Console (terminal) window By default, processes are launched with their console output (stdout/stderr) going to the VS Code Debugger Console. This is useful for executables that take their input from the network, files, etc. But this does NOT work for applications that want to read from the console (ex: `Console.ReadLine`). For these applications, use a setting such as the following: @@ -66,11 +83,6 @@ You can optionally configure a file by file mapping by providing map following t "C:\\foo":"/home/me/foo" } -## Symbol Path -You can optionally provide paths to symbols following this schema: - - "symbolPath": [ "/Volumes/symbols" ] - ## Just My Code You can optionally disable `justMyCode` by setting it to "false". You should disable Just My Code when you are trying to debug into a library that you pulled down which doesn't have symbols or is optimized. @@ -110,7 +122,103 @@ More information about pipe transport can be found [here](https://github.com/Omn You can find information on configuring pipe transport for [Windows Subsystem for Linux](https://msdn.microsoft.com/en-us/commandline/wsl/about) (WSL) [here](https://github.com/OmniSharp/omnisharp-vscode/wiki/Windows-Subsystem-for-Linux). -## Operating System Specific Configurations +### Operating System Specific Configurations If there specific commands that need to be changed per operating system, you can use the fields: 'windows', 'osx', or 'linux'. You can replace any of the fields mentioned above for the specific operating system. +## Suppress JIT Optimizations + +The .NET Debugger supports the following option. If true, when an optimized module (.dll compiled in the Release configuration) loads in the target process, the debugger will ask the Just-In-Time compiler to generate code with optimizations disabled. The option defaults to false. + +``` + "suppressJITOptimizations": true +``` + +**How optimizations work in .NET:** If you are trying to debug code, it is easier when that code is **NOT** optimized. This is because when code is optimized, the compiler and runtime will make changes to the emitted CPU code so that it runs faster, but has a less direct mapping to original source code. This means that debuggers are frequently unable to tell you the value of local variables, and code stepping and breakpoints might not work as you expect. + +Normally the Release build configuration creates optimized code and the Debug build configuration does not. The `Optimize` MSBuild property controls whether the compiler is told to optimize code. + +In the .NET ecosystem, code is turned from source to CPU instructions in a two-step process: first, the C# compiler converts the text you type in to an intermediate binary form called MSIL and writes this out to .dll files. Later, the .NET Runtime converts this MSIL to CPU instructions. Both steps can optimize to some degree, but the second step performed by the .NET Runtime performs the more significant optimizations. + +**What does the option do:** This option controls what happens when a DLL that was compiled with optimizations enabled loads inside of the target process. If this option is false (the default value), then when the .NET Runtime compiles the MSIL code into CPU code, it leaves the optimizations enabled. If the option is true, then the debugger requests that optimizations be disabled. + +**When should you use this option:** This option should be used when you have downloaded dlls from another source, such as a nuget package, and you want to debug the code in this DLL. In order for this to work you must also find the symbol (.pdb) file for this DLL. + +If you are only interested in debugging code you are building locally, it is best to leave this option false, as, in some cases, enabling this option will significantly slow down debugging. There are two reason for this slow down -- + +* Optimized code runs faster. If you are turning off optimizations for lots of code the time can add up. +* If you have Just My Code enabled, the debugger will not even try and load symbols for dlls which are optimized. Finding symbols can take a long time. + +**Limitations of this option:** There are two situations where this option will **NOT** work: + +1: In situations where you are attaching the debugger to an already running process, this option will have no effect on modules that were already loaded at the time the debugger was attached. + +2: This option has no effect on dlls that have been pre-compiled (a.k.a ngen'ed) to native code. However, you can disable usage of pre-compiled code by starting the process with the environment variable 'COMPlus_ZapDisable' set to '1'. If you are launching under the debugger, this code be done by adding this to launch.json -- + +```json + "env": { + "COMPlus_ZapDisable": "1" + } +``` + +## Symbol Options + +The `symbolOptions` element allows customization of how the debugger searches for symbols. Example: + +```json + "symbolOptions": { + "searchPaths": [ + "~/src/MyOtherProject/bin/debug", + "https://my-companies-symbols-server" + ], + "searchMicrosoftSymbolServer": true, + "cachePath": "/symcache", + "moduleFilter": { + "mode": "loadAllButExcluded", + "excludedModules": [ "DoNotLookForThisOne*.dll" ] + } + } +``` + +### Properties: + +**searchPaths**: Array of symbol server URLs (example: https://msdl.microsoft.com/download/symbols) or directories (example: /build/symbols) to search for .pdb files. These directories will be searched in addition to the default locations -- next to the module and the path where the pdb was originally dropped to. + +**searchMicrosoftSymbolServer**: If `true` the Microsoft Symbol server (https://msdl.microsoft.com/download/symbols) is added to the symbols search path. If unspecified, this option defaults to `false`. + +**cachePath**": Directory where symbols downloaded from symbol servers should be cached. If unspecified, on Windows the debugger will default to %TEMP%\\SymbolCache, and on Linux and macOS the debugger will default to ~/.vsdbg/SymbolCache. + +**moduleFilter.mode**: This value is either `"loadAllButExcluded"` or `"loadOnlyIncluded"`. In `"loadAllButExcluded"` mode, the debugger loads symbols for all modules unless the module is in the 'excludedModules' array. In `"loadOnlyIncluded"` mode, the debugger will not attempt to load symbols for ANY module unless it is in the 'includedModules' array, or it is included through the 'includeSymbolsNextToModules' setting. + +#### Properties for `"loadAllButExcluded"` mode: +**moduleFilter.excludedModules**: Array of modules that the debugger should NOT load symbols for. Wildcards (example: MyCompany.*.dll) are supported. + +#### Properties for `"loadOnlyIncluded"` mode: +**moduleFilter.includedModules**: Array of modules that the debugger should load symbols for. Wildcards (example: MyCompany.*.dll) are supported. + +**moduleFilter.includeSymbolsNextToModules**: If true, for any module NOT in the 'includedModules' array, the debugger will still check next to the module itself and the launching executable, but it will not check paths on the symbol search list. This option defaults to 'true'. + +## Source Link options + +Source Link is a feature that makes it so that when you are debugging code that was built on another computer, such as code coming from a nuget package, the debugger can automatically bring up matching source code by downloading it from the web. To make this work, the .pdb files for the code you are debugging contains data that maps the source files in the DLL to a URL that the debugger can download from. More information about Source Link can be found at [https://aka.ms/SourceLinkSpec](https://aka.ms/SourceLinkSpec). + +The `sourceLinkOptions` element in launch.json allows customization of Source Link behavior by URL. It is a map from URL to Source Link options for that URL. Wildcards are supported in the URL name. Currently the only customization is if Source Link is enabled for that URL, but more options may be added in the future. + +Example: + +```json + "sourceLinkOptions": { + "https://raw.githubusercontent.com/*": { "enabled": true }, + "*": { "enabled": false } + } +``` + +This example will enable Source Link for GitHub URLs, and disable Source Link for all other URLs. + +The default value of this option is to enable Source Link for all URLs. Similarly, Source Link will be enabled for any URL that doesn't have a rule in the `sourceLinkOptions` map. + +To disable Source Link for all URLs, use `"sourceLinkOptions": { "*": { "enabled": false } }`. + +If multiple entries cover the same URL, the more specific entry (the entry with the longer string length) will be used. + +Currently Source Link only works for source files that can be accessed without authentication. So, for example, the debugger can download source files from open source projects on GitHub, but it cannot download from private GitHub repos, or from Visual Studio Team Services. diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index dd2b06202..000000000 --- a/gulpfile.js +++ /dev/null @@ -1,171 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -'use strict'; - -const fs = require('fs'); -const path = require('path'); -const del = require('del'); -const gulp = require('gulp'); -const mocha = require('gulp-mocha'); -const tslint = require('gulp-tslint'); -const vsce = require('vsce'); -const debugUtil = require('./out/src/coreclr-debug/util'); -const packages = require('./out/src/packages'); -const logger = require('./out/src/logger'); -const platform = require('./out/src/platform'); -const util = require('./out/src/common'); -const child_process = require('child_process'); -const optionsSchemaGenerator = require('./out/src/tools/GenerateOptionsSchema'); -const packageDependencyUpdater = require('./out/src/tools/UpdatePackageDependencies'); - -const Logger = logger.Logger; -const PackageManager = packages.PackageManager; -const LinuxDistribution = platform.LinuxDistribution; -const PlatformInformation = platform.PlatformInformation; - -function cleanSync(deleteVsix) { - del.sync('install.*'); - del.sync('.omnisharp*'); - del.sync('.debugger'); - - if (deleteVsix) { - del.sync('*.vsix'); - } -} - -gulp.task('clean', () => { - cleanSync(true); -}); - -gulp.task('generateOptionsSchema', () => { - optionsSchemaGenerator.GenerateOptionsSchema(); -}); - -gulp.task('updatePackageDependencies', () => { - packageDependencyUpdater.updatePackageDependencies(); -}); - -// Install Tasks -function install(platformInfo, packageJSON) { - const packageManager = new PackageManager(platformInfo, packageJSON); - const logger = new Logger(message => process.stdout.write(message)); - const debuggerUtil = new debugUtil.CoreClrDebugUtil(path.resolve('.'), logger); - - return packageManager.DownloadPackages(logger) - .then(() => { - return packageManager.InstallPackages(logger); - }) - .then(() => { - return util.touchInstallFile(util.InstallFileType.Lock) - }) - .then(() => { - return debugUtil.CoreClrDebugUtil.writeEmptyFile(debuggerUtil.installCompleteFilePath()); - }); -} - -gulp.task('install', ['clean'], () => { - util.setExtensionPath(__dirname); - - return PlatformInformation.GetCurrent() - .then(platformInfo => { - return install(platformInfo, getPackageJSON()); - }); -}); - -/// Packaging (VSIX) Tasks -function doPackageSync(packageName) { - - var vsceArgs = []; - vsceArgs.push(path.join(__dirname, 'node_modules', 'vsce', 'out', 'vsce')) - vsceArgs.push('package'); // package command - - if (packageName !== undefined) { - vsceArgs.push('-o'); - vsceArgs.push(packageName); - } - - var proc = child_process.spawnSync('node', vsceArgs); - if (proc.error) { - console.error(proc.error.toString()); - } -} - -function doOfflinePackage(platformInfo, packageName, packageJSON) { - if (process.platform === 'win32') { - throw new Error('Do not build offline packages on windows. Runtime executables will not be marked executable in *nix packages.'); - } - - cleanSync(false); - return install(platformInfo, packageJSON) - .then(() => { - doPackageSync(packageName + '-' + platformInfo.platform + '-' + platformInfo.architecture + '.vsix'); - }); -} - -function getPackageJSON() { - return JSON.parse(fs.readFileSync('package.json')); -} - -gulp.task('package:clean', () => { - del.sync('*.vsix'); -}); - -gulp.task('package:online', ['clean'], () => { - doPackageSync(); -}); - -gulp.task('package:offline', ['clean'], () => { - util.setExtensionPath(__dirname); - - var packageJSON = getPackageJSON(); - var name = packageJSON.name; - var version = packageJSON.version; - var packageName = name + '.' + version; - - var packages = []; - packages.push(new PlatformInformation('win32', 'x86_64')); - packages.push(new PlatformInformation('darwin', 'x86_64')); - packages.push(new PlatformInformation('linux', 'x86_64')); - - var promise = Promise.resolve(); - - packages.forEach(platformInfo => { - promise = promise - .then(() => { - return doOfflinePackage(platformInfo, packageName, packageJSON); - }); - }); - - return promise; -}); - -/// Misc Tasks -const allTypeScript = [ - 'src/**/*.ts', - '!**/*.d.ts', - '!**/typings**' -]; - -const lintReporter = (output, file, options) => { - //emits: src/helloWorld.c:5:3: warning: implicit declaration of function ‘prinft’ - var relativeBase = file.base.substring(file.cwd.length + 1).replace('\\', '/'); - output.forEach(e => { - var message = relativeBase + e.name + ':' + (e.startPosition.line + 1) + ':' + (e.startPosition.character + 1) + ': ' + e.failure; - console.log('[tslint] ' + message); - }); -}; - -gulp.task('tslint', () => { - gulp.src(allTypeScript) - .pipe(tslint({ - program: require('tslint').Linter.createProgram("./tsconfig.json"), - configuration: "./tslint.json" - })) - .pipe(tslint.report(lintReporter, { - summarizeFailureOutput: false, - emitError: false - })) -}); diff --git a/gulpfile.ts b/gulpfile.ts new file mode 100644 index 000000000..7b29c4c97 --- /dev/null +++ b/gulpfile.ts @@ -0,0 +1,43 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import * as gulp from 'gulp'; +import * as optionsSchemaGenerator from './src/tools/GenerateOptionsSchema'; +import * as packageDependencyUpdater from './src/tools/UpdatePackageDependencies'; +import tslint from 'gulp-tslint'; + +require('./tasks/testTasks'); +require('./tasks/onlinePackagingTasks'); +require('./tasks/offlinePackagingTasks'); +require('./tasks/backcompatTasks'); +require('./tasks/coverageTasks'); + +gulp.task('generateOptionsSchema', () => { + optionsSchemaGenerator.GenerateOptionsSchema(); +}); + +gulp.task('updatePackageDependencies', () => { + packageDependencyUpdater.updatePackageDependencies(); +}); + +gulp.task('tslint', () => { + gulp.src([ + '**/*.ts', + '!**/*.d.ts', + '!**/typings**', + '!node_modules/**', + '!vsix/**' + ]) + .pipe(tslint({ + program: require('tslint').Linter.createProgram("./tsconfig.json"), + configuration: "./tslint.json" + })) + .pipe(tslint.report({ + summarizeFailureOutput: false, + emitError: false + })); +}); \ No newline at end of file diff --git a/mocha.opts b/mocha.opts new file mode 100644 index 000000000..630fc14c6 --- /dev/null +++ b/mocha.opts @@ -0,0 +1,3 @@ +--ui tdd +--require source-map-support/register +--require ts-node/register diff --git a/offline.vscodeignore b/offline.vscodeignore new file mode 100644 index 000000000..8222e783f --- /dev/null +++ b/offline.vscodeignore @@ -0,0 +1,37 @@ +!.debugger/** +.logs/** +.nyc_output/** +!.omnisharp/** +.rpt2_cache/** +.travis/** +.vscode/** +.vscode-test/** +coverage/** +out/test/** +src/** +tasks/** +test/** +typings/** +vsix/** + +**/*.map +*.vsix + +.editorconfig +.gitignore +.travis.yml +gulpfile.ts +!install.Lock +ISSUE_TEMPLATE +mocha.opts +*.vscodeignore +package-lock.json +package.json +test-plan.md +tsconfig.json +tslint.json +wallaby.js + + ++RuntimeLicenses/dependencies/* +coreclr-debug/install.log \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 878983cb6..0f665b37a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,22 @@ { "name": "csharp", - "version": "1.14.0-beta2", + "version": "1.15.0-beta4", "lockfileVersion": 1, "requires": true, "dependencies": { + "@types/archiver": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@types/archiver/-/archiver-2.1.1.tgz", + "integrity": "sha512-xejo0g2dIEy6qrQfOfOXNWwbBn397hTl8DHe6pETGwjjTCTdRER4j6vpaeWOBSMuC7zdFbp7i/iipGbo35IQEw==", + "dev": true, + "requires": { + "@types/glob": "5.0.35" + } + }, "@types/chai": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.0.8.tgz", - "integrity": "sha512-m812CONwdZn/dMzkIJEY0yAs4apyTkTORgfB2UsMOxgkUbC205AHnm4T8I0I5gPg9MHrFc1dJ35iS75c0CJkjg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.2.tgz", + "integrity": "sha512-D8uQwKYUw2KESkorZ27ykzXgvkDJYXVEihGklgfp5I4HUP8D6IxtcdLTMB1emjQiWzV7WZ5ihm1cxIzVwjoleQ==", "dev": true }, "@types/chai-arrays": { @@ -16,75 +25,277 @@ "integrity": "sha512-/kgYvj5Pwiv/bOlJ6c5GlRF/W6lUGSLrpQGl/7Gg6w7tvBYcf0iF91+wwyuwDYGO2zM0wNpcoPixZVif8I/r6g==", "dev": true, "requires": { - "@types/chai": "4.0.8" + "@types/chai": "4.1.2" + } + }, + "@types/chai-as-promised": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.0.tgz", + "integrity": "sha512-MFiW54UOSt+f2bRw8J7LgQeIvE/9b4oGvwU7XW30S9QGAiHGnU/fmiOprsyMkdmH2rl8xSPc0/yrQw8juXU6bQ==", + "dev": true, + "requires": { + "@types/chai": "4.1.2" + } + }, + "@types/chai-string": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@types/chai-string/-/chai-string-1.4.0.tgz", + "integrity": "sha512-iR9OZXsjfA9TQBMgqXdJQwStPjEadpzTOlESbr9JYWCdckKf/nmkc+zOJwY/HYpOkyGbOWQ+0yNXK76CgCIBeQ==", + "dev": true, + "requires": { + "@types/chai": "4.1.2" } }, + "@types/del": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/del/-/del-3.0.1.tgz", + "integrity": "sha512-y6qRq6raBuu965clKgx6FHuiPu3oHdtmzMPXi8Uahsjdq1L6DL5fS/aY5/s71YwM7k6K1QIWvem5vNwlnNGIkQ==", + "dev": true, + "requires": { + "@types/glob": "5.0.35" + } + }, + "@types/events": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", + "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==", + "dev": true + }, + "@types/fancy-log": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@types/fancy-log/-/fancy-log-1.3.0.tgz", + "integrity": "sha512-mQjDxyOM1Cpocd+vm1kZBP7smwKZ4TNokFeds9LV7OZibmPJFEzY3+xZMrKfUdNT71lv8GoCPD6upKwHxubClw==", + "dev": true + }, "@types/fs-extra": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz", - "integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-5.0.2.tgz", + "integrity": "sha512-Q3FWsbdmkQd1ib11A4XNWQvRD//5KpPoGawA8aB2DR7pWKoW9XQv3+dGxD/Z1eVFze23Okdo27ZQytVFlweKvQ==", + "dev": true, + "requires": { + "@types/node": "9.6.4" + } + }, + "@types/glob": { + "version": "5.0.35", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-5.0.35.tgz", + "integrity": "sha512-wc+VveszMLyMWFvXLkloixT4n0harUIVZjnpzztaZ0nKLuul7Z32iMt2fUFGAaZ4y1XWjFRMtCI5ewvyh4aIeg==", + "dev": true, + "requires": { + "@types/events": "1.2.0", + "@types/minimatch": "3.0.3", + "@types/node": "9.6.4" + } + }, + "@types/gulp": { + "version": "3.8.36", + "resolved": "https://registry.npmjs.org/@types/gulp/-/gulp-3.8.36.tgz", + "integrity": "sha512-u6/zWPzYRNPAtvyFJ3/RSXjmBaBM1dVs5kW22/jU6J786ZGLfSndhLoNOpFI6FGQvqTA+QzFHjSMhpkAN+wxcQ==", + "dev": true, + "requires": { + "@types/node": "9.6.4", + "@types/orchestrator": "0.3.2", + "@types/vinyl": "2.0.2" + } + }, + "@types/gulp-mocha": { + "version": "0.0.32", + "resolved": "https://registry.npmjs.org/@types/gulp-mocha/-/gulp-mocha-0.0.32.tgz", + "integrity": "sha512-30OJubm6wl7oVFR7ibaaTl0h52sRQDJwB0h7SXm8KbPG7TN3Bb8QqNI7ObfGFjCoBCk9tr55R4278ckLMFzNcw==", "dev": true, "requires": { - "@types/node": "8.0.53" + "@types/mocha": "2.2.48", + "@types/node": "9.6.4" } }, + "@types/istanbul": { + "version": "0.4.30", + "resolved": "https://registry.npmjs.org/@types/istanbul/-/istanbul-0.4.30.tgz", + "integrity": "sha512-+hQU4fh2G96ze78uI5/V6+SRDZD1UnVrFn23i2eDetwfbBq3s0/zYP92xj/3qyvVMM3WnvS88N56zjz+HmL04A==", + "dev": true + }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "@types/minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=", + "dev": true + }, "@types/mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha512-XA4vNO6GCBz8Smq0hqSRo4yRWMqr4FPQrWjhJt6nKskzly4/p87SfuJMFYGRyYb6jo2WNIQU2FDBsY5r1BibUA==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.2.tgz", + "integrity": "sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==", "dev": true, "requires": { - "@types/node": "8.0.53" + "@types/node": "9.6.4" } }, "@types/mocha": { - "version": "2.2.32", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.32.tgz", - "integrity": "sha1-3aDabq8hldL/gI9CoXJbGhnn7Wk=", + "version": "2.2.48", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.48.tgz", + "integrity": "sha512-nlK/iyETgafGli8Zh9zJVCTicvU3iajSkRwOh3Hhiva598CMqNJ4NcVCGMTGKpGpTYj/9R8RLzS9NAykSSCqGw==", "dev": true }, "@types/node": { - "version": "8.0.53", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.53.tgz", - "integrity": "sha512-54Dm6NwYeiSQmRB1BLXKr5GELi0wFapR1npi8bnZhEcu84d/yQKqnwwXQ56hZ0RUbTG6L5nqDZaN3dgByQXQRQ==", + "version": "9.6.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.4.tgz", + "integrity": "sha512-Awg4BcUYiZtNKoveGOu654JVPt11V/KIC77iBz8NweyoOAZpz5rUJfPDwwD+ajfTs2HndbTCEB8IuLfX9m/mmw==", + "dev": true + }, + "@types/orchestrator": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@types/orchestrator/-/orchestrator-0.3.2.tgz", + "integrity": "sha512-cKB4yTX0wGaRCSkdHDX2fkGQbMAA8UOshC2U7DQky1CE5o+5q2iQQ8VkbPbE/88uaTtsusvBPMcCX7dgmjxBhQ==", + "dev": true, + "requires": { + "@types/node": "9.6.4", + "@types/q": "1.5.0" + } + }, + "@types/q": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.0.tgz", + "integrity": "sha512-sWj7AMiG0fYmta6ug1ublLjtj/tqn+CnCZeo7yswR1ykxel0FOWFGdWviTcGSNAMmtLbycDqbg6w98VPFKJmbw==", "dev": true }, "@types/semver": { - "version": "5.3.30", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.3.30.tgz", - "integrity": "sha1-tVo70HtrizX51EcuH8Mxi2ikk7I=", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==", "dev": true }, + "@types/shelljs": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/@types/shelljs/-/shelljs-0.7.8.tgz", + "integrity": "sha512-M2giRw93PxKS7YjU6GZjtdV9HASdB7TWqizBXe4Ju7AqbKlWvTr0gNO92XH56D/gMxqD/jNHLNfC5hA34yGqrQ==", + "dev": true, + "requires": { + "@types/glob": "5.0.35", + "@types/node": "9.6.4" + } + }, "@types/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.0.33.tgz", "integrity": "sha1-EHPEvIJHVK49EM+riKsCN7qWTk0=", "dev": true }, + "@types/vinyl": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/vinyl/-/vinyl-2.0.2.tgz", + "integrity": "sha512-2iYpNuOl98SrLPBZfEN9Mh2JCJ2EI9HU35SfgBEb51DcmaHkhp8cKMblYeBqMQiwXMgAD3W60DbQ4i/UdLiXhw==", + "dev": true, + "requires": { + "@types/node": "9.6.4" + } + }, + "@types/yauzl": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.0.tgz", + "integrity": "sha512-KVQbjKvieCq6d5LqZ8KIzzwygF88fWC+l7wvPbRPM3OI3f9ZAlhaKUlk3kjiyvOMqopSTM7enjduXXl5B+msXw==", + "dev": true, + "requires": { + "@types/events": "1.2.0", + "@types/node": "9.6.4" + } + }, + "abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", + "dev": true + }, "agent-base": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.1.2.tgz", - "integrity": "sha512-VE6QoEdaugY86BohRtfGmTDabxdU5sCKOkbcPA6PXKJsRzEi/7A3RCTxJal1ft/4qSfPht5/iQLhMh/wzSkkNw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.0.tgz", + "integrity": "sha512-c+R/U5X+2zz2+UCrCFv6odQzJdoqI+YecuhnAJLa1zYaMc13zPfwMwZrr91Pd1DYNo/yPRbiM4WVf9whgwFsIg==", "requires": { "es6-promisify": "5.0.0" } }, "ajv": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.1.tgz", - "integrity": "sha1-s4u4h22ehr7plJVqBOch6IskjrI=", + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", + "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", "dev": true, "requires": { "co": "4.6.0", - "fast-deep-equal": "1.0.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" + "json-stable-stringify": "1.0.1" + } + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "dev": true, + "requires": { + "kind-of": "3.2.2", + "longest": "1.0.1", + "repeat-string": "1.6.1" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + }, + "ansi-colors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", + "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", + "dev": true, + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-cyan": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz", + "integrity": "sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=", + "dev": true, + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-gray": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", + "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", + "dev": true, + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-red": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", + "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=", + "dev": true, + "requires": { + "ansi-wrap": "0.1.0" } }, "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, "ansi-styles": { @@ -93,10 +304,136 @@ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, + "ansi-wrap": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", + "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", + "dev": true + }, "applicationinsights": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-0.18.0.tgz", - "integrity": "sha1-Fi67SKODQIvE3kTbMrQXMH9Fu8E=" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.1.tgz", + "integrity": "sha1-U0Rrgw/o1dYZ7uKieLMdPSUDCSc=", + "requires": { + "diagnostic-channel": "0.2.0", + "diagnostic-channel-publishers": "0.2.1", + "zone.js": "0.7.6" + } + }, + "archiver": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-2.1.1.tgz", + "integrity": "sha1-/2YrSnggFJSj7lRNOjP+dJZQnrw=", + "dev": true, + "requires": { + "archiver-utils": "1.3.0", + "async": "2.6.0", + "buffer-crc32": "0.2.13", + "glob": "7.1.2", + "lodash": "4.17.5", + "readable-stream": "2.3.6", + "tar-stream": "1.5.5", + "zip-stream": "1.2.0" + }, + "dependencies": { + "async": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", + "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", + "dev": true, + "requires": { + "lodash": "4.17.5" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "lodash": { + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==", + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, + "archiver-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-1.3.0.tgz", + "integrity": "sha1-5QtMCccL89aA4y/xt5lOn52JUXQ=", + "dev": true, + "requires": { + "glob": "7.1.2", + "graceful-fs": "4.1.11", + "lazystream": "1.0.0", + "lodash": "4.17.5", + "normalize-path": "2.1.1", + "readable-stream": "2.3.6" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "lodash": { + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==", + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } }, "archy": { "version": "1.0.0", @@ -105,22 +442,25 @@ "dev": true }, "argparse": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", - "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "requires": { "sprintf-js": "1.0.3" } }, + "argv": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/argv/-/argv-0.0.2.tgz", + "integrity": "sha1-7L0W+JSbFXGDcRsb2jNPN4QBhas=", + "dev": true + }, "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "1.1.0" - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true }, "arr-flatten": { "version": "1.1.0", @@ -128,6 +468,12 @@ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", "dev": true }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, "array-differ": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", @@ -190,9 +536,9 @@ "dev": true }, "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, "arrify": { @@ -214,9 +560,21 @@ "dev": true }, "assertion-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz", - "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", "dev": true }, "async-arrays": { @@ -225,7 +583,16 @@ "integrity": "sha1-NHrytw8qeldnotVnnMQrvxwiD9k=", "dev": true, "requires": { - "sift": "5.0.0" + "sift": "5.1.0" + } + }, + "async-child-process": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/async-child-process/-/async-child-process-1.1.1.tgz", + "integrity": "sha1-J9ClmLVzhwf5iYwEi9IxNAWDdHs=", + "dev": true, + "requires": { + "babel-runtime": "6.26.0" } }, "async-file": { @@ -237,12 +604,28 @@ "rimraf": "2.6.2" } }, + "async-shelljs": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/async-shelljs/-/async-shelljs-0.1.2.tgz", + "integrity": "sha512-dk7WMFhb1dRfexI/2voIUDpmWX3XfPRyTWeafGUtdHqlcQgIZPk0St6+d9Ns3Eantq6MB+Lk4GwMCaSS8MkMRg==", + "dev": true, + "requires": { + "@types/shelljs": "0.7.8", + "shelljs": "0.8.1" + } + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, + "atob": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.0.tgz", + "integrity": "sha512-SuiKH8vbsOyCALjA/+EINmt/Kdl+TQPrtFgW7XZZcwtryFu9e5kQoX3bjCW6mIvGH1fbeAZZuvwGR5IlBRznGw==", + "dev": true + }, "aws-sign2": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", @@ -250,9 +633,9 @@ "dev": true }, "aws4": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", - "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", + "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==", "dev": true }, "babel-code-frame": { @@ -266,36 +649,111 @@ "js-tokens": "3.0.2" } }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "2.5.5", + "regenerator-runtime": "0.11.1" + } + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, - "base64-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.1.2.tgz", - "integrity": "sha1-1kAMrBxMZgl22Q0HoENR2JOV9eg=", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", - "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, - "optional": true, "requires": { - "tweetnacl": "0.14.5" - } - }, - "beeper": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", - "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", - "dev": true - }, - "bit-mask": { - "version": "1.0.1", + "cache-base": "1.0.1", + "class-utils": "0.3.6", + "component-emitter": "1.2.1", + "define-property": "1.0.0", + "isobject": "3.0.1", + "mixin-deep": "1.3.1", + "pascalcase": "0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" + } + } + } + }, + "base64-js": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.3.tgz", + "integrity": "sha512-MsAhsUW1GxCdgYSO6tAfZrNapmUKk7mWx/k5mFY/A1gBtkaCaNapTg+FExCw1r9yeaZhqx/xPg43xgTFH6KL5w==", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "dev": true, + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "beeper": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", + "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", + "dev": true + }, + "binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", + "dev": true, + "requires": { + "buffers": "0.1.1", + "chainsaw": "0.1.0" + } + }, + "bit-mask": { + "version": "1.0.1", "resolved": "https://registry.npmjs.org/bit-mask/-/bit-mask-1.0.1.tgz", "integrity": "sha1-188hK95uLcwFA/qrUJQeTrKJpvU=", "dev": true, @@ -303,6 +761,48 @@ "array-events": "0.2.0" } }, + "bl": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", + "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", + "dev": true, + "requires": { + "readable-stream": "2.3.6", + "safe-buffer": "5.1.1" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, "block-stream": { "version": "0.0.9", "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", @@ -312,6 +812,46 @@ "inherits": "2.0.3" } }, + "bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" + }, + "body-parser": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", + "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "dev": true, + "requires": { + "bytes": "3.0.0", + "content-type": "1.0.4", + "debug": "2.6.9", + "depd": "1.1.2", + "http-errors": "1.6.3", + "iconv-lite": "0.4.19", + "on-finished": "2.3.0", + "qs": "6.5.1", + "raw-body": "2.3.2", + "type-is": "1.6.16" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", + "dev": true + } + } + }, "boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -328,9 +868,9 @@ } }, "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { "balanced-match": "1.0.0", @@ -338,14 +878,32 @@ } }, "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.2" + "arr-flatten": "1.1.0", + "array-unique": "0.3.2", + "extend-shallow": "2.0.1", + "fill-range": "4.0.0", + "isobject": "3.0.1", + "repeat-element": "1.1.2", + "snapdragon": "0.8.2", + "snapdragon-node": "2.1.1", + "split-string": "3.1.0", + "to-regex": "3.0.2" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } } }, "browser-stdout": { @@ -359,36 +917,82 @@ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" }, + "buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=", + "dev": true + }, "builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", "dev": true }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "1.0.0", + "component-emitter": "1.2.1", + "get-value": "2.0.6", + "has-value": "1.0.0", + "isobject": "3.0.1", + "set-value": "2.0.0", + "to-object-path": "0.3.0", + "union-value": "1.0.0", + "unset-value": "1.0.0" + } + }, "call-me-maybe": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", "dev": true }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, "caseless": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", - "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "dev": true, + "optional": true, + "requires": { + "align-text": "0.1.4", + "lazy-cache": "1.0.4" + } + }, "chai": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", "dev": true, "requires": { - "assertion-error": "1.0.2", + "assertion-error": "1.1.0", "check-error": "1.0.2", "deep-eql": "3.0.1", "get-func-name": "2.0.0", "pathval": "1.1.0", - "type-detect": "4.0.5" + "type-detect": "4.0.8" } }, "chai-arrays": { @@ -397,6 +1001,15 @@ "integrity": "sha512-jWAvZu1BV8tL3pj0iosBECzzHEg+XB1zSnMjJGX83bGi/1GlGdDO7J/A0sbBBS6KJT0FVqZIzZW9C6WLiMkHpQ==", "dev": true }, + "chai-as-promised": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", + "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", + "dev": true, + "requires": { + "check-error": "1.0.2" + } + }, "chai-fs": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chai-fs/-/chai-fs-2.0.0.tgz", @@ -407,6 +1020,21 @@ "readdir-enhanced": "1.5.2" } }, + "chai-string": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/chai-string/-/chai-string-1.4.0.tgz", + "integrity": "sha1-NZFAwFHTak5LGl/GuRAVL0OKjUk=", + "dev": true + }, + "chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", + "dev": true, + "requires": { + "traverse": "0.3.9" + } + }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", @@ -418,6 +1046,23 @@ "has-ansi": "2.0.0", "strip-ansi": "3.0.1", "supports-color": "2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + } } }, "check-error": { @@ -436,22 +1081,56 @@ "dom-serializer": "0.1.0", "entities": "1.1.1", "htmlparser2": "3.9.2", - "lodash": "4.17.4", + "lodash": "4.17.5", "parse5": "3.0.3" }, "dependencies": { "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==", "dev": true } } }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "3.1.0", + "define-property": "0.2.5", + "isobject": "3.0.1", + "static-extend": "0.1.2" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + } + } + }, + "cliui": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.0.0.tgz", + "integrity": "sha512-nY3W5Gu2racvdDk//ELReY+dHjb9PlIcVDFXP72nVIhq2Gy3LuVXYwJoPVudwQnv1shtohpgkdCKT2YaKY0CKw==", + "dev": true, + "requires": { + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "wrap-ansi": "2.1.0" + } + }, "clone": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz", - "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", "dev": true }, "clone-buffer": { @@ -467,14 +1146,46 @@ "dev": true }, "cloneable-readable": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.0.0.tgz", - "integrity": "sha1-pikNQT8hemEjL5XkWP84QYz7ARc=", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.2.tgz", + "integrity": "sha512-Bq6+4t+lbM8vhTs/Bef5c5AdEMtapp/iFb6+s4/Hh9MVTt8OLKH7ZOOZSCT+Ys7hsHvqv0GuMPJ1lnQJVHvxpg==", "dev": true, "requires": { "inherits": "2.0.3", - "process-nextick-args": "1.0.7", - "through2": "2.0.3" + "process-nextick-args": "2.0.0", + "readable-stream": "2.3.6" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } } }, "co": { @@ -483,6 +1194,33 @@ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", "dev": true }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "codecov": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/codecov/-/codecov-3.0.0.tgz", + "integrity": "sha1-wnO4xPEpRXI+jcnSWAPYk0Pl8o4=", + "dev": true, + "requires": { + "argv": "0.0.2", + "request": "2.81.0", + "urlgrey": "0.4.4" + } + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "1.0.0", + "object-visit": "1.0.1" + } + }, "color-convert": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", @@ -498,22 +1236,75 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true + }, "combined-stream": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", - "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", + "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", "dev": true, "requires": { "delayed-stream": "1.0.0" } }, "commander": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "compress-commons": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-1.2.2.tgz", + "integrity": "sha1-UkqfEJA/OoEzibAiXSfEi7dRiQ8=", "dev": true, "requires": { - "graceful-readlink": "1.0.1" + "buffer-crc32": "0.2.13", + "crc32-stream": "2.0.0", + "normalize-path": "2.1.1", + "readable-stream": "2.3.6" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } } }, "concat-map": { @@ -522,26 +1313,129 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "convert-source-map": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", - "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "cross-env": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.1.1.tgz", - "integrity": "sha512-Wtvr+z0Z06KO1JxjfRRsPC+df7biIOiuV4iZ73cThjFGkH+ULBZq1MkBdywEcJC4cTDbO6c8IjgRjfswx3YTBA==", + "connect": { + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz", + "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=", + "dev": true, + "requires": { + "debug": "2.6.9", + "finalhandler": "1.1.0", + "parseurl": "1.3.2", + "utils-merge": "1.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "convert-source-map": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", + "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", + "dev": true + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "copyfiles": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-2.0.0.tgz", + "integrity": "sha512-NSSJdwCH27/hEiBlhkXYWh3AaPo8IATxLX5XtJQgknOvOehrREtETsGd/BNr2vuj0URgKBC/50PNRM3yShQGJQ==", + "dev": true, + "requires": { + "glob": "7.1.2", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "noms": "0.0.0", + "through2": "2.0.3", + "yargs": "11.0.0" + } + }, + "core-js": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.5.tgz", + "integrity": "sha1-sU3ek2xkDAV5prUMq8wTLdYSfjs=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "crc": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.5.0.tgz", + "integrity": "sha1-mLi6fUiWZbo5efWbITgTdBAaGWQ=", + "dev": true + }, + "crc32-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-2.0.0.tgz", + "integrity": "sha1-483TtN8xaN10494/u8t7KX/pCPQ=", + "dev": true, + "requires": { + "crc": "3.5.0", + "readable-stream": "2.3.6" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, + "cross-env": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.1.4.tgz", + "integrity": "sha512-Mx8mw6JWhfpYoEk7PGvHxJMLQwQHORAs8+2bX+C1lGQ4h3GkDb1zbzC2Nw85YH9ZQMlO0BHZxMacgrfPmMFxbg==", "dev": true, "requires": { "cross-spawn": "5.1.0", - "is-windows": "1.0.1" + "is-windows": "1.0.2" } }, "cross-spawn": { @@ -550,7 +1444,7 @@ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { - "lru-cache": "4.1.1", + "lru-cache": "4.1.2", "shebang-command": "1.2.0", "which": "1.3.0" } @@ -612,13 +1506,25 @@ "dev": true }, "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "requires": { "ms": "2.0.0" } }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, "deep-assign": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/deep-assign/-/deep-assign-1.0.0.tgz", @@ -634,16 +1540,22 @@ "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", "dev": true, "requires": { - "type-detect": "4.0.5" + "type-detect": "4.0.8" } }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, "defaults": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", "dev": true, "requires": { - "clone": "1.0.3" + "clone": "1.0.4" } }, "define-properties": { @@ -656,6 +1568,47 @@ "object-keys": "1.0.11" } }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "1.0.2", + "isobject": "3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" + } + } + } + }, "del": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", @@ -664,7 +1617,7 @@ "requires": { "globby": "6.1.0", "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.0", + "is-path-in-cwd": "1.0.1", "p-map": "1.2.0", "pify": "3.0.0", "rimraf": "2.6.2" @@ -682,6 +1635,12 @@ "integrity": "sha1-OjYof1A05pnnV3kBBSwubJQlFjE=", "dev": true }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, "deprecated": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz", @@ -689,18 +1648,28 @@ "dev": true }, "detect-file": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-0.1.0.tgz", - "integrity": "sha1-STXe39lIhkjgBrASlWbpOGcR6mM=", - "dev": true, + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true + }, + "diagnostic-channel": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", + "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", "requires": { - "fs-exists-sync": "0.1.0" + "semver": "5.5.0" } }, + "diagnostic-channel-publishers": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz", + "integrity": "sha1-ji1geottef6IC1SLxYzGvrKIxPM=" + }, "diff": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", - "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", + "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", "dev": true }, "dom-serializer": { @@ -759,24 +1728,38 @@ "dev": true, "requires": { "readable-stream": "1.1.14" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + } } }, "duplexify": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.1.tgz", - "integrity": "sha512-j5goxHTwVED1Fpe5hh3q9R93Kip0Bg2KVAt4f8CEYM3UEwYcPSvWbXaUQOzdX/HtiNomipv+gU7ASQPDbV7pGQ==", + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.4.tgz", + "integrity": "sha512-JzYSLYMhoVVBe8+mbHQ4KgpvHpm0DZpJuL8PY93Vyv1fW7jYJ90LoXa1di/CVbJM+TgMs91rbDapE/RNIfnJsA==", "dev": true, "requires": { - "end-of-stream": "1.4.0", + "end-of-stream": "1.4.1", "inherits": "2.0.3", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "stream-shift": "1.0.0" }, "dependencies": { "end-of-stream": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz", - "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", "dev": true, "requires": { "once": "1.4.0" @@ -789,24 +1772,24 @@ "dev": true }, "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { "core-util-is": "1.0.2", "inherits": "2.0.3", "isarray": "1.0.0", - "process-nextick-args": "1.0.7", + "process-nextick-args": "2.0.0", "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", + "string_decoder": "1.1.1", "util-deprecate": "1.0.2" } }, "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { "safe-buffer": "5.1.1" @@ -824,6 +1807,18 @@ "jsbn": "0.1.1" } }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, "end-of-stream": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz", @@ -860,9 +1855,9 @@ } }, "es-abstract": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz", - "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.11.0.tgz", + "integrity": "sha512-ZnQrE/lXTTQ39ulXZ+J1DTFazV9qBy61x2bY071B+qGco8Z8q1QddsLdt/EF8Ai9hcWH72dWS0kFqXLxOxqslA==", "dev": true, "requires": { "es-to-primitive": "1.1.1", @@ -884,24 +1879,67 @@ } }, "es6-promise": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.1.1.tgz", - "integrity": "sha512-OaU1hHjgJf+b0NzsxCg7NdIYERD6Hy/PEmFLTjw+b65scuisG3Kt4QoTvJ66BBkPZ581gr0kpoVzKnxniM8nng==" + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", + "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==" }, "es6-promisify": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", "requires": { - "es6-promise": "4.1.1" + "es6-promise": "4.2.4" } }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, + "escodegen": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", + "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", + "dev": true, + "requires": { + "esprima": "2.7.3", + "estraverse": "1.9.3", + "esutils": "2.0.2", + "optionator": "0.8.2", + "source-map": "0.2.0" + }, + "dependencies": { + "source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", + "dev": true, + "optional": true, + "requires": { + "amdefine": "1.0.1" + } + } + } + }, + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "dev": true + }, "esutils": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", @@ -910,7 +1948,7 @@ }, "event-stream": { "version": "3.3.4", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", + "resolved": "http://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", "dev": true, "requires": { @@ -932,9 +1970,9 @@ } }, "execa": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.6.3.tgz", - "integrity": "sha1-V7aaWU8IF1nGnlNw8NF7nLEWWP4=", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", "dev": true, "requires": { "cross-spawn": "5.1.0", @@ -947,12 +1985,47 @@ } }, "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "requires": { - "is-posix-bracket": "0.1.1" + "debug": "2.6.9", + "define-property": "0.2.5", + "extend-shallow": "2.0.1", + "posix-character-classes": "0.1.1", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } } }, "expand-range": { @@ -962,29 +2035,90 @@ "dev": true, "requires": { "fill-range": "2.2.3" + }, + "dependencies": { + "fill-range": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "dev": true, + "requires": { + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.7", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } } }, "expand-tilde": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz", - "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", "dev": true, "requires": { - "os-homedir": "1.0.2" + "homedir-polyfill": "1.0.1" } }, "extend": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", + "dev": true }, "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "assign-symbols": "1.0.0", + "is-extendable": "1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "2.0.4" + } + } } }, "extended-emitter": { @@ -993,17 +2127,73 @@ "integrity": "sha1-olIauT87G2mjX/OjXamIk4Wpm6A=", "dev": true, "requires": { - "sift": "5.0.0", + "sift": "5.1.0", "wolfy87-eventemitter": "5.2.4" } }, "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "1.0.0" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "0.3.2", + "define-property": "1.0.0", + "expand-brackets": "2.1.4", + "extend-shallow": "2.0.1", + "fragment-cache": "0.2.1", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" + } + } } }, "extsprintf": { @@ -1013,19 +2203,20 @@ "dev": true }, "fancy-log": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.0.tgz", - "integrity": "sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg=", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.2.tgz", + "integrity": "sha1-9BEl49hPLn2JpD0G2VjI94vha+E=", "dev": true, "requires": { - "chalk": "1.1.3", + "ansi-gray": "0.1.1", + "color-support": "1.1.3", "time-stamp": "1.1.0" } }, "fast-deep-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", - "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", "dev": true }, "fast-json-stable-stringify": { @@ -1034,6 +2225,12 @@ "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", "dev": true }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, "fd-slicer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", @@ -1048,17 +2245,93 @@ "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", "dev": true }, + "fileset": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fileset/-/fileset-0.2.1.tgz", + "integrity": "sha1-WI74lzxmI7KnbfRlEFaWuWqsgGc=", + "dev": true, + "requires": { + "glob": "5.0.15", + "minimatch": "2.0.10" + }, + "dependencies": { + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "2.0.10", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "minimatch": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", + "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", + "dev": true, + "requires": { + "brace-expansion": "1.1.11" + } + } + } + }, "fill-range": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", - "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { - "is-number": "2.1.0", - "isobject": "2.1.0", - "randomatic": "1.1.7", - "repeat-element": "1.1.2", - "repeat-string": "1.6.1" + "extend-shallow": "2.0.1", + "is-number": "3.0.0", + "repeat-string": "1.6.1", + "to-regex-range": "2.1.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "finalhandler": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", + "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "statuses": "1.3.1", + "unpipe": "1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", + "dev": true + } } }, "find-index": { @@ -1067,16 +2340,25 @@ "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", "dev": true }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "2.0.0" + } + }, "findup-sync": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.4.3.tgz", - "integrity": "sha1-QAQ5Kee8YK3wt/SCfExudaDeyhI=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", + "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", "dev": true, "requires": { - "detect-file": "0.1.0", - "is-glob": "2.0.1", - "micromatch": "2.3.11", - "resolve-dir": "0.1.1" + "detect-file": "1.0.0", + "is-glob": "3.1.0", + "micromatch": "3.1.10", + "resolve-dir": "1.0.1" } }, "fined": { @@ -1089,18 +2371,7 @@ "is-plain-object": "2.0.4", "object.defaults": "1.1.0", "object.pick": "1.3.0", - "parse-filepath": "1.0.1" - }, - "dependencies": { - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "dev": true, - "requires": { - "homedir-polyfill": "1.0.1" - } - } + "parse-filepath": "1.0.2" } }, "first-chunk-stream": { @@ -1110,9 +2381,9 @@ "dev": true }, "flagged-respawn": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-0.3.2.tgz", - "integrity": "sha1-/xke3c1wiKZ1smEP/8l2vpuAdLU=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.0.tgz", + "integrity": "sha1-Tnmumy6zi/hrO7Vr8+ClaqX8q9c=", "dev": true }, "for-in": { @@ -1122,9 +2393,9 @@ "dev": true }, "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", "dev": true, "requires": { "for-in": "1.0.2" @@ -1149,8 +2420,17 @@ "dev": true, "requires": { "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" + "combined-stream": "1.0.6", + "mime-types": "2.1.18" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "0.2.2" } }, "from": { @@ -1159,12 +2439,6 @@ "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", "dev": true }, - "fs-exists-sync": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", - "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=", - "dev": true - }, "fs-extra": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", @@ -1182,15 +2456,26 @@ "dev": true }, "fstream": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", - "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + "version": "0.1.31", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-0.1.31.tgz", + "integrity": "sha1-czfwWPu7vvqMn1YaKMqwhJICyYg=", "dev": true, "requires": { - "graceful-fs": "4.1.11", + "graceful-fs": "3.0.11", "inherits": "2.0.3", "mkdirp": "0.5.1", "rimraf": "2.6.2" + }, + "dependencies": { + "graceful-fs": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz", + "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=", + "dev": true, + "requires": { + "natives": "1.1.3" + } + } } }, "function-bind": { @@ -1223,18 +2508,36 @@ "is-property": "1.0.2" } }, + "get-caller-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", + "dev": true + }, "get-func-name": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, + "get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=", + "dev": true + }, "get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", "dev": true }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -1274,15 +2577,51 @@ "requires": { "glob-parent": "2.0.0", "is-glob": "2.0.1" + }, + "dependencies": { + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "2.0.1" + } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + } } }, "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "requires": { - "is-glob": "2.0.1" + "is-glob": "3.1.0", + "path-dirname": "1.0.2" + } + }, + "glob-promise": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/glob-promise/-/glob-promise-3.4.0.tgz", + "integrity": "sha512-q08RJ6O+eJn+dVanerAndJwIcumgbDdYiUT7zFQl3Wm1xD6fBKtah7H8ZJChj4wP+8C+QfeVy8xautR7rdmKEw==", + "dev": true, + "requires": { + "@types/glob": "5.0.35" } }, "glob-stream": { @@ -1317,19 +2656,7 @@ "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", "dev": true, "requires": { - "brace-expansion": "1.1.8" - } - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" + "brace-expansion": "1.1.11" } }, "through2": { @@ -1369,41 +2696,27 @@ } }, "global-modules": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz", - "integrity": "sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", "dev": true, "requires": { - "global-prefix": "0.1.5", - "is-windows": "0.2.0" - }, - "dependencies": { - "is-windows": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", - "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=", - "dev": true - } + "global-prefix": "1.0.2", + "is-windows": "1.0.2", + "resolve-dir": "1.0.1" } }, "global-prefix": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz", - "integrity": "sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", "dev": true, "requires": { + "expand-tilde": "2.0.2", "homedir-polyfill": "1.0.1", "ini": "1.3.5", - "is-windows": "0.2.0", + "is-windows": "1.0.2", "which": "1.3.0" - }, - "dependencies": { - "is-windows": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", - "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=", - "dev": true - } } }, "globby": { @@ -1480,9 +2793,9 @@ } }, "glogg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.0.tgz", - "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.1.tgz", + "integrity": "sha512-ynYqXLoluBKf9XGR1gA59yEJisIL7YHEH4xr3ZziHB5/yl4qWfaK8Js9jGe6gBGCSCKVqiyO30WnRZADvemUNw==", "dev": true, "requires": { "sparkles": "1.0.0" @@ -1493,16 +2806,10 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" }, - "graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", - "dev": true - }, "growl": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", - "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", + "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", "dev": true }, "gulp": { @@ -1516,7 +2823,7 @@ "deprecated": "0.0.1", "gulp-util": "3.0.8", "interpret": "1.1.0", - "liftoff": "2.3.0", + "liftoff": "2.5.0", "minimist": "1.2.0", "orchestrator": "0.3.8", "pretty-hrtime": "1.0.3", @@ -1526,12 +2833,6 @@ "vinyl-fs": "0.3.14" }, "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, "semver": { "version": "4.3.6", "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", @@ -1552,13 +2853,13 @@ } }, "gulp-filter": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/gulp-filter/-/gulp-filter-5.0.1.tgz", - "integrity": "sha512-5olRzAhFdXB2klCu1lnazP65aO9YdA/5WfC9VdInIc8PrUeDIoZfaA3Edb0yUBGhVdHv4eHKL9Fg5tUoEJ9z5A==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/gulp-filter/-/gulp-filter-5.1.0.tgz", + "integrity": "sha1-oF4Rr/sHz33PQafeHLe2OsN4PnM=", "dev": true, "requires": { - "gulp-util": "3.0.8", "multimatch": "2.1.0", + "plugin-error": "0.1.2", "streamfilter": "1.0.7" } }, @@ -1578,18 +2879,6 @@ "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", "dev": true }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, "through2": { "version": "0.6.5", "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", @@ -1613,69 +2902,59 @@ } }, "gulp-mocha": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/gulp-mocha/-/gulp-mocha-4.3.1.tgz", - "integrity": "sha1-d5ULQ7z/gWWVdnwHNOD9p9Fz3Nk=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/gulp-mocha/-/gulp-mocha-5.0.0.tgz", + "integrity": "sha512-NIjXZLqqcw9DXIEBcfm0sP1AUDlUJJeaK9EGCH2s6lSwo5NK/cEat0Vm7XelOkxZnWl0O5Za+aM6E4jyxWxTlw==", "dev": true, "requires": { "dargs": "5.1.0", - "execa": "0.6.3", - "gulp-util": "3.0.8", - "mocha": "3.5.3", + "execa": "0.8.0", + "mocha": "4.1.0", "npm-run-path": "2.0.2", + "plugin-error": "0.1.2", "through2": "2.0.3" }, "dependencies": { - "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", - "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", + "execa": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz", + "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=", "dev": true, "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "cross-spawn": "5.1.0", + "get-stream": "3.0.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" } }, "mocha": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.3.tgz", - "integrity": "sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", + "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", "dev": true, "requires": { "browser-stdout": "1.3.0", - "commander": "2.9.0", - "debug": "2.6.8", - "diff": "3.2.0", + "commander": "2.11.0", + "debug": "3.1.0", + "diff": "3.3.1", "escape-string-regexp": "1.0.5", - "glob": "7.1.1", - "growl": "1.9.2", + "glob": "7.1.2", + "growl": "1.10.3", "he": "1.1.1", - "json3": "3.3.2", - "lodash.create": "3.1.1", "mkdirp": "0.5.1", - "supports-color": "3.1.2" + "supports-color": "4.4.0" } }, "supports-color": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", - "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", "dev": true, "requires": { - "has-flag": "1.0.0" + "has-flag": "2.0.0" } } } @@ -1693,12 +2972,36 @@ "vinyl": "2.0.2" }, "dependencies": { + "caseless": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", + "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", + "dev": true + }, "clone-stats": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", "dev": true }, + "har-validator": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", + "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "commander": "2.11.0", + "is-my-json-valid": "2.17.2", + "pinkie-promise": "2.0.1" + } + }, + "qs": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz", + "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=", + "dev": true + }, "replace-ext": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", @@ -1712,9 +3015,9 @@ "dev": true, "requires": { "aws-sign2": "0.6.0", - "aws4": "1.6.0", + "aws4": "1.7.0", "caseless": "0.11.0", - "combined-stream": "1.0.5", + "combined-stream": "1.0.6", "extend": "3.0.1", "forever-agent": "0.6.1", "form-data": "2.1.4", @@ -1724,25 +3027,31 @@ "is-typedarray": "1.0.0", "isstream": "0.1.2", "json-stringify-safe": "5.0.1", - "mime-types": "2.1.17", + "mime-types": "2.1.18", "oauth-sign": "0.8.2", "qs": "6.3.2", "stringstream": "0.0.5", - "tough-cookie": "2.3.3", + "tough-cookie": "2.3.4", "tunnel-agent": "0.4.3", - "uuid": "3.1.0" + "uuid": "3.2.1" } }, + "tunnel-agent": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", + "dev": true + }, "vinyl": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.0.2.tgz", "integrity": "sha1-CjcT2NTpIhxY8QyhbAEWyeJe2nw=", "dev": true, "requires": { - "clone": "1.0.3", + "clone": "1.0.4", "clone-buffer": "1.0.0", "clone-stats": "1.0.0", - "cloneable-readable": "1.0.0", + "cloneable-readable": "1.1.2", "is-stream": "1.1.0", "remove-trailing-separator": "1.1.0", "replace-ext": "1.0.0" @@ -1750,6 +3059,15 @@ } } }, + "gulp-sequence": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulp-sequence/-/gulp-sequence-1.0.0.tgz", + "integrity": "sha512-c+p+EcyBl1UCpbfFA/vUD6MuC7uxoY6Y4g2lq9lLtzOHh9o1wijAQ4o0TIRQ14C7cG6zR6Zi+bpA0cW78CFt6g==", + "dev": true, + "requires": { + "thunks": "4.9.2" + } + }, "gulp-sourcemaps": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz", @@ -1778,7 +3096,7 @@ "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", "dev": true, "requires": { - "clone": "1.0.3", + "clone": "1.0.4", "clone-stats": "0.0.1", "replace-ext": "0.0.1" } @@ -1797,6 +3115,50 @@ "vinyl-fs": "2.4.4" }, "dependencies": { + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "1.1.0" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "0.1.1" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, "glob": { "version": "5.0.15", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", @@ -1810,16 +3172,6 @@ "path-is-absolute": "1.0.1" } }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" - } - }, "glob-stream": { "version": "5.3.5", "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz", @@ -1873,18 +3225,18 @@ } }, "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", "dev": true }, "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { - "is-extglob": "2.1.1" + "is-extglob": "1.0.0" } }, "isarray": { @@ -1893,6 +3245,36 @@ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.2", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.4" + } + }, "ordered-read-streams": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz", @@ -1900,28 +3282,28 @@ "dev": true, "requires": { "is-stream": "1.1.0", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { "core-util-is": "1.0.2", "inherits": "2.0.3", "isarray": "1.0.0", - "process-nextick-args": "1.0.7", + "process-nextick-args": "2.0.0", "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", + "string_decoder": "1.1.1", "util-deprecate": "1.0.2" } }, "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { "safe-buffer": "5.1.1" @@ -1952,7 +3334,7 @@ "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", "dev": true, "requires": { - "clone": "1.0.3", + "clone": "1.0.4", "clone-stats": "0.0.1", "replace-ext": "0.0.1" } @@ -1963,7 +3345,7 @@ "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", "dev": true, "requires": { - "duplexify": "3.5.1", + "duplexify": "3.5.4", "glob-stream": "5.3.5", "graceful-fs": "4.1.11", "gulp-sourcemaps": "1.6.0", @@ -1973,7 +3355,7 @@ "merge-stream": "1.0.1", "mkdirp": "0.5.1", "object-assign": "4.1.1", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "strip-bom": "2.0.0", "strip-bom-stream": "1.0.0", "through2": "2.0.3", @@ -1985,14 +3367,66 @@ } }, "gulp-tslint": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/gulp-tslint/-/gulp-tslint-8.1.2.tgz", - "integrity": "sha512-0RNGqbp2TKPdbG+sWU3mNMXEMuF/noY1KS4+jd5lOStkvuFINkFL29dHX3IT1u+vVFD4Glwf+lkcdR2QMVNMzA==", + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/gulp-tslint/-/gulp-tslint-8.1.3.tgz", + "integrity": "sha512-KEP350N5B9Jg6o6jnyCyKVBPemJePYpMsGfIQq0G0ErvY7tw4Lrfb/y3L4WRf7ek0OsaE8nnj86w+lcLXW8ovw==", "dev": true, "requires": { - "gulp-util": "3.0.8", + "@types/fancy-log": "1.3.0", + "chalk": "2.3.1", + "fancy-log": "1.3.2", "map-stream": "0.0.7", + "plugin-error": "1.0.1", "through": "2.3.8" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", + "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", + "dev": true, + "requires": { + "ansi-styles": "3.2.1", + "escape-string-regexp": "1.0.5", + "supports-color": "5.3.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "plugin-error": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", + "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", + "dev": true, + "requires": { + "ansi-colors": "1.1.0", + "arr-diff": "4.0.0", + "arr-union": "3.1.0", + "extend-shallow": "3.0.2" + } + }, + "supports-color": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", + "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", + "dev": true, + "requires": { + "has-flag": "3.0.0" + } + } } }, "gulp-untar": { @@ -2019,7 +3453,7 @@ "beeper": "1.1.1", "chalk": "1.1.3", "dateformat": "2.2.0", - "fancy-log": "1.3.0", + "fancy-log": "1.3.2", "gulplog": "1.0.0", "has-gulplog": "0.1.0", "lodash._reescape": "3.0.0", @@ -2034,12 +3468,6 @@ "vinyl": "0.5.3" }, "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, "object-assign": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", @@ -2063,10 +3491,36 @@ "yazl": "2.4.3" }, "dependencies": { + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "1.1.0" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + } + }, "clone": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", - "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", "dev": true }, "clone-stats": { @@ -2075,6 +3529,24 @@ "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", "dev": true }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "0.1.1" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, "glob": { "version": "5.0.15", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", @@ -2088,16 +3560,6 @@ "path-is-absolute": "1.0.1" } }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" - } - }, "glob-stream": { "version": "5.3.5", "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz", @@ -2151,18 +3613,18 @@ } }, "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", "dev": true }, "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { - "is-extglob": "2.1.1" + "is-extglob": "1.0.0" } }, "isarray": { @@ -2171,6 +3633,36 @@ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.2", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.4" + } + }, "ordered-read-streams": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz", @@ -2178,7 +3670,7 @@ "dev": true, "requires": { "is-stream": "1.1.0", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "queue": { @@ -2191,17 +3683,17 @@ } }, "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { "core-util-is": "1.0.2", "inherits": "2.0.3", "isarray": "1.0.0", - "process-nextick-args": "1.0.7", + "process-nextick-args": "2.0.0", "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", + "string_decoder": "1.1.1", "util-deprecate": "1.0.2" } }, @@ -2212,9 +3704,9 @@ "dev": true }, "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { "safe-buffer": "5.1.1" @@ -2245,10 +3737,10 @@ "integrity": "sha1-Ah+cLPlR1rk5lDyJ617lrdT9kkw=", "dev": true, "requires": { - "clone": "2.1.1", + "clone": "2.1.2", "clone-buffer": "1.0.0", "clone-stats": "1.0.0", - "cloneable-readable": "1.0.0", + "cloneable-readable": "1.1.2", "remove-trailing-separator": "1.1.0", "replace-ext": "1.0.0" } @@ -2259,7 +3751,7 @@ "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=", "dev": true, "requires": { - "duplexify": "3.5.1", + "duplexify": "3.5.4", "glob-stream": "5.3.5", "graceful-fs": "4.1.11", "gulp-sourcemaps": "1.6.0", @@ -2269,7 +3761,7 @@ "merge-stream": "1.0.1", "mkdirp": "0.5.1", "object-assign": "4.1.1", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "strip-bom": "2.0.0", "strip-bom-stream": "1.0.0", "through2": "2.0.3", @@ -2279,9 +3771,9 @@ }, "dependencies": { "clone": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz", - "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", "dev": true }, "clone-stats": { @@ -2302,7 +3794,7 @@ "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", "dev": true, "requires": { - "clone": "1.0.3", + "clone": "1.0.4", "clone-stats": "0.0.1", "replace-ext": "0.0.1" } @@ -2317,25 +3809,46 @@ "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", "dev": true, "requires": { - "glogg": "1.0.0" + "glogg": "1.0.1" + } + }, + "handlebars": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz", + "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", + "dev": true, + "requires": { + "async": "1.5.2", + "optimist": "0.6.1", + "source-map": "0.4.4", + "uglify-js": "2.8.29" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "requires": { + "amdefine": "1.0.1" + } + } } }, "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", + "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", "dev": true }, "har-validator": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", - "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", + "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", "dev": true, "requires": { - "chalk": "1.1.3", - "commander": "2.9.0", - "is-my-json-valid": "2.16.1", - "pinkie-promise": "2.0.1" + "ajv": "4.11.8", + "har-schema": "1.0.5" } }, "has": { @@ -2354,12 +3867,20 @@ "dev": true, "requires": { "ansi-regex": "2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + } } }, "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", "dev": true }, "has-gulplog": { @@ -2371,6 +3892,38 @@ "sparkles": "1.0.0" } }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "2.0.6", + "has-values": "1.0.0", + "isobject": "3.0.1" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "3.0.0", + "kind-of": "4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, "hawk": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", @@ -2405,9 +3958,9 @@ } }, "hosted-git-info": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", - "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz", + "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==", "dev": true }, "htmlparser2": { @@ -2421,7 +3974,7 @@ "domutils": "1.5.1", "entities": "1.1.1", "inherits": "2.0.3", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" }, "dependencies": { "isarray": { @@ -2431,24 +3984,24 @@ "dev": true }, "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { "core-util-is": "1.0.2", "inherits": "2.0.3", "isarray": "1.0.0", - "process-nextick-args": "1.0.7", + "process-nextick-args": "2.0.0", "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", + "string_decoder": "1.1.1", "util-deprecate": "1.0.2" } }, "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { "safe-buffer": "5.1.1" @@ -2456,13 +4009,25 @@ } } }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": "1.5.0" + } + }, "http-proxy-agent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.0.0.tgz", - "integrity": "sha1-RkgqLwUjpNYIJVFwn0acs+SoX/Q=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", + "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", "requires": { - "agent-base": "4.1.2", - "debug": "2.6.9" + "agent-base": "4.2.0", + "debug": "3.1.0" } }, "http-signature": { @@ -2473,28 +4038,24 @@ "requires": { "assert-plus": "0.2.0", "jsprim": "1.4.1", - "sshpk": "1.13.1" + "sshpk": "1.14.1" } }, "https-proxy-agent": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.1.1.tgz", - "integrity": "sha512-LK6tQUR/VOkTI6ygAfWUKKP95I+e6M1h7N3PncGu1CATHCnex+CAv9ttR0lbHu1Uk2PXm/WoAHFo6JCGwMjVMw==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", + "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", "requires": { - "agent-base": "4.1.2", + "agent-base": "4.2.0", "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - } } }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", + "dev": true + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -2523,6 +4084,12 @@ "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", "dev": true }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, "is": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/is/-/is-3.2.1.tgz", @@ -2530,20 +4097,32 @@ "dev": true }, "is-absolute": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.2.6.tgz", - "integrity": "sha1-IN5p89uULvLYe5wto28XIjWxtes=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "requires": { + "is-relative": "1.0.0", + "is-windows": "1.0.2" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { - "is-relative": "0.2.1", - "is-windows": "0.2.0" + "kind-of": "3.2.2" }, "dependencies": { - "is-windows": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", - "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=", - "dev": true + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } } } }, @@ -2574,12 +4153,51 @@ "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", "dev": true }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, "is-date-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", "dev": true }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, "is-dotfile": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", @@ -2602,39 +4220,63 @@ "dev": true }, "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { - "is-extglob": "1.0.0" + "is-extglob": "2.1.1" } }, + "is-my-ip-valid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", + "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", + "dev": true + }, "is-my-json-valid": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz", - "integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==", + "version": "2.17.2", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.17.2.tgz", + "integrity": "sha512-IBhBslgngMQN8DDSppmgDv7RNrlFotuuDsKcrCP3+HbFaVivIBU7u9oiiErw8sH4ynx3+gOGQ3q2otkgiSi6kg==", "dev": true, "requires": { "generate-function": "2.0.0", "generate-object-property": "1.2.0", + "is-my-ip-valid": "1.0.0", "jsonpointer": "4.0.1", "xtend": "4.0.1" } }, "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } } }, "is-obj": { @@ -2643,6 +4285,23 @@ "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", "dev": true }, + "is-odd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz", + "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==", + "dev": true, + "requires": { + "is-number": "4.0.0" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true + } + } + }, "is-path-cwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", @@ -2650,9 +4309,9 @@ "dev": true }, "is-path-in-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", - "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", "dev": true, "requires": { "is-path-inside": "1.0.1" @@ -2674,14 +4333,6 @@ "dev": true, "requires": { "isobject": "3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } } }, "is-posix-bracket": { @@ -2712,12 +4363,12 @@ } }, "is-relative": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz", - "integrity": "sha1-0n9MfVFtF1+2ENuEu+7yPDvJeqU=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", "dev": true, "requires": { - "is-unc-path": "0.1.2" + "is-unc-path": "1.0.0" } }, "is-stream": { @@ -2739,9 +4390,9 @@ "dev": true }, "is-unc-path": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-0.1.2.tgz", - "integrity": "sha1-arBTpyVzwQJQ/0FqOBTDUXivObk=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", "dev": true, "requires": { "unc-path-regex": "0.1.2" @@ -2760,9 +4411,9 @@ "dev": true }, "is-windows": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.1.tgz", - "integrity": "sha1-MQ23D3QtJZoWo2kgK1GvhCMzENk=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, "isarray": { @@ -2778,21 +4429,10 @@ "dev": true }, "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - } - } + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true }, "isstream": { "version": "0.1.2", @@ -2800,19 +4440,246 @@ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "dev": true }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "istanbul": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz", + "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", "dev": true, - "optional": true - }, + "requires": { + "abbrev": "1.0.9", + "async": "1.5.2", + "escodegen": "1.8.1", + "esprima": "2.7.3", + "glob": "5.0.15", + "handlebars": "4.0.11", + "js-yaml": "3.11.0", + "mkdirp": "0.5.1", + "nopt": "3.0.6", + "once": "1.4.0", + "resolve": "1.1.7", + "supports-color": "3.2.3", + "which": "1.3.0", + "wordwrap": "1.0.0" + }, + "dependencies": { + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "istanbul-combine": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/istanbul-combine/-/istanbul-combine-0.3.0.tgz", + "integrity": "sha1-VrLV5joiBZi23ErIrVcucV6ZV3M=", + "dev": true, + "requires": { + "glob": "5.0.15", + "istanbul": "0.3.22", + "minimist": "1.2.0", + "q": "1.5.1" + }, + "dependencies": { + "escodegen": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.7.1.tgz", + "integrity": "sha1-MOz89mypjcZ80v0WKr626vqM5vw=", + "dev": true, + "requires": { + "esprima": "1.2.5", + "estraverse": "1.9.3", + "esutils": "2.0.2", + "optionator": "0.5.0", + "source-map": "0.2.0" + }, + "dependencies": { + "esprima": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.5.tgz", + "integrity": "sha1-CZNQL+r2aBODJXVvMPmlH+7sEek=", + "dev": true + } + } + }, + "esprima": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.5.0.tgz", + "integrity": "sha1-84ekb9NEwbGjm6+MIL+0O20AWMw=", + "dev": true + }, + "fast-levenshtein": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.0.7.tgz", + "integrity": "sha1-AXjc3uAjuSkFGTrwlZ6KdjnP3Lk=", + "dev": true + }, + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "istanbul": { + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.3.22.tgz", + "integrity": "sha1-PhZNhQIf4ZyYXR8OfvDD4i0BLrY=", + "dev": true, + "requires": { + "abbrev": "1.0.9", + "async": "1.5.2", + "escodegen": "1.7.1", + "esprima": "2.5.0", + "fileset": "0.2.1", + "handlebars": "4.0.11", + "js-yaml": "3.11.0", + "mkdirp": "0.5.1", + "nopt": "3.0.6", + "once": "1.4.0", + "resolve": "1.1.7", + "supports-color": "3.2.3", + "which": "1.3.0", + "wordwrap": "1.0.0" + } + }, + "levn": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.2.5.tgz", + "integrity": "sha1-uo0znQykphDjo/FFucr0iAcVUFQ=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2", + "type-check": "0.3.2" + } + }, + "optionator": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.5.0.tgz", + "integrity": "sha1-t1qJlaLUF98ltuTjhi9QqohlE2g=", + "dev": true, + "requires": { + "deep-is": "0.1.3", + "fast-levenshtein": "1.0.7", + "levn": "0.2.5", + "prelude-ls": "1.1.2", + "type-check": "0.3.2", + "wordwrap": "0.0.3" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + } + } + }, + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + }, + "source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", + "dev": true, + "optional": true, + "requires": { + "amdefine": "1.0.1" + } + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz", + "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==", + "dev": true, + "requires": { + "argparse": "1.0.10", + "esprima": "4.0.0" + }, + "dependencies": { + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "dev": true + } + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true, + "optional": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -2840,16 +4707,10 @@ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", "dev": true }, - "json3": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", - "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", - "dev": true - }, "jsonc-parser": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-1.0.0.tgz", - "integrity": "sha1-3cyGSucI5gp6bdNtrqABcvqNknI=" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-1.0.3.tgz", + "integrity": "sha512-hk/69oAeaIzchq/v3lS50PXuzn5O2ynldopMC+SWBql7J2WtdptfB9dy8Y7+Og5rPkTCpn83zTiO8FMcqlXJ/g==" }, "jsonfile": { "version": "4.0.0", @@ -2892,13 +4753,17 @@ } }, "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", "dev": true, - "requires": { - "is-buffer": "1.1.6" - } + "optional": true }, "lazystream": { "version": "1.0.0", @@ -2906,7 +4771,7 @@ "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", "dev": true, "requires": { - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" }, "dependencies": { "isarray": { @@ -2916,24 +4781,24 @@ "dev": true }, "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { "core-util-is": "1.0.2", "inherits": "2.0.3", "isarray": "1.0.0", - "process-nextick-args": "1.0.7", + "process-nextick-args": "2.0.0", "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", + "string_decoder": "1.1.1", "util-deprecate": "1.0.2" } }, "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { "safe-buffer": "5.1.1" @@ -2941,21 +4806,39 @@ } } }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "1.0.0" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2", + "type-check": "0.3.2" + } + }, "liftoff": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.3.0.tgz", - "integrity": "sha1-qY8v9nGD2Lp8+soQVIvX/wVQs4U=", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz", + "integrity": "sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=", "dev": true, "requires": { "extend": "3.0.1", - "findup-sync": "0.4.3", + "findup-sync": "2.0.0", "fined": "1.1.0", - "flagged-respawn": "0.3.2", - "lodash.isplainobject": "4.0.6", - "lodash.isstring": "4.0.1", - "lodash.mapvalues": "4.6.0", + "flagged-respawn": "1.0.0", + "is-plain-object": "2.0.4", + "object.map": "1.0.1", "rechoir": "0.6.2", - "resolve": "1.5.0" + "resolve": "1.7.0" } }, "linkify-it": { @@ -2964,19 +4847,20 @@ "integrity": "sha1-2UpGSPmxwXnWT6lykSaL22zpQ08=", "dev": true, "requires": { - "uc.micro": "1.0.3" + "uc.micro": "1.0.5" } }, "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { "graceful-fs": "4.1.11", "parse-json": "2.2.0", "pify": "2.3.0", - "strip-bom": "3.0.0" + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" }, "dependencies": { "pify": { @@ -2986,41 +4870,38 @@ "dev": true }, "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "0.2.1" + } } } }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "2.0.0", + "path-exists": "3.0.0" + } + }, "lodash": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", "integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=", "dev": true }, - "lodash._baseassign": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", - "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", - "dev": true, - "requires": { - "lodash._basecopy": "3.0.1", - "lodash.keys": "3.1.2" - } - }, "lodash._basecopy": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", "dev": true }, - "lodash._basecreate": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", - "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=", - "dev": true - }, "lodash._basetostring": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", @@ -3069,22 +4950,6 @@ "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", "dev": true }, - "lodash.create": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", - "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", - "dev": true, - "requires": { - "lodash._baseassign": "3.2.0", - "lodash._basecreate": "3.0.3", - "lodash._isiterateecall": "3.0.9" - } - }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" - }, "lodash.escape": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", @@ -3112,18 +4977,6 @@ "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", "dev": true }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=", - "dev": true - }, "lodash.keys": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", @@ -3135,12 +4988,6 @@ "lodash.isarray": "3.0.4" } }, - "lodash.mapvalues": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz", - "integrity": "sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw=", - "dev": true - }, "lodash.restparam": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", @@ -3174,16 +5021,43 @@ "lodash.escape": "3.2.0" } }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "dev": true + }, "lru-cache": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", - "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.2.tgz", + "integrity": "sha512-wgeVXhrDwAWnIF/yZARsFnMBtdFXOg1b8RIrhilp+0iDYN4mdQcNZElDZ0e4B64BhaxeQ5zN7PMyvu7we1kPeQ==", "dev": true, "requires": { "pseudomap": "1.0.2", "yallist": "2.1.2" } }, + "ltcdr": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ltcdr/-/ltcdr-2.2.1.tgz", + "integrity": "sha1-Wrh60dTB2rjowIu/A37gwZAih88=", + "dev": true + }, + "make-error": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.4.tgz", + "integrity": "sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g==", + "dev": true + }, + "make-iterator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", @@ -3196,17 +5070,36 @@ "integrity": "sha1-ih8HiW2CsQkmvTdEokIACfiJdKg=", "dev": true }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "1.0.1" + } + }, "markdown-it": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.0.tgz", - "integrity": "sha512-tNuOCCfunY5v5uhcO2AUMArvKAyKMygX8tfup/JrgnsDqcCATQsAExBq7o5Ml9iMmO82bk6jYNLj6khcrl0JGA==", + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.1.tgz", + "integrity": "sha512-CzzqSSNkFRUf9vlWvhK1awpJreMRqdCrBvZ8DIoDWTOkESMIF741UPAhuAmbyWmdiFPA6WARNhnu2M6Nrhwa+A==", "dev": true, "requires": { - "argparse": "1.0.9", + "argparse": "1.0.10", "entities": "1.1.1", "linkify-it": "2.0.3", "mdurl": "1.0.1", - "uc.micro": "1.0.3" + "uc.micro": "1.0.5" + } + }, + "match-stream": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/match-stream/-/match-stream-0.0.2.tgz", + "integrity": "sha1-mesFAJOzTf+t5CG5rAtBCpz6F88=", + "dev": true, + "requires": { + "buffers": "0.1.1", + "readable-stream": "1.0.34" } }, "mdurl": { @@ -3215,36 +5108,34 @@ "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", "dev": true }, - "memory-streams": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/memory-streams/-/memory-streams-0.1.2.tgz", - "integrity": "sha1-Jz/3d6tg/sWZsRY1UlUoLMosUMI=", + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", "dev": true, "requires": { - "readable-stream": "1.0.34" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - } + "mimic-fn": "1.2.0" } }, + "memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", + "dev": true + }, "merge-stream": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", "dev": true, "requires": { - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" }, "dependencies": { "isarray": { @@ -3254,24 +5145,24 @@ "dev": true }, "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { "core-util-is": "1.0.2", "inherits": "2.0.3", "isarray": "1.0.0", - "process-nextick-args": "1.0.7", + "process-nextick-args": "2.0.0", "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", + "string_decoder": "1.1.1", "util-deprecate": "1.0.2" } }, "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { "safe-buffer": "5.1.1" @@ -3280,24 +5171,24 @@ } }, "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.1", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.2.2", - "normalize-path": "2.1.1", - "object.omit": "2.0.1", - "parse-glob": "3.0.4", - "regex-cache": "0.4.4" + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "4.0.0", + "array-unique": "0.3.2", + "braces": "2.3.2", + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "extglob": "2.0.4", + "fragment-cache": "0.2.1", + "kind-of": "6.0.2", + "nanomatch": "1.2.9", + "object.pick": "1.3.0", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" } }, "mime": { @@ -3307,52 +5198,87 @@ "dev": true }, "mime-db": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", - "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", "dev": true }, "mime-types": { - "version": "2.1.17", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", - "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", "dev": true, "requires": { - "mime-db": "1.30.0" + "mime-db": "1.33.0" } }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "brace-expansion": "1.1.8" + "brace-expansion": "1.1.11" } }, "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "dev": true, + "requires": { + "for-in": "1.0.2", + "is-extendable": "1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "requires": { "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + } } }, "mocha": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.0.1.tgz", - "integrity": "sha512-evDmhkoA+cBNiQQQdSKZa2b9+W2mpLoj50367lhy+Klnx9OV8XlCIhigUnn1gaTFLQCa0kdNhEGDr0hCXOQFDw==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.0.5.tgz", + "integrity": "sha512-3MM3UjZ5p8EJrYpG7s+29HAI9G7sTzKEe4+w37Dg0QP7qL4XGsV+Q2xet2cE37AqdgN1OtYQB6Vl98YiPV3PgA==", "dev": true, "requires": { - "browser-stdout": "1.3.0", + "browser-stdout": "1.3.1", "commander": "2.11.0", "debug": "3.1.0", - "diff": "3.3.1", + "diff": "3.5.0", "escape-string-regexp": "1.0.5", "glob": "7.1.2", "growl": "1.10.3", @@ -3361,50 +5287,151 @@ "supports-color": "4.4.0" }, "dependencies": { - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", "dev": true, "requires": { - "ms": "2.0.0" + "has-flag": "2.0.0" } - }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", + } + } + }, + "mocha-typescript": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/mocha-typescript/-/mocha-typescript-1.1.12.tgz", + "integrity": "sha512-vnq0iOYdeP0w7xaWTeQxniy/CJ/uQGI5rHerTB/PVeUm2GNKcy2tJFGikmAw73boJIYsdQ/H5TR09E4QCUib6A==", + "dev": true, + "requires": { + "chalk": "1.1.3", + "cross-spawn": "5.1.0", + "yargs": "6.6.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", "dev": true }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "requires": { + "lcid": "1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", "dev": true }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "yargs": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", + "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=", "dev": true, "requires": { - "has-flag": "2.0.0" + "camelcase": "3.0.0", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "os-locale": "1.4.0", + "read-pkg-up": "1.0.1", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "1.0.2", + "which-module": "1.0.0", + "y18n": "3.2.1", + "yargs-parser": "4.2.1" + } + }, + "yargs-parser": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", + "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=", + "dev": true, + "requires": { + "camelcase": "3.0.0" } } } }, + "mock-http-server": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/mock-http-server/-/mock-http-server-0.2.0.tgz", + "integrity": "sha1-7e/sDoC+i8oobx4MAN6Nv+vw7JA=", + "dev": true, + "requires": { + "body-parser": "1.18.2", + "connect": "3.6.6", + "multiparty": "4.1.3", + "underscore": "1.8.3" + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -3422,6 +5449,15 @@ "minimatch": "3.0.4" } }, + "multiparty": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/multiparty/-/multiparty-4.1.3.tgz", + "integrity": "sha1-PEPH/LGJbhdGBDap3Qtu8WaOT5Q=", + "dev": true, + "requires": { + "fd-slicer": "1.0.1" + } + }, "multipipe": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", @@ -3437,12 +5473,40 @@ "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", "dev": true }, + "nanomatch": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz", + "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==", + "dev": true, + "requires": { + "arr-diff": "4.0.0", + "array-unique": "0.3.2", + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "fragment-cache": "0.2.1", + "is-odd": "2.0.0", + "is-windows": "1.0.2", + "kind-of": "6.0.2", + "object.pick": "1.3.0", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" + } + }, "natives": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.1.tgz", - "integrity": "sha512-8eRaxn8u/4wN8tGkhlc2cgwwvOLMLUMUn4IYTexMgWd+LyUDfeXVkk2ygQR0hvIHbJQXgHujia3ieUUDwNGkEA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.3.tgz", + "integrity": "sha512-BZGSYV4YOLxzoTK73l0/s/0sH9l8SHs2ocReMH1f8JYSh5FUWu4ZrKCpJdRkWXV6HFR/pZDz7bwWOVAY07q77g==", "dev": true }, + "node-filter-async": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/node-filter-async/-/node-filter-async-0.0.4.tgz", + "integrity": "sha512-W3p4yGNzH1822Z+CHitXY0uCy3vd9Vic7lEZv8NXHqT9erfod+UuZ/wN57oJwCqiSMoBqke62suyORwVb/mYIA==", + "requires": { + "bluebird": "3.5.1" + } + }, "node.extend": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/node.extend/-/node.extend-1.1.6.tgz", @@ -3452,16 +5516,35 @@ "is": "3.2.1" } }, + "noms": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz", + "integrity": "sha1-2o69nzr51nYJGbJ9nNyAkqczKFk=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "1.0.34" + } + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1.0.9" + } + }, "normalize-package-data": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", "dev": true, "requires": { - "hosted-git-info": "2.5.0", + "hosted-git-info": "2.6.0", "is-builtin-module": "1.0.0", - "semver": "5.4.1", - "validate-npm-package-license": "3.0.1" + "semver": "5.5.0", + "validate-npm-package-license": "3.0.3" } }, "normalize-path": { @@ -3474,55 +5557,103 @@ } }, "npm-run-all": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.1.tgz", - "integrity": "sha512-qrmqqaJa+REbzUTIL/mHfTdgwz+gL1xUezY/ueyLa7GISZ4T3h0CH8D2r6AaZdCYN2unu7PzspP0ofpXla1ftg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.2.tgz", + "integrity": "sha512-Z2aRlajMK4SQ8u19ZA75NZZu7wupfCNQWdYosIi8S6FgBdGf/8Y6Hgyjdc8zU2cYmIRVCx1nM80tJPkdEd+UYg==", "dev": true, "requires": { - "ansi-styles": "3.2.0", - "chalk": "2.3.0", + "ansi-styles": "3.2.1", + "chalk": "2.3.2", "cross-spawn": "5.1.0", - "memory-streams": "0.1.2", + "memorystream": "0.3.1", "minimatch": "3.0.4", "ps-tree": "1.1.0", - "read-pkg": "2.0.0", + "read-pkg": "3.0.0", "shell-quote": "1.6.1", "string.prototype.padend": "3.0.0" }, "dependencies": { "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { "color-convert": "1.9.1" } }, "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", + "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", + "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "supports-color": "5.3.0" } }, "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "4.0.0", + "pify": "3.0.0", + "strip-bom": "3.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "1.3.1", + "json-parse-better-errors": "1.0.2" + } + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "3.0.0" + } + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "4.0.0", + "normalize-package-data": "2.4.0", + "path-type": "3.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", + "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", "dev": true, "requires": { - "has-flag": "2.0.0" + "has-flag": "3.0.0" } } } @@ -3545,103 +5676,2963 @@ "boolbase": "1.0.0" } }, - "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-keys": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", - "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true }, - "object.defaults": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", - "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "nyc": { + "version": "11.6.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-11.6.0.tgz", + "integrity": "sha512-ZaXCh0wmbk2aSBH2B5hZGGvK2s9aM8DIm2rVY+BG3Fx8tUS+bpJSswUVZqOD1YfCmnYRFSqgYJSr7UeeUcW0jg==", "dev": true, "requires": { - "array-each": "1.0.1", - "array-slice": "1.1.0", - "for-own": "1.0.0", - "isobject": "3.0.1" + "archy": "1.0.0", + "arrify": "1.0.1", + "caching-transform": "1.0.1", + "convert-source-map": "1.5.1", + "debug-log": "1.0.1", + "default-require-extensions": "1.0.0", + "find-cache-dir": "0.1.1", + "find-up": "2.1.0", + "foreground-child": "1.5.6", + "glob": "7.1.2", + "istanbul-lib-coverage": "1.2.0", + "istanbul-lib-hook": "1.1.0", + "istanbul-lib-instrument": "1.10.1", + "istanbul-lib-report": "1.1.3", + "istanbul-lib-source-maps": "1.2.3", + "istanbul-reports": "1.3.0", + "md5-hex": "1.3.0", + "merge-source-map": "1.1.0", + "micromatch": "2.3.11", + "mkdirp": "0.5.1", + "resolve-from": "2.0.0", + "rimraf": "2.6.2", + "signal-exit": "3.0.2", + "spawn-wrap": "1.4.2", + "test-exclude": "4.2.1", + "yargs": "11.1.0", + "yargs-parser": "8.1.0" }, "dependencies": { - "for-own": { + "align-text": { + "version": "0.1.4", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2", + "longest": "1.0.1", + "repeat-string": "1.6.1" + } + }, + "amdefine": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "bundled": true, + "dev": true + }, + "append-transform": { + "version": "0.4.0", + "bundled": true, + "dev": true, + "requires": { + "default-require-extensions": "1.0.0" + } + }, + "archy": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "bundled": true, + "dev": true + }, + "arr-diff": { + "version": "2.0.0", + "bundled": true, "dev": true, "requires": { - "for-in": "1.0.2" + "arr-flatten": "1.1.0" } }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "arr-flatten": { + "version": "1.1.0", + "bundled": true, "dev": true - } - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "0.1.5", - "is-extendable": "0.1.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + }, + "arr-union": { + "version": "3.1.0", + "bundled": true, "dev": true - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1.0.2" - } - }, - "open": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/open/-/open-0.0.5.tgz", - "integrity": "sha1-QsPhjslUZra/DcQvOilFw/DK2Pw=" - }, - "orchestrator": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/orchestrator/-/orchestrator-0.3.8.tgz", - "integrity": "sha1-FOfp4nZPcxX7rBhOUGx6pt+UrX4=", - "dev": true, - "requires": { - "end-of-stream": "0.1.5", + }, + "array-unique": { + "version": "0.2.1", + "bundled": true, + "dev": true + }, + "arrify": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "async": { + "version": "1.5.2", + "bundled": true, + "dev": true + }, + "atob": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "bundled": true, + "dev": true, + "requires": { + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" + } + }, + "babel-generator": { + "version": "6.26.1", + "bundled": true, + "dev": true, + "requires": { + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "detect-indent": "4.0.0", + "jsesc": "1.3.0", + "lodash": "4.17.5", + "source-map": "0.5.7", + "trim-right": "1.0.1" + } + }, + "babel-messages": { + "version": "6.23.0", + "bundled": true, + "dev": true, + "requires": { + "babel-runtime": "6.26.0" + } + }, + "babel-runtime": { + "version": "6.26.0", + "bundled": true, + "dev": true, + "requires": { + "core-js": "2.5.3", + "regenerator-runtime": "0.11.1" + } + }, + "babel-template": { + "version": "6.26.0", + "bundled": true, + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "lodash": "4.17.5" + } + }, + "babel-traverse": { + "version": "6.26.0", + "bundled": true, + "dev": true, + "requires": { + "babel-code-frame": "6.26.0", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "debug": "2.6.9", + "globals": "9.18.0", + "invariant": "2.2.3", + "lodash": "4.17.5" + } + }, + "babel-types": { + "version": "6.26.0", + "bundled": true, + "dev": true, + "requires": { + "babel-runtime": "6.26.0", + "esutils": "2.0.2", + "lodash": "4.17.5", + "to-fast-properties": "1.0.3" + } + }, + "babylon": { + "version": "6.18.0", + "bundled": true, + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "base": { + "version": "0.11.2", + "bundled": true, + "dev": true, + "requires": { + "cache-base": "1.0.1", + "class-utils": "0.3.6", + "component-emitter": "1.2.1", + "define-property": "1.0.0", + "isobject": "3.0.1", + "mixin-deep": "1.3.1", + "pascalcase": "0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "bundled": true, + "dev": true + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "1.8.5", + "bundled": true, + "dev": true, + "requires": { + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" + } + }, + "builtin-modules": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "cache-base": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "collection-visit": "1.0.0", + "component-emitter": "1.2.1", + "get-value": "2.0.6", + "has-value": "1.0.0", + "isobject": "3.0.1", + "set-value": "2.0.0", + "to-object-path": "0.3.0", + "union-value": "1.0.0", + "unset-value": "1.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "bundled": true, + "dev": true + } + } + }, + "caching-transform": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "md5-hex": "1.3.0", + "mkdirp": "0.5.1", + "write-file-atomic": "1.3.4" + } + }, + "camelcase": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true + }, + "center-align": { + "version": "0.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "align-text": "0.1.4", + "lazy-cache": "1.0.4" + } + }, + "chalk": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "class-utils": { + "version": "0.3.6", + "bundled": true, + "dev": true, + "requires": { + "arr-union": "3.1.0", + "define-property": "0.2.5", + "isobject": "3.0.1", + "static-extend": "0.1.2" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "bundled": true, + "dev": true, + "requires": { + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" + } + }, + "isobject": { + "version": "3.0.1", + "bundled": true, + "dev": true + }, + "kind-of": { + "version": "5.1.0", + "bundled": true, + "dev": true + } + } + }, + "cliui": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "center-align": "0.1.3", + "right-align": "0.1.3", + "wordwrap": "0.0.2" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.2", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "collection-visit": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "map-visit": "1.0.0", + "object-visit": "1.0.1" + } + }, + "commondir": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "component-emitter": { + "version": "1.2.1", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "convert-source-map": { + "version": "1.5.1", + "bundled": true, + "dev": true + }, + "copy-descriptor": { + "version": "0.1.1", + "bundled": true, + "dev": true + }, + "core-js": { + "version": "2.5.3", + "bundled": true, + "dev": true + }, + "cross-spawn": { + "version": "4.0.2", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "4.1.2", + "which": "1.3.0" + } + }, + "debug": { + "version": "2.6.9", + "bundled": true, + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "debug-log": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "decamelize": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "bundled": true, + "dev": true + }, + "default-require-extensions": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "strip-bom": "2.0.0" + } + }, + "define-property": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "1.0.2", + "isobject": "3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "bundled": true, + "dev": true + } + } + }, + "detect-indent": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "repeating": "2.0.1" + } + }, + "error-ex": { + "version": "1.3.1", + "bundled": true, + "dev": true, + "requires": { + "is-arrayish": "0.2.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "bundled": true, + "dev": true + }, + "esutils": { + "version": "2.0.2", + "bundled": true, + "dev": true + }, + "execa": { + "version": "0.7.0", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "5.1.0", + "get-stream": "3.0.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "4.1.2", + "shebang-command": "1.2.0", + "which": "1.3.0" + } + } + } + }, + "expand-brackets": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "requires": { + "is-posix-bracket": "0.1.1" + } + }, + "expand-range": { + "version": "1.8.2", + "bundled": true, + "dev": true, + "requires": { + "fill-range": "2.2.3" + } + }, + "extend-shallow": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "assign-symbols": "1.0.0", + "is-extendable": "1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-plain-object": "2.0.4" + } + } + } + }, + "extglob": { + "version": "0.3.2", + "bundled": true, + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "filename-regex": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "fill-range": { + "version": "2.2.3", + "bundled": true, + "dev": true, + "requires": { + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "1.1.7", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" + } + }, + "find-cache-dir": { + "version": "0.1.1", + "bundled": true, + "dev": true, + "requires": { + "commondir": "1.0.1", + "mkdirp": "0.5.1", + "pkg-dir": "1.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "locate-path": "2.0.0" + } + }, + "for-in": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "for-own": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "requires": { + "for-in": "1.0.2" + } + }, + "foreground-child": { + "version": "1.5.6", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "4.0.2", + "signal-exit": "3.0.2" + } + }, + "fragment-cache": { + "version": "0.2.1", + "bundled": true, + "dev": true, + "requires": { + "map-cache": "0.2.2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "get-caller-file": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "get-value": { + "version": "2.0.6", + "bundled": true, + "dev": true + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "glob-base": { + "version": "0.3.0", + "bundled": true, + "dev": true, + "requires": { + "glob-parent": "2.0.0", + "is-glob": "2.0.1" + } + }, + "glob-parent": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-glob": "2.0.1" + } + }, + "globals": { + "version": "9.18.0", + "bundled": true, + "dev": true + }, + "graceful-fs": { + "version": "4.1.11", + "bundled": true, + "dev": true + }, + "handlebars": { + "version": "4.0.11", + "bundled": true, + "dev": true, + "requires": { + "async": "1.5.2", + "optimist": "0.6.1", + "source-map": "0.4.4", + "uglify-js": "2.8.29" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "bundled": true, + "dev": true, + "requires": { + "amdefine": "1.0.1" + } + } + } + }, + "has-ansi": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "has-flag": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "has-value": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "get-value": "2.0.6", + "has-values": "1.0.0", + "isobject": "3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "bundled": true, + "dev": true + } + } + }, + "has-values": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-number": "3.0.0", + "kind-of": "4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "hosted-git-info": { + "version": "2.6.0", + "bundled": true, + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "bundled": true, + "dev": true + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "invariant": { + "version": "2.2.3", + "bundled": true, + "dev": true, + "requires": { + "loose-envify": "1.3.1" + } + }, + "invert-kv": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "6.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "bundled": true, + "dev": true + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "bundled": true, + "dev": true + }, + "is-buffer": { + "version": "1.1.6", + "bundled": true, + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "builtin-modules": "1.1.1" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "6.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "bundled": true, + "dev": true + } + } + }, + "is-descriptor": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "bundled": true, + "dev": true + } + } + }, + "is-dotfile": { + "version": "1.0.3", + "bundled": true, + "dev": true + }, + "is-equal-shallow": { + "version": "0.1.3", + "bundled": true, + "dev": true, + "requires": { + "is-primitive": "2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "bundled": true, + "dev": true + }, + "is-extglob": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + }, + "is-number": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "is-odd": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-number": "4.0.0" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "bundled": true, + "dev": true + } + } + }, + "is-plain-object": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "requires": { + "isobject": "3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "bundled": true, + "dev": true + } + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "bundled": true, + "dev": true + }, + "is-primitive": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "bundled": true, + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "isexe": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "isobject": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "isarray": "1.0.0" + } + }, + "istanbul-lib-coverage": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "istanbul-lib-hook": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "append-transform": "0.4.0" + } + }, + "istanbul-lib-instrument": { + "version": "1.10.1", + "bundled": true, + "dev": true, + "requires": { + "babel-generator": "6.26.1", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "istanbul-lib-coverage": "1.2.0", + "semver": "5.5.0" + } + }, + "istanbul-lib-report": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "requires": { + "istanbul-lib-coverage": "1.2.0", + "mkdirp": "0.5.1", + "path-parse": "1.0.5", + "supports-color": "3.2.3" + }, + "dependencies": { + "supports-color": { + "version": "3.2.3", + "bundled": true, + "dev": true, + "requires": { + "has-flag": "1.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "1.2.3", + "bundled": true, + "dev": true, + "requires": { + "debug": "3.1.0", + "istanbul-lib-coverage": "1.2.0", + "mkdirp": "0.5.1", + "rimraf": "2.6.2", + "source-map": "0.5.7" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "istanbul-reports": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "handlebars": "4.0.11" + } + }, + "js-tokens": { + "version": "3.0.2", + "bundled": true, + "dev": true + }, + "jsesc": { + "version": "1.3.0", + "bundled": true, + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + }, + "lazy-cache": { + "version": "1.0.4", + "bundled": true, + "dev": true, + "optional": true + }, + "lcid": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "invert-kv": "1.0.0" + } + }, + "load-json-file": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-locate": "2.0.0", + "path-exists": "3.0.0" + }, + "dependencies": { + "path-exists": { + "version": "3.0.0", + "bundled": true, + "dev": true + } + } + }, + "lodash": { + "version": "4.17.5", + "bundled": true, + "dev": true + }, + "longest": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "loose-envify": { + "version": "1.3.1", + "bundled": true, + "dev": true, + "requires": { + "js-tokens": "3.0.2" + } + }, + "lru-cache": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + }, + "map-cache": { + "version": "0.2.2", + "bundled": true, + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "object-visit": "1.0.1" + } + }, + "md5-hex": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "md5-o-matic": "0.1.1" + } + }, + "md5-o-matic": { + "version": "0.1.1", + "bundled": true, + "dev": true + }, + "mem": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "mimic-fn": "1.2.0" + } + }, + "merge-source-map": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "source-map": "0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "micromatch": { + "version": "2.3.11", + "bundled": true, + "dev": true, + "requires": { + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.2", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.4" + } + }, + "mimic-fn": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "1.1.11" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "mixin-deep": { + "version": "1.3.1", + "bundled": true, + "dev": true, + "requires": { + "for-in": "1.0.2", + "is-extendable": "1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-plain-object": "2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "nanomatch": { + "version": "1.2.9", + "bundled": true, + "dev": true, + "requires": { + "arr-diff": "4.0.0", + "array-unique": "0.3.2", + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "fragment-cache": "0.2.1", + "is-odd": "2.0.0", + "is-windows": "1.0.2", + "kind-of": "6.0.2", + "object.pick": "1.3.0", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "bundled": true, + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "bundled": true, + "dev": true + } + } + }, + "normalize-package-data": { + "version": "2.4.0", + "bundled": true, + "dev": true, + "requires": { + "hosted-git-info": "2.6.0", + "is-builtin-module": "1.0.0", + "semver": "5.5.0", + "validate-npm-package-license": "3.0.3" + } + }, + "normalize-path": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "remove-trailing-separator": "1.1.0" + } + }, + "npm-run-path": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "path-key": "2.0.1" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "bundled": true, + "dev": true, + "requires": { + "copy-descriptor": "0.1.1", + "define-property": "0.2.5", + "kind-of": "3.2.2" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "is-descriptor": { + "version": "0.1.6", + "bundled": true, + "dev": true, + "requires": { + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "bundled": true, + "dev": true + } + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "isobject": "3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "bundled": true, + "dev": true + } + } + }, + "object.omit": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "for-own": "0.1.5", + "is-extendable": "0.1.1" + } + }, + "object.pick": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "isobject": "3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "bundled": true, + "dev": true + } + } + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "optimist": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8", + "wordwrap": "0.0.3" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "os-locale": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "execa": "0.7.0", + "lcid": "1.0.0", + "mem": "1.1.0" + } + }, + "p-finally": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "p-limit": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "p-try": "1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-limit": "1.2.0" + } + }, + "p-try": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "parse-glob": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "glob-base": "0.3.0", + "is-dotfile": "1.0.3", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" + } + }, + "parse-json": { + "version": "2.2.0", + "bundled": true, + "dev": true, + "requires": { + "error-ex": "1.3.1" + } + }, + "pascalcase": { + "version": "0.1.1", + "bundled": true, + "dev": true + }, + "path-exists": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "pinkie-promise": "2.0.1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "path-key": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "path-parse": { + "version": "1.0.5", + "bundled": true, + "dev": true + }, + "path-type": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" + } + }, + "pify": { + "version": "2.3.0", + "bundled": true, + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "bundled": true, + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "pinkie": "2.0.4" + } + }, + "pkg-dir": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "find-up": "1.1.2" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } + } + } + }, + "posix-character-classes": { + "version": "0.1.1", + "bundled": true, + "dev": true + }, + "preserve": { + "version": "0.2.0", + "bundled": true, + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "randomatic": { + "version": "1.1.7", + "bundled": true, + "dev": true, + "requires": { + "is-number": "3.0.0", + "kind-of": "4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "read-pkg": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "load-json-file": "1.1.0", + "normalize-package-data": "2.4.0", + "path-type": "1.1.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "requires": { + "find-up": "1.1.2", + "read-pkg": "1.1.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } + } + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "bundled": true, + "dev": true + }, + "regex-cache": { + "version": "0.4.4", + "bundled": true, + "dev": true, + "requires": { + "is-equal-shallow": "0.1.3" + } + }, + "regex-not": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "extend-shallow": "3.0.2", + "safe-regex": "1.1.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "bundled": true, + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "bundled": true, + "dev": true + }, + "repeating": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-finite": "1.0.2" + } + }, + "require-directory": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "resolve-from": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "bundled": true, + "dev": true + }, + "ret": { + "version": "0.1.15", + "bundled": true, + "dev": true + }, + "right-align": { + "version": "0.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "align-text": "0.1.4" + } + }, + "rimraf": { + "version": "2.6.2", + "bundled": true, + "dev": true, + "requires": { + "glob": "7.1.2" + } + }, + "safe-regex": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "ret": "0.1.15" + } + }, + "semver": { + "version": "5.5.0", + "bundled": true, + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "set-value": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "extend-shallow": "2.0.1", + "is-extendable": "0.1.1", + "is-plain-object": "2.0.4", + "split-string": "3.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "shebang-command": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "shebang-regex": "1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true + }, + "slide": { + "version": "1.1.6", + "bundled": true, + "dev": true + }, + "snapdragon": { + "version": "0.8.2", + "bundled": true, + "dev": true, + "requires": { + "base": "0.11.2", + "debug": "2.6.9", + "define-property": "0.2.5", + "extend-shallow": "2.0.1", + "map-cache": "0.2.2", + "source-map": "0.5.7", + "source-map-resolve": "0.5.1", + "use": "3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "bundled": true, + "dev": true, + "requires": { + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" + } + }, + "kind-of": { + "version": "5.1.0", + "bundled": true, + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "define-property": "1.0.0", + "isobject": "3.0.1", + "snapdragon-util": "3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "bundled": true, + "dev": true + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "source-map": { + "version": "0.5.7", + "bundled": true, + "dev": true + }, + "source-map-resolve": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "atob": "2.0.3", + "decode-uri-component": "0.2.0", + "resolve-url": "0.2.1", + "source-map-url": "0.4.0", + "urix": "0.1.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "bundled": true, + "dev": true + }, + "spawn-wrap": { + "version": "1.4.2", + "bundled": true, + "dev": true, + "requires": { + "foreground-child": "1.5.6", + "mkdirp": "0.5.1", + "os-homedir": "1.0.2", + "rimraf": "2.6.2", + "signal-exit": "3.0.2", + "which": "1.3.0" + } + }, + "spdx-correct": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-expression-parse": "3.0.0", + "spdx-license-ids": "3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.1.0", + "bundled": true, + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-exceptions": "2.1.0", + "spdx-license-ids": "3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "split-string": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "extend-shallow": "3.0.2" + } + }, + "static-extend": { + "version": "0.1.2", + "bundled": true, + "dev": true, + "requires": { + "define-property": "0.2.5", + "object-copy": "0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "bundled": true, + "dev": true, + "requires": { + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" + } + }, + "kind-of": { + "version": "5.1.0", + "bundled": true, + "dev": true + } + } + }, + "string-width": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-bom": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-utf8": "0.2.1" + } + }, + "strip-eof": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "supports-color": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "test-exclude": { + "version": "4.2.1", + "bundled": true, + "dev": true, + "requires": { + "arrify": "1.0.1", + "micromatch": "3.1.9", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "require-main-filename": "1.0.1" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "bundled": true, + "dev": true + }, + "braces": { + "version": "2.3.1", + "bundled": true, + "dev": true, + "requires": { + "arr-flatten": "1.1.0", + "array-unique": "0.3.2", + "define-property": "1.0.0", + "extend-shallow": "2.0.1", + "fill-range": "4.0.0", + "isobject": "3.0.1", + "kind-of": "6.0.2", + "repeat-element": "1.1.2", + "snapdragon": "0.8.2", + "snapdragon-node": "2.1.1", + "split-string": "3.1.0", + "to-regex": "3.0.2" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "expand-brackets": { + "version": "2.1.4", + "bundled": true, + "dev": true, + "requires": { + "debug": "2.6.9", + "define-property": "0.2.5", + "extend-shallow": "2.0.1", + "posix-character-classes": "0.1.1", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + }, + "is-descriptor": { + "version": "0.1.6", + "bundled": true, + "dev": true, + "requires": { + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" + } + }, + "kind-of": { + "version": "5.1.0", + "bundled": true, + "dev": true + } + } + }, + "extglob": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "requires": { + "array-unique": "0.3.2", + "define-property": "1.0.0", + "expand-brackets": "2.1.4", + "extend-shallow": "2.0.1", + "fragment-cache": "0.2.1", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "extend-shallow": "2.0.1", + "is-number": "3.0.0", + "repeat-string": "1.6.1", + "to-regex-range": "2.1.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "bundled": true, + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "bundled": true, + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "bundled": true, + "dev": true + }, + "micromatch": { + "version": "3.1.9", + "bundled": true, + "dev": true, + "requires": { + "arr-diff": "4.0.0", + "array-unique": "0.3.2", + "braces": "2.3.1", + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "extglob": "2.0.4", + "fragment-cache": "0.2.1", + "kind-of": "6.0.2", + "nanomatch": "1.2.9", + "object.pick": "1.3.0", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" + } + } + } + }, + "to-fast-properties": { + "version": "1.0.3", + "bundled": true, + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + }, + "to-regex": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "regex-not": "1.0.2", + "safe-regex": "1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "is-number": "3.0.0", + "repeat-string": "1.6.1" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "3.2.2" + } + } + } + }, + "trim-right": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "uglify-js": { + "version": "2.8.29", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "source-map": "0.5.7", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" + }, + "dependencies": { + "yargs": { + "version": "3.10.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", + "window-size": "0.1.0" + } + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "union-value": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "arr-union": "3.1.0", + "get-value": "2.0.6", + "is-extendable": "0.1.1", + "set-value": "0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + }, + "set-value": { + "version": "0.4.3", + "bundled": true, + "dev": true, + "requires": { + "extend-shallow": "2.0.1", + "is-extendable": "0.1.1", + "is-plain-object": "2.0.4", + "to-object-path": "0.3.0" + } + } + } + }, + "unset-value": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "has-value": "0.3.1", + "isobject": "3.0.1" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "bundled": true, + "dev": true, + "requires": { + "get-value": "2.0.6", + "has-values": "0.1.4", + "isobject": "2.1.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "bundled": true, + "dev": true + }, + "isobject": { + "version": "3.0.1", + "bundled": true, + "dev": true + } + } + }, + "urix": { + "version": "0.1.0", + "bundled": true, + "dev": true + }, + "use": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "kind-of": "6.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "bundled": true, + "dev": true + } + } + }, + "validate-npm-package-license": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "requires": { + "spdx-correct": "3.0.0", + "spdx-expression-parse": "3.0.0" + } + }, + "which": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "isexe": "2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "window-size": { + "version": "0.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "wordwrap": { + "version": "0.0.3", + "bundled": true, + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "write-file-atomic": { + "version": "1.3.4", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "imurmurhash": "0.1.4", + "slide": "1.1.6" + } + }, + "y18n": { + "version": "3.2.1", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "2.1.2", + "bundled": true, + "dev": true + }, + "yargs": { + "version": "11.1.0", + "bundled": true, + "dev": true, + "requires": { + "cliui": "4.0.0", + "decamelize": "1.2.0", + "find-up": "2.1.0", + "get-caller-file": "1.0.2", + "os-locale": "2.1.0", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "2.1.1", + "which-module": "2.0.0", + "y18n": "3.2.1", + "yargs-parser": "9.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "bundled": true, + "dev": true + }, + "cliui": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "wrap-ansi": "2.1.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + }, + "yargs-parser": { + "version": "9.0.2", + "bundled": true, + "dev": true, + "requires": { + "camelcase": "4.1.0" + } + } + } + }, + "yargs-parser": { + "version": "8.1.0", + "bundled": true, + "dev": true, + "requires": { + "camelcase": "4.1.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "bundled": true, + "dev": true + } + } + } + } + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "0.1.1", + "define-property": "0.2.5", + "kind-of": "3.2.2" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "object-keys": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", + "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "3.0.1" + } + }, + "object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "dev": true, + "requires": { + "array-each": "1.0.1", + "array-slice": "1.1.0", + "for-own": "1.0.0", + "isobject": "3.0.1" + } + }, + "object.map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", + "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "dev": true, + "requires": { + "for-own": "1.0.0", + "make-iterator": "1.0.1" + } + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true, + "requires": { + "for-own": "0.1.5", + "is-extendable": "0.1.1" + }, + "dependencies": { + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "requires": { + "for-in": "1.0.2" + } + } + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "3.0.1" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "open": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/open/-/open-0.0.5.tgz", + "integrity": "sha1-QsPhjslUZra/DcQvOilFw/DK2Pw=" + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "requires": { + "minimist": "0.0.10", + "wordwrap": "0.0.3" + }, + "dependencies": { + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", + "dev": true + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + } + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "0.1.3", + "fast-levenshtein": "2.0.6", + "levn": "0.3.0", + "prelude-ls": "1.1.2", + "type-check": "0.3.2", + "wordwrap": "1.0.0" + } + }, + "orchestrator": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/orchestrator/-/orchestrator-0.3.8.tgz", + "integrity": "sha1-FOfp4nZPcxX7rBhOUGx6pt+UrX4=", + "dev": true, + "requires": { + "end-of-stream": "0.1.5", "sequencify": "0.0.7", - "stream-consume": "0.1.0" + "stream-consume": "0.1.1" } }, "ordered-read-streams": { @@ -3656,40 +8647,81 @@ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "dev": true, + "requires": { + "execa": "0.7.0", + "lcid": "1.0.0", + "mem": "1.1.0" + } + }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" }, "osenv": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz", - "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=", + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", "dev": true, "requires": { "os-homedir": "1.0.2", "os-tmpdir": "1.0.2" } }, + "over": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/over/-/over-0.0.5.tgz", + "integrity": "sha1-8phS5w/X4l82DgE6jsRMgq7bVwg=", + "dev": true + }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", "dev": true }, + "p-limit": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", + "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", + "dev": true, + "requires": { + "p-try": "1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "1.2.0" + } + }, "p-map": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", "dev": true }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, "parse-filepath": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.1.tgz", - "integrity": "sha1-FZ1hVdQ5BNFsEO9piRHaHpGWm3M=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", "dev": true, "requires": { - "is-absolute": "0.2.6", + "is-absolute": "1.0.0", "map-cache": "0.2.2", "path-root": "0.1.1" } @@ -3704,6 +8736,23 @@ "is-dotfile": "1.0.3", "is-extglob": "1.0.0", "is-glob": "2.0.1" + }, + "dependencies": { + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "1.0.0" + } + } } }, "parse-json": { @@ -3727,7 +8776,7 @@ "integrity": "sha1-mkr9bfBj3Egm+T+6SpnPIj9mbLg=", "dev": true, "requires": { - "semver": "5.4.1" + "semver": "5.5.0" } }, "parse5": { @@ -3736,15 +8785,33 @@ "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", "dev": true, "requires": { - "@types/node": "8.0.53" + "@types/node": "9.6.4" } }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, "path-dirname": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", "dev": true }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -3785,12 +8852,14 @@ "dev": true }, "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "requires": { - "pify": "2.3.0" + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" }, "dependencies": { "pify": { @@ -3822,9 +8891,9 @@ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" }, "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", + "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", "dev": true }, "pify": { @@ -3849,16 +8918,80 @@ } }, "plist": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/plist/-/plist-2.0.1.tgz", - "integrity": "sha1-CjLKlIGxw2TpLhjcVch23p0B2os=", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz", + "integrity": "sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ==", "dev": true, "requires": { - "base64-js": "1.1.2", - "xmlbuilder": "8.2.2", + "base64-js": "1.2.3", + "xmlbuilder": "9.0.7", "xmldom": "0.1.27" } }, + "plugin-error": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", + "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=", + "dev": true, + "requires": { + "ansi-cyan": "0.1.1", + "ansi-red": "0.1.1", + "arr-diff": "1.1.0", + "arr-union": "2.1.0", + "extend-shallow": "1.1.4" + }, + "dependencies": { + "arr-diff": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz", + "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=", + "dev": true, + "requires": { + "arr-flatten": "1.1.0", + "array-slice": "0.2.3" + } + }, + "arr-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz", + "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=", + "dev": true + }, + "array-slice": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", + "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", + "dev": true + }, + "extend-shallow": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz", + "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=", + "dev": true, + "requires": { + "kind-of": "1.1.0" + } + }, + "kind-of": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", + "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=", + "dev": true + } + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, "preserve": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", @@ -3872,9 +9005,9 @@ "dev": true }, "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true }, "ps-tree": { @@ -3892,6 +9025,18 @@ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, + "pullstream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/pullstream/-/pullstream-0.4.1.tgz", + "integrity": "sha1-1vs79a7Wl+gxFQ6xACwlo/iuExQ=", + "dev": true, + "requires": { + "over": "0.0.5", + "readable-stream": "1.0.34", + "setimmediate": "1.0.5", + "slice-stream": "1.0.0" + } + }, "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", @@ -3905,9 +9050,9 @@ "dev": true }, "qs": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz", - "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", + "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", "dev": true }, "querystringify": { @@ -3935,26 +9080,6 @@ "kind-of": "4.0.0" }, "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, "kind-of": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", @@ -3966,6 +9091,44 @@ } } }, + "raw-body": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", + "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "dev": true, + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "unpipe": "1.0.0" + }, + "dependencies": { + "depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", + "dev": true + }, + "http-errors": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", + "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "dev": true, + "requires": { + "depd": "1.1.1", + "inherits": "2.0.3", + "setprototypeof": "1.0.3", + "statuses": "1.5.0" + } + }, + "setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", + "dev": true + } + } + }, "read": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", @@ -3976,20 +9139,51 @@ } }, "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "requires": { - "load-json-file": "2.0.0", + "load-json-file": "1.1.0", "normalize-package-data": "2.4.0", - "path-type": "2.0.0" + "path-type": "1.1.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "1.1.2", + "read-pkg": "1.1.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "2.0.1" + } + } } }, "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { "core-util-is": "1.0.2", @@ -4005,7 +9199,7 @@ "dev": true, "requires": { "call-me-maybe": "1.0.1", - "es6-promise": "4.1.1", + "es6-promise": "4.2.4", "glob-to-regexp": "0.3.0" } }, @@ -4015,9 +9209,15 @@ "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", "dev": true, "requires": { - "resolve": "1.5.0" + "resolve": "1.7.0" } }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + }, "regex-cache": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", @@ -4027,220 +9227,188 @@ "is-equal-shallow": "0.1.3" } }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "replace-ext": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", - "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", - "dev": true + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "3.0.2", + "safe-regex": "1.1.0" + } }, - "request": { - "version": "2.83.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", - "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", + "remap-istanbul": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/remap-istanbul/-/remap-istanbul-0.11.0.tgz", + "integrity": "sha512-gQqJ+mW+jF7Hv8hXYO/pIRMz6WgZyrlp3rSxejGXzwqtK9+sNTB/tUSnLWAFTgQx4x5dx0sPDsLvbpZXuZ0omQ==", "dev": true, "requires": { - "aws-sign2": "0.7.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.3.1", - "har-validator": "5.0.3", - "hawk": "6.0.2", - "http-signature": "1.2.0", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.17", - "oauth-sign": "0.8.2", - "performance-now": "2.1.0", - "qs": "6.5.1", - "safe-buffer": "5.1.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.3", - "tunnel-agent": "0.6.0", - "uuid": "3.1.0" + "amdefine": "1.0.1", + "istanbul": "0.4.5", + "minimatch": "3.0.4", + "plugin-error": "0.1.2", + "source-map": "0.6.1", + "through2": "2.0.1" }, "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true - }, - "boom": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", - "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", - "dev": true, - "requires": { - "hoek": "4.2.0" - } - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, - "cryptiles": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", - "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", - "dev": true, - "requires": { - "boom": "5.2.0" - }, - "dependencies": { - "boom": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", - "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", - "dev": true, - "requires": { - "hoek": "4.2.0" - } - } - } - }, - "form-data": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", - "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", - "dev": true, - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" - } - }, - "har-validator": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", - "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", - "dev": true, - "requires": { - "ajv": "5.5.1", - "har-schema": "2.0.0" - } - }, - "hawk": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", - "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", - "dev": true, - "requires": { - "boom": "4.3.1", - "cryptiles": "3.1.2", - "hoek": "4.2.0", - "sntp": "2.1.0" - } - }, - "hoek": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", - "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==", - "dev": true - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "jsprim": "1.4.1", - "sshpk": "1.13.1" - } + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true }, - "qs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", "dev": true }, - "sntp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", - "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", "dev": true, "requires": { - "hoek": "4.2.0" + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" } }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "through2": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.1.tgz", + "integrity": "sha1-OE51MU1J8y3hLuu4E2uOtrXVnak=", "dev": true, "requires": { - "safe-buffer": "5.1.1" + "readable-stream": "2.0.6", + "xtend": "4.0.1" } } } }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", + "dev": true + }, + "request": { + "version": "2.81.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", + "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", + "dev": true, + "requires": { + "aws-sign2": "0.6.0", + "aws4": "1.7.0", + "caseless": "0.12.0", + "combined-stream": "1.0.6", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.1.4", + "har-validator": "4.2.1", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.18", + "oauth-sign": "0.8.2", + "performance-now": "0.2.0", + "qs": "6.4.0", + "safe-buffer": "5.1.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.4", + "tunnel-agent": "0.6.0", + "uuid": "3.2.1" + } + }, "request-light": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.1.tgz", - "integrity": "sha1-mG9agok+nRymqJbr5vRsUca0VX8=", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.2.2.tgz", + "integrity": "sha512-sQx7pzLfXK0JVq+EoHVaSgZgFZsLCrG6GPUcksbu8xJzLyNLh8X/Z5RnsuX6rhAkxBWVM4Nhfhc9uo+fK4a1PA==", "requires": { - "http-proxy-agent": "0.2.7", - "https-proxy-agent": "0.3.6", + "http-proxy-agent": "2.0.0", + "https-proxy-agent": "2.1.1", "vscode-nls": "2.0.2" }, "dependencies": { - "agent-base": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-1.0.2.tgz", - "integrity": "sha1-aJDT+yFwBLYrcPiSjg+uX4lSpwY=" + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } }, "http-proxy-agent": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-0.2.7.tgz", - "integrity": "sha1-4X/aZfCQLZUs55IeYsf/iGJlWl4=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.0.0.tgz", + "integrity": "sha1-RkgqLwUjpNYIJVFwn0acs+SoX/Q=", "requires": { - "agent-base": "1.0.2", - "debug": "2.6.9", - "extend": "3.0.1" + "agent-base": "4.2.0", + "debug": "2.6.9" } }, "https-proxy-agent": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-0.3.6.tgz", - "integrity": "sha1-cT+jjl01P1DrFKNC/r4pAz7RYZs=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.1.1.tgz", + "integrity": "sha512-LK6tQUR/VOkTI6ygAfWUKKP95I+e6M1h7N3PncGu1CATHCnex+CAv9ttR0lbHu1Uk2PXm/WoAHFo6JCGwMjVMw==", "requires": { - "agent-base": "1.0.2", - "debug": "2.6.9", - "extend": "3.0.1" + "agent-base": "4.2.0", + "debug": "3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + } } } } }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -4248,22 +9416,44 @@ "dev": true }, "resolve": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", - "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.0.tgz", + "integrity": "sha512-QdgZ5bjR1WAlpLaO5yHepFvC+o3rCr6wpfE2tpJNMkXdulf2jKomQBdNRQITF3ZKHNlT71syG98yQP03gasgnA==", "dev": true, "requires": { "path-parse": "1.0.5" } }, "resolve-dir": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz", - "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "2.0.2", + "global-modules": "1.0.0" + } + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", "dev": true, + "optional": true, "requires": { - "expand-tilde": "1.2.2", - "global-modules": "0.2.3" + "align-text": "0.1.4" } }, "rimraf": { @@ -4275,16 +9465,33 @@ "glob": "7.1.2" } }, + "rxjs": { + "version": "5.5.9", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.9.tgz", + "integrity": "sha512-DHG9AHmCmgaFWgjBcXp6NxFDmh3MvIA62GqTWmLnTzr/3oZ6h5hLD8NA+9j+GF0jEwklNIpI4KuuyLG8UWMEvQ==", + "requires": { + "symbol-observable": "1.0.1" + } + }, "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", "dev": true }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "0.1.15" + } + }, "semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" }, "sequencify": { "version": "0.0.7", @@ -4292,6 +9499,47 @@ "integrity": "sha1-kM/xnQLgcCf9dn9erT57ldHnOAw=", "dev": true }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "dev": true, + "requires": { + "extend-shallow": "2.0.1", + "is-extendable": "0.1.1", + "is-plain-object": "2.0.4", + "split-string": "3.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -4319,10 +9567,21 @@ "jsonify": "0.0.0" } }, + "shelljs": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.1.tgz", + "integrity": "sha512-YA/iYtZpzFe5HyWVGrb02FjPxc4EMCfpoU/Phg9fQoyMC72u9598OUBrsU8IrtwAKG0tO8IYaqbaLIw+k3IRGA==", + "dev": true, + "requires": { + "glob": "7.1.2", + "interpret": "1.1.0", + "rechoir": "0.6.2" + } + }, "sift": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/sift/-/sift-5.0.0.tgz", - "integrity": "sha1-IS7LQQ2KUbg+fZaeSdU+ZZAoX/o=", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/sift/-/sift-5.1.0.tgz", + "integrity": "sha1-G78t+w63HlbEzH+1Z/vRNRtlAV4=", "dev": true }, "sigmund": { @@ -4337,6 +9596,131 @@ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, + "slice-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-stream/-/slice-stream-1.0.0.tgz", + "integrity": "sha1-WzO9ZvATsaf4ZGCwPUY97DmtPqA=", + "dev": true, + "requires": { + "readable-stream": "1.0.34" + } + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "0.11.2", + "debug": "2.6.9", + "define-property": "0.2.5", + "extend-shallow": "2.0.1", + "map-cache": "0.2.2", + "source-map": "0.5.7", + "source-map-resolve": "0.5.1", + "use": "3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "1.0.0", + "isobject": "3.0.1", + "snapdragon-util": "3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, "sntp": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", @@ -4347,20 +9731,47 @@ } }, "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, + "source-map-resolve": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.1.tgz", + "integrity": "sha512-0KW2wvzfxm8NCTb30z0LMNyPqWCdDGE2viwzUaucqJdkTRXtZiSY3I+2A6nVAjmdOy0I4gU8DwnVVGsk9jvP2A==", + "dev": true, + "requires": { + "atob": "2.1.0", + "decode-uri-component": "0.2.0", + "resolve-url": "0.2.1", + "source-map-url": "0.4.0", + "urix": "0.1.0" + } + }, "source-map-support": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.0.tgz", - "integrity": "sha512-vUoN3I7fHQe0R/SJLKRdKYuEdRGogsviXFkHHo17AWaTGv17VLnxw+CFXvqy+y4ORZ3doWLQcxRYfwKrsd/H7Q==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.4.tgz", + "integrity": "sha512-PETSPG6BjY1AHs2t64vS2aqAgu6dMIMXJULWFBGbh2Gr8nVLbCFDo6i/RMMvviIQ2h1Z8+5gQhVKSn2je9nmdg==", "dev": true, "requires": { "source-map": "0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, "sparkles": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", @@ -4368,24 +9779,35 @@ "dev": true }, "spdx-correct": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", - "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", + "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", "dev": true, "requires": { - "spdx-license-ids": "1.2.2" + "spdx-expression-parse": "3.0.0", + "spdx-license-ids": "3.0.0" } }, - "spdx-expression-parse": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", - "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "spdx-exceptions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", + "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", "dev": true }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "2.1.0", + "spdx-license-ids": "3.0.0" + } + }, "spdx-license-ids": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", - "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", + "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", "dev": true }, "split": { @@ -4397,6 +9819,15 @@ "through": "2.3.8" } }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "3.0.2" + } + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -4404,9 +9835,9 @@ "dev": true }, "sshpk": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", - "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz", + "integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=", "dev": true, "requires": { "asn1": "0.2.3", @@ -4433,6 +9864,33 @@ "integrity": "sha1-5sgLYjEj19gM8TLOU480YokHJQI=", "dev": true }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "0.2.5", + "object-copy": "0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "0.1.6" + } + } + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, "stream-combiner": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", @@ -4443,9 +9901,9 @@ } }, "stream-consume": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.0.tgz", - "integrity": "sha1-pB6tGm1ggc63n2WwYZAbbY89HQ8=", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.1.tgz", + "integrity": "sha512-tNa3hzgkjEP7XbCkbRXe1jpg+ievoa0O4SCFlMOYEscGSS4JJsckGL8swUyAa/ApGU3Ae4t6Honor4HhL+tRyg==", "dev": true }, "stream-shift": { @@ -4460,7 +9918,7 @@ "integrity": "sha512-Gk6KZM+yNA1JpW0KzlZIhjo3EaBJDkYfXtYSbOwNIQ7Zd6006E6+sCFlW1NDvFG/vnXhKmw6TJJgiEQg/8lXfQ==", "dev": true, "requires": { - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" }, "dependencies": { "isarray": { @@ -4470,24 +9928,24 @@ "dev": true }, "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { "core-util-is": "1.0.2", "inherits": "2.0.3", "isarray": "1.0.0", - "process-nextick-args": "1.0.7", + "process-nextick-args": "2.0.0", "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", + "string_decoder": "1.1.1", "util-deprecate": "1.0.2" } }, "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { "safe-buffer": "5.1.1" @@ -4501,6 +9959,16 @@ "integrity": "sha1-l+mNj6TRBdYqJpHR3AfoINuN/E8=", "dev": true }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + } + }, "string.prototype.padend": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz", @@ -4508,7 +9976,7 @@ "dev": true, "requires": { "define-properties": "1.1.2", - "es-abstract": "1.10.0", + "es-abstract": "1.11.0", "function-bind": "1.1.1" } }, @@ -4525,12 +9993,12 @@ "dev": true }, "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "3.0.0" } }, "strip-bom": { @@ -4576,6 +10044,11 @@ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true }, + "symbol-observable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", + "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=" + }, "tar": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", @@ -4585,6 +10058,73 @@ "block-stream": "0.0.9", "fstream": "1.0.11", "inherits": "2.0.3" + }, + "dependencies": { + "fstream": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", + "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11", + "inherits": "2.0.3", + "mkdirp": "0.5.1", + "rimraf": "2.6.2" + } + } + } + }, + "tar-stream": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.5.tgz", + "integrity": "sha512-mQdgLPc/Vjfr3VWqWbfxW8yQNiJCbAZ+Gf6GDu1Cy0bdb33ofyiNGBtAY96jHFhDuivCwgW1H9DgTON+INiXgg==", + "dev": true, + "requires": { + "bl": "1.2.2", + "end-of-stream": "1.4.1", + "readable-stream": "2.3.6", + "xtend": "4.0.1" + }, + "dependencies": { + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "1.4.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } } }, "through": { @@ -4599,7 +10139,7 @@ "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", "dev": true, "requires": { - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "xtend": "4.0.1" }, "dependencies": { @@ -4610,24 +10150,24 @@ "dev": true }, "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { "core-util-is": "1.0.2", "inherits": "2.0.3", "isarray": "1.0.0", - "process-nextick-args": "1.0.7", + "process-nextick-args": "2.0.0", "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", + "string_decoder": "1.1.1", "util-deprecate": "1.0.2" } }, "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { "safe-buffer": "5.1.1" @@ -4645,6 +10185,12 @@ "xtend": "4.0.1" } }, + "thunks": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/thunks/-/thunks-4.9.2.tgz", + "integrity": "sha1-qsLTU4ElEhYKRhHjAI16luN1b44=", + "dev": true + }, "tildify": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz", @@ -4675,112 +10221,223 @@ "dev": true, "requires": { "extend-shallow": "2.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } + } + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "regex-not": "1.0.2", + "safe-regex": "1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "3.0.0", + "repeat-string": "1.6.1" } }, "tough-cookie": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", - "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", "dev": true, "requires": { "punycode": "1.4.1" } }, + "traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", + "dev": true + }, + "ts-node": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-5.0.1.tgz", + "integrity": "sha512-XK7QmDcNHVmZkVtkiwNDWiERRHPyU8nBqZB1+iv2UhOG0q3RQ9HsZ2CMqISlFbxjrYFGfG2mX7bW4dAyxBVzUw==", + "dev": true, + "requires": { + "arrify": "1.0.1", + "chalk": "2.3.2", + "diff": "3.3.1", + "make-error": "1.3.4", + "minimist": "1.2.0", + "mkdirp": "0.5.1", + "source-map-support": "0.5.4", + "yn": "2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", + "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", + "dev": true, + "requires": { + "ansi-styles": "3.2.1", + "escape-string-regexp": "1.0.5", + "supports-color": "5.3.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", + "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", + "dev": true, + "requires": { + "has-flag": "3.0.0" + } + } + } + }, "tslib": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.8.1.tgz", - "integrity": "sha1-aUavLR1lGnsYY7Ux1uWvpBqkTqw=", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz", + "integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ==", "dev": true }, "tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=", + "version": "5.9.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.9.1.tgz", + "integrity": "sha1-ElX4ej/1frCw4fDmEKi0dIBGya4=", "dev": true, "requires": { "babel-code-frame": "6.26.0", "builtin-modules": "1.1.1", - "chalk": "2.3.0", - "commander": "2.9.0", - "diff": "3.2.0", + "chalk": "2.3.2", + "commander": "2.15.1", + "diff": "3.3.1", "glob": "7.1.2", + "js-yaml": "3.11.0", "minimatch": "3.0.4", - "resolve": "1.5.0", - "semver": "5.4.1", - "tslib": "1.8.1", - "tsutils": "2.13.0" + "resolve": "1.7.0", + "semver": "5.5.0", + "tslib": "1.9.0", + "tsutils": "2.26.1" }, "dependencies": { "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { "color-convert": "1.9.1" } }, "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", + "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", "dev": true, "requires": { - "ansi-styles": "3.2.0", + "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "supports-color": "5.3.0" } }, + "commander": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "dev": true + }, "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", + "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", "dev": true, "requires": { - "has-flag": "2.0.0" + "has-flag": "3.0.0" } } } }, "tslint-microsoft-contrib": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-5.0.1.tgz", - "integrity": "sha1-Mo7pwo0HzfeTKTIEyW4v+rkiGZQ=", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-5.0.3.tgz", + "integrity": "sha512-5AnfTGlfpUzpRHLmoojPBKFTTmbjnwgdaTHMdllausa4GBPya5u36i9ddrTX4PhetGZvd4JUYIpAmgHqVnsctg==", "dev": true, "requires": { - "tsutils": "1.9.1" - }, - "dependencies": { - "tsutils": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-1.9.1.tgz", - "integrity": "sha1-ufmrROVa+WgYMdXyjQrur1x1DLA=", - "dev": true - } + "tsutils": "2.26.1" } }, "tslint-no-unused-expression-chai": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tslint-no-unused-expression-chai/-/tslint-no-unused-expression-chai-0.0.3.tgz", - "integrity": "sha512-jKqhimj5gKl96ngeKxSVG1nOE7wmKRiHXD3kKpi+GG+5CmXJevD0ogsThZ8uSQCBIELFLVqXpZ43PpLniWu7jw==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/tslint-no-unused-expression-chai/-/tslint-no-unused-expression-chai-0.1.3.tgz", + "integrity": "sha512-dNnAc2f4M0KvyPNtEgiW2lS1LIss9Rg+cYI6x9J2NQeNt7FUI/5UfOJvsOERyog+D5+YeEzhkQSfSc4H7KMZLA==", "dev": true, "requires": { - "tsutils": "2.13.0" + "tsutils": "2.26.1" } }, "tsutils": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.13.0.tgz", - "integrity": "sha512-FuWzNJbMsp3gcZMbI3b5DomhW4Ia41vMxjN63nKWI0t7f+I3UmHfRl0TrXJTwI2LUduDG+eR1Mksp3pvtlyCFQ==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.26.1.tgz", + "integrity": "sha512-bnm9bcjOqOr1UljleL94wVCDlpa6KjfGaTkefeLch4GRafgDkROxPizbB/FxTEdI++5JqhxczRy/Qub0syNqZA==", "dev": true, "requires": { - "tslib": "1.8.1" + "tslib": "1.9.0" } }, "tunnel": { @@ -4790,10 +10447,13 @@ "dev": true }, "tunnel-agent": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", - "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", - "dev": true + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } }, "tweetnacl": { "version": "0.14.5", @@ -4802,12 +10462,48 @@ "dev": true, "optional": true }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "1.1.2" + } + }, "type-detect": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.5.tgz", - "integrity": "sha512-N9IvkQslUGYGC24RkJk1ba99foK6TkwC2FHAEBlQFBP0RxQZS8ZpJuAZcwiY/w9ZJHFQb1aOXBI60OdxhTrwEQ==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, + "type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "2.1.18" + }, + "dependencies": { + "mime-db": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "dev": true + }, + "mime-types": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "dev": true, + "requires": { + "mime-db": "1.33.0" + } + } + } + }, "typed-rest-client": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-0.9.0.tgz", @@ -4819,17 +10515,77 @@ } }, "typescript": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.2.tgz", - "integrity": "sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q=", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.8.1.tgz", + "integrity": "sha512-Ao/f6d/4EPLq0YwzsQz8iXflezpTkQzqAyenTiw4kCUGr1uPiFLC3+fZ+gMZz6eeI/qdRUqvC+HxIJzUAzEFdg==", "dev": true }, "uc.micro": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.3.tgz", - "integrity": "sha1-ftUNXg+an7ClczeSWfKndFjVAZI=", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.5.tgz", + "integrity": "sha512-JoLI4g5zv5qNyT09f4YAvEZIIV1oOjqnewYg5D38dkQljIzpPT296dbIGvKro3digYI1bkb7W6EP1y4uDlmzLg==", "dev": true }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "dev": true, + "optional": true, + "requires": { + "source-map": "0.5.7", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" + }, + "dependencies": { + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "dev": true, + "optional": true + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "dev": true, + "optional": true, + "requires": { + "center-align": "0.1.3", + "right-align": "0.1.3", + "wordwrap": "0.0.2" + } + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true, + "optional": true + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "dev": true, + "optional": true, + "requires": { + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", + "window-size": "0.1.0" + } + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "dev": true, + "optional": true + }, "unc-path-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", @@ -4842,6 +10598,41 @@ "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", "dev": true }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "dev": true, + "requires": { + "arr-union": "3.1.0", + "get-value": "2.0.6", + "is-extendable": "0.1.1", + "set-value": "0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + }, + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "dev": true, + "requires": { + "extend-shallow": "2.0.1", + "is-extendable": "0.1.1", + "is-plain-object": "2.0.4", + "to-object-path": "0.3.0" + } + } + } + }, "unique-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz", @@ -4853,6 +10644,78 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz", "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=" }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "0.3.1", + "isobject": "3.0.1" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "2.0.6", + "has-values": "0.1.4", + "isobject": "2.1.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } + } + }, + "unzip2": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/unzip2/-/unzip2-0.2.5.tgz", + "integrity": "sha1-TveleaeMFcUfVQ9qBT2xlBSciZI=", + "dev": true, + "requires": { + "binary": "0.3.0", + "fstream": "0.1.31", + "match-stream": "0.0.2", + "pullstream": "0.4.1", + "readable-stream": "1.0.34", + "setimmediate": "1.0.5" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, "url-join": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/url-join/-/url-join-1.1.0.tgz", @@ -4860,15 +10723,30 @@ "dev": true }, "url-parse": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.2.0.tgz", - "integrity": "sha512-DT1XbYAfmQP65M/mE6OALxmXzZ/z1+e5zk2TcSKe/KiYbNGZxgtttzC0mR/sjopbpOXcbniq7eIKmocJnUWlEw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.3.0.tgz", + "integrity": "sha512-zPvPA3T7P6M+0iNsgX+iAcAz4GshKrowtQBHHc/28tVsBc8jK7VRCNX+2GEcoE6zDB6XqXhcyiUWPVZY6C70Cg==", "dev": true, "requires": { "querystringify": "1.0.0", "requires-port": "1.0.0" } }, + "urlgrey": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/urlgrey/-/urlgrey-0.4.4.tgz", + "integrity": "sha1-iS/pWWCAXoVRnxzUOJ8stMu3ZS8=", + "dev": true + }, + "use": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz", + "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, "user-home": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", @@ -4881,10 +10759,16 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, "uuid": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", - "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", + "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==", "dev": true }, "v8flags": { @@ -4903,13 +10787,13 @@ "dev": true }, "validate-npm-package-license": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", - "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", + "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", "dev": true, "requires": { - "spdx-correct": "1.0.2", - "spdx-expression-parse": "1.0.4" + "spdx-correct": "3.0.0", + "spdx-expression-parse": "3.0.0" } }, "verror": { @@ -4937,7 +10821,7 @@ "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", "dev": true, "requires": { - "clone": "1.0.3", + "clone": "1.0.4", "clone-stats": "0.0.1", "replace-ext": "0.0.1" } @@ -4970,19 +10854,7 @@ "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=", "dev": true, "requires": { - "natives": "1.1.1" - } - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" + "natives": "1.1.3" } }, "through2": { @@ -5008,12 +10880,12 @@ } }, "vinyl-source-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vinyl-source-stream/-/vinyl-source-stream-1.1.0.tgz", - "integrity": "sha1-RMvlEIIFJ53rDFZTwJSiiHk4sas=", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vinyl-source-stream/-/vinyl-source-stream-1.1.2.tgz", + "integrity": "sha1-YrU6E1YQqJbpjKlr7jqH8Aio54A=", "dev": true, "requires": { - "through2": "0.6.5", + "through2": "2.0.3", "vinyl": "0.4.6" }, "dependencies": { @@ -5023,28 +10895,6 @@ "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", "dev": true }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - }, "vinyl": { "version": "0.4.6", "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", @@ -5058,23 +10908,23 @@ } }, "vsce": { - "version": "1.35.0", - "resolved": "https://registry.npmjs.org/vsce/-/vsce-1.35.0.tgz", - "integrity": "sha512-haTQ17f/fD46XjsdZSnDDmHtPuq9dOpQCz4ZI8DZ3gDkkyP260JFR+Brp1TTMK6Hm9pT7bi7DeH3YPkK8PJAiA==", + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/vsce/-/vsce-1.39.0.tgz", + "integrity": "sha512-PkvA4u/o4qhQEUQrQGzNQXHZXBLae1EDmB+w1Z/HLhpX4pqbCSP3GCremiKRV5i9n7UnAC/8YrO2RhZl/x97Hw==", "dev": true, "requires": { "cheerio": "1.0.0-rc.2", - "commander": "2.9.0", + "commander": "2.11.0", "denodeify": "1.2.1", "glob": "7.1.2", - "lodash": "4.17.4", - "markdown-it": "8.4.0", + "lodash": "4.17.5", + "markdown-it": "8.4.1", "mime": "1.6.0", "minimatch": "3.0.4", - "osenv": "0.1.4", + "osenv": "0.1.5", "parse-semver": "1.1.1", "read": "1.0.7", - "semver": "5.4.1", + "semver": "5.5.0", "tmp": "0.0.29", "url-join": "1.1.0", "vso-node-api": "6.1.2-preview", @@ -5083,9 +10933,9 @@ }, "dependencies": { "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==", "dev": true }, "tmp": { @@ -5100,39 +10950,227 @@ } }, "vscode": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.10.tgz", - "integrity": "sha512-MvFXXSGuhw0Q6GC6dQrnRc0ES+63wpttGIoYGBMQnoS9JFCCNC/rWfX0lBCHJyuKL2Q8CYg0ROsMEHbHVwEtVw==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.14.tgz", + "integrity": "sha512-acfn3fzGtTm7UjChAN7/YjsC0qIyJeuSrJwvm6qb7tLN6Geq1FmCz1JnBOc3kaY+HCLjQBAfwG/CsgnasOdXMw==", "dev": true, "requires": { "glob": "7.1.2", "gulp-chmod": "2.0.0", - "gulp-filter": "5.0.1", + "gulp-filter": "5.1.0", "gulp-gunzip": "1.0.0", "gulp-remote-src": "0.4.3", "gulp-symdest": "1.1.0", "gulp-untar": "0.0.6", "gulp-vinyl-zip": "2.1.0", - "mocha": "4.0.1", - "request": "2.83.0", - "semver": "5.4.1", - "source-map-support": "0.5.0", - "url-parse": "1.2.0", - "vinyl-source-stream": "1.1.0" + "mocha": "4.1.0", + "request": "2.85.0", + "semver": "5.5.0", + "source-map-support": "0.5.4", + "url-parse": "1.3.0", + "vinyl-source-stream": "1.1.2" + }, + "dependencies": { + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "dev": true, + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.1.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "boom": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", + "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", + "dev": true, + "requires": { + "hoek": "4.2.1" + } + }, + "cryptiles": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", + "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", + "dev": true, + "requires": { + "boom": "5.2.0" + }, + "dependencies": { + "boom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", + "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", + "dev": true, + "requires": { + "hoek": "4.2.1" + } + } + } + }, + "form-data": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", + "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", + "dev": true, + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.6", + "mime-types": "2.1.18" + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "dev": true, + "requires": { + "ajv": "5.5.2", + "har-schema": "2.0.0" + } + }, + "hawk": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", + "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", + "dev": true, + "requires": { + "boom": "4.3.1", + "cryptiles": "3.1.2", + "hoek": "4.2.1", + "sntp": "2.1.0" + } + }, + "hoek": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", + "dev": true + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "jsprim": "1.4.1", + "sshpk": "1.14.1" + } + }, + "mocha": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", + "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", + "dev": true, + "requires": { + "browser-stdout": "1.3.0", + "commander": "2.11.0", + "debug": "3.1.0", + "diff": "3.3.1", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.3", + "he": "1.1.1", + "mkdirp": "0.5.1", + "supports-color": "4.4.0" + } + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", + "dev": true + }, + "request": { + "version": "2.85.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.85.0.tgz", + "integrity": "sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg==", + "dev": true, + "requires": { + "aws-sign2": "0.7.0", + "aws4": "1.7.0", + "caseless": "0.12.0", + "combined-stream": "1.0.6", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.3.2", + "har-validator": "5.0.3", + "hawk": "6.0.2", + "http-signature": "1.2.0", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.18", + "oauth-sign": "0.8.2", + "performance-now": "2.1.0", + "qs": "6.5.1", + "safe-buffer": "5.1.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.4", + "tunnel-agent": "0.6.0", + "uuid": "3.2.1" + } + }, + "sntp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", + "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", + "dev": true, + "requires": { + "hoek": "4.2.1" + } + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "2.0.0" + } + } } }, "vscode-debugprotocol": { - "version": "1.25.0", - "resolved": "https://registry.npmjs.org/vscode-debugprotocol/-/vscode-debugprotocol-1.25.0.tgz", - "integrity": "sha512-e1EUy/5npqa0NlAwRCUu8A9LnVRf6tkwiPQcCLyUFCC9o2GxcAqH5Va4mqXDoxQ58ar3zODivKQeRb3z1KH7WA==" + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/vscode-debugprotocol/-/vscode-debugprotocol-1.28.0.tgz", + "integrity": "sha512-QM4J8A13jBY9I7OPWXN0ZO1cqydnD4co2j/O81jIj6em8VkmJT4VyJQkq4HmwJe3af+u9+7IYCIEDrowgvKxTA==" }, "vscode-extension-telemetry": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.8.tgz", - "integrity": "sha1-ImG/+Ya2aQpvH3RqRaxb0fhdKeA=", + "version": "0.0.15", + "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.15.tgz", + "integrity": "sha512-Yf6dL9r2x2GISI1xh22XsAaydSTQG/4aBitu8sGBwGr42n2TyOsIXGtXSDgqQBNZgYD6+P1EHqrrzetn9ekWTQ==", "requires": { - "applicationinsights": "0.18.0", - "winreg": "1.2.3" + "applicationinsights": "1.0.1" } }, "vscode-nls": { @@ -5161,10 +11199,18 @@ "isexe": "2.0.0" } }, - "winreg": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.3.tgz", - "integrity": "sha1-k60RayaW2ofVj3JlqPzqUlSpZdU=" + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", + "dev": true, + "optional": true }, "wolfy87-eventemitter": { "version": "5.2.4", @@ -5172,6 +11218,59 @@ "integrity": "sha512-yUOUSIzZxqBeu6VdnigqYHwwjy5N3CRX5XSHh/YcVpy+Qsx+HkHaEWdmdyAr3NvyBYDraOa5EfNIbu47T5QzIA==", "dev": true }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "1.0.1" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "2.1.1" + } + } + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -5179,9 +11278,9 @@ "dev": true }, "xmlbuilder": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-8.2.2.tgz", - "integrity": "sha1-aSSGc0ELS6QuGmE2VR0pIjNap3M=", + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", "dev": true }, "xmldom": { @@ -5196,12 +11295,47 @@ "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", "dev": true }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true }, + "yargs": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.0.0.tgz", + "integrity": "sha512-Rjp+lMYQOWtgqojx1dEWorjCofi1YN7AoFvYV7b1gx/7dAAeuI4kN5SZiEvr0ZmsZTOpDRcCqrpI10L31tFkBw==", + "dev": true, + "requires": { + "cliui": "4.0.0", + "decamelize": "1.2.0", + "find-up": "2.1.0", + "get-caller-file": "1.0.2", + "os-locale": "2.1.0", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "2.1.1", + "which-module": "2.0.0", + "y18n": "3.2.1", + "yargs-parser": "9.0.2" + } + }, + "yargs-parser": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", + "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", + "dev": true, + "requires": { + "camelcase": "4.1.0" + } + }, "yauzl": { "version": "2.9.1", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.9.1.tgz", @@ -5219,6 +11353,67 @@ "requires": { "buffer-crc32": "0.2.13" } + }, + "yn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", + "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", + "dev": true + }, + "zip-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-1.2.0.tgz", + "integrity": "sha1-qLxF9MG0lpnGuQGYuqyqzbzUugQ=", + "dev": true, + "requires": { + "archiver-utils": "1.3.0", + "compress-commons": "1.2.2", + "lodash": "4.17.5", + "readable-stream": "2.3.6" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "lodash": { + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==", + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, + "zone.js": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz", + "integrity": "sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=" } } } diff --git a/package.json b/package.json index 044e9b7d5..e107f6075 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,13 @@ { "name": "csharp", "publisher": "ms-vscode", - "version": "1.14.0", + "version": "1.15.0-beta5", "description": "C# for Visual Studio Code (powered by OmniSharp).", "displayName": "C#", "author": "Microsoft Corporation", "license": "SEE LICENSE IN RuntimeLicenses/license.txt", "icon": "images/csharpIcon.png", - "preview": true, + "preview": false, "bugs": { "url": "https://github.com/OmniSharp/omnisharp-vscode/issues" }, @@ -29,57 +29,114 @@ "vscode:prepublish": "tsc -p ./", "compile": "tsc -p ./ && gulp tslint", "watch": "tsc -watch -p ./", - "test": "npm-run-all test:unit test:integration", - "test:unit": "cross-env CODE_TESTS_PATH=./out/test/unitTests npm run test:runInVsCode", - "test:integration": "npm-run-all test:integration:*", - "test:integration:singleCsproj": "cross-env OSVC_SUITE=singleCsproj npm run test:runSuiteInVsCode", - "test:integration:slnWithCsproj": "cross-env OSVC_SUITE=slnWithCsproj npm run test:runSuiteInVsCode", - "test:runSuiteInVsCode": "cross-env CODE_TESTS_PATH=./out/test/integrationTests CODE_TESTS_WORKSPACE=./test/integrationTests/testAssets/$OSVC_SUITE npm run test:runInVsCode", - "test:runInVsCode": "node ./test/runVsCodeTestsWithAbsolutePaths.js", - "postinstall": "node ./node_modules/vscode/bin/install" + "tdd": "mocha --opts ./mocha.opts --watch --watch-extensions ts test/unitTests/**/*.test.ts*", + "test": "gulp test", + "test:unit": "gulp test:unit", + "test:feature": "gulp test:feature", + "test:integration": "gulp test:integration", + "test:integration:singleCsproj": "gulp test:integration:singleCsproj", + "test:integration:slnWithCsproj": "gulp test:integration:slnWithCsproj", + "test:release": "mocha --opts ./mocha.opts test/releaseTests/**/*.test.ts", + "test:artifacts": "mocha --opts ./mocha.opts test/artifactTests/**/*.test.ts", + "postinstall": "node ./node_modules/vscode/bin/install", + "cov:instrument": "gulp cov:instrument", + "cov:merge": "gulp cov:merge", + "cov:merge-html": "gulp cov:merge-html", + "cov:report": "npm-run-all cov:report:integration cov:report:unit", + "cov:report:unit": "gulp cov:report:unit", + "cov:report:integration": "gulp cov:report:integration", + "unpackage:vsix": "gulp vsix:release:unpackage", + "gulp": "gulp" + }, + "nyc": { + "include": [ + "src/**/*.ts", + "src/**/*.tsx" + ], + "extension": [ + ".ts", + ".tsx" + ], + "require": [ + "ts-node/register", + "source-map-support/register" + ], + "sourceMap": true, + "instrument": true }, "dependencies": { "fs-extra": "^5.0.0", "http-proxy-agent": "^2.0.0", "https-proxy-agent": "^2.1.1", "jsonc-parser": "^1.0.0", - "lodash.debounce": "^4.0.8", "mkdirp": "^0.5.1", + "node-filter-async": "0.0.4", "open": "*", "request-light": "^0.2.0", + "rxjs": "^5.5.6", "semver": "*", "tmp": "0.0.33", "vscode-debugprotocol": "^1.6.1", - "vscode-extension-telemetry": "0.0.11", - "yauzl": "^2.5.0" + "vscode-extension-telemetry": "0.0.15", + "yauzl": "^2.9.1" }, "devDependencies": { - "@types/chai": "4.0.8", + "@types/archiver": "^2.1.1", + "@types/chai": "^4.1.2", "@types/chai-arrays": "1.0.2", - "@types/fs-extra": "4.0.5", - "@types/mkdirp": "0.5.1", - "@types/mocha": "2.2.32", - "@types/node": "8.0.53", - "@types/semver": "5.3.30", + "@types/chai-as-promised": "^7.1.0", + "@types/chai-string": "^1.4.0", + "@types/del": "^3.0.1", + "@types/fs-extra": "^5.0.1", + "@types/gulp": "^3.8.36", + "@types/gulp-mocha": "0.0.32", + "@types/istanbul": "^0.4.30", + "@types/minimist": "^1.2.0", + "@types/mkdirp": "^0.5.2", + "@types/mocha": "^2.2.48", + "@types/node": "^9.4.7", + "@types/semver": "^5.5.0", "@types/tmp": "0.0.33", - "async-file": "2.0.2", + "@types/yauzl": "^2.9.0", + "archiver": "^2.1.1", + "async-child-process": "^1.1.1", + "async-file": "^2.0.2", + "async-shelljs": "^0.1.2", "chai": "4.1.2", "chai-arrays": "2.0.0", + "chai-as-promised": "7.1.1", "chai-fs": "2.0.0", - "cross-env": "5.1.1", + "chai-string": "^1.4.0", + "codecov": "^3.0.0", + "copyfiles": "^2.0.0", + "cross-env": "^5.1.4", "del": "3.0.0", + "get-port": "^3.2.0", + "glob-promise": "^3.4.0", "gulp": "3.9.1", - "gulp-mocha": "4.3.1", - "gulp-tslint": "8.1.2", - "mocha": "4.0.1", - "npm-run-all": "4.1.1", - "plist": "2.0.1", - "tslint": "5.8.0", - "tslint-microsoft-contrib": "5.0.1", - "tslint-no-unused-expression-chai": "0.0.3", - "typescript": "2.6.2", - "vsce": "^1.32.0", - "vscode": "^1.1.8" + "gulp-mocha": "^5.0.0", + "gulp-sequence": "^1.0.0", + "gulp-tslint": "^8.1.3", + "istanbul": "^0.4.5", + "istanbul-combine": "^0.3.0", + "ltcdr": "^2.2.1", + "minimist": "^1.2.0", + "mocha": "^5.0.4", + "mocha-typescript": "^1.1.12", + "mock-http-server": "^0.2.0", + "npm-run-all": "^4.1.2", + "nyc": "^11.6.0", + "plist": "^3.0.1", + "remap-istanbul": "^0.11.0", + "source-map-support": "^0.5.4", + "ts-node": "^5.0.1", + "tslint": "^5.9.1", + "tslint-microsoft-contrib": "^5.0.3", + "tslint-no-unused-expression-chai": "^0.1.3", + "typescript": "^2.7.2", + "unzip2": "^0.2.5", + "vsce": "^1.39.0", + "vscode": "^1.1.14" }, "runtimeDependencies": [ { @@ -93,7 +150,8 @@ "architectures": [ "x86" ], - "installTestPath": "./.omnisharp/OmniSharp.exe" + "installTestPath": "./.omnisharp/OmniSharp.exe", + "platformId": "win-x86" }, { "description": "OmniSharp for Windows (.NET 4.6 / x64)", @@ -106,7 +164,8 @@ "architectures": [ "x86_64" ], - "installTestPath": "./.omnisharp/OmniSharp.exe" + "installTestPath": "./.omnisharp/OmniSharp.exe", + "platformId": "win-x64" }, { "description": "OmniSharp for OSX", @@ -120,7 +179,8 @@ "./mono.osx", "./run" ], - "installTestPath": "./.omnisharp/mono.osx" + "installTestPath": "./.omnisharp/mono.osx", + "platformId": "osx" }, { "description": "OmniSharp for Linux (x86)", @@ -138,7 +198,8 @@ "./mono.linux-x86", "./run" ], - "installTestPath": "./.omnisharp/mono.linux-x86" + "installTestPath": "./.omnisharp/mono.linux-x86", + "platformId": "linux-x86" }, { "description": "OmniSharp for Linux (x64)", @@ -155,12 +216,13 @@ "./mono.linux-x86_64", "./run" ], - "installTestPath": "./.omnisharp/mono.linux-x86_64" + "installTestPath": "./.omnisharp/mono.linux-x86_64", + "platformId": "linux-x64" }, { "description": ".NET Core Debugger (Windows / x64)", - "url": "https://download.visualstudio.microsoft.com/download/pr/11522728/3d79abf5bc635c3b55ad2ee590c1eb0e/coreclr-debug-win7-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-14-7/coreclr-debug-win7-x64.zip", + "url": "https://download.visualstudio.microsoft.com/download/pr/12149320/af1529a62f43fb8a922eccf750bdf9f7/coreclr-debug-win7-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-15-1/coreclr-debug-win7-x64.zip", "installPath": ".debugger", "platforms": [ "win32" @@ -172,8 +234,8 @@ }, { "description": ".NET Core Debugger (macOS / x64)", - "url": "https://download.visualstudio.microsoft.com/download/pr/11522728/3d79abf5bc635c3b55ad2ee590c1eb0e/coreclr-debug-osx-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-14-7/coreclr-debug-osx-x64.zip", + "url": "https://download.visualstudio.microsoft.com/download/pr/12149320/af1529a62f43fb8a922eccf750bdf9f7/coreclr-debug-osx-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-15-1/coreclr-debug-osx-x64.zip", "installPath": ".debugger", "platforms": [ "darwin" @@ -189,8 +251,8 @@ }, { "description": ".NET Core Debugger (linux / x64)", - "url": "https://download.visualstudio.microsoft.com/download/pr/11522728/3d79abf5bc635c3b55ad2ee590c1eb0e/coreclr-debug-linux-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-14-7/coreclr-debug-linux-x64.zip", + "url": "https://download.visualstudio.microsoft.com/download/pr/12149320/af1529a62f43fb8a922eccf750bdf9f7/coreclr-debug-linux-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-15-1/coreclr-debug-linux-x64.zip", "installPath": ".debugger", "platforms": [ "linux" @@ -263,14 +325,6 @@ "description": "Optional flag to only show user code.", "default": true }, - "symbolPath": { - "type": "array", - "description": "Array of directories to use to search for .pdb files. These directories will be searched in addition to the default locations -- next to the module and the path where the pdb was originally dropped to. Example: '[ \"/Volumes/symbols\" ]", - "items": { - "type": "string" - }, - "default": [] - }, "requireExactSource": { "type": "boolean", "description": "Optional flag to require current source code to match the pdb.", @@ -281,11 +335,6 @@ "description": "Optional flag to enable stepping over Properties and Operators.", "default": true }, - "debugServer": { - "type": "number", - "description": "For debug extension development only: if a port is specified VS Code tries to connect to a debug adapter running in server mode", - "default": 4711 - }, "logging": { "description": "Optional flags to determine what types of messages should be logged to the output window.", "type": "object", @@ -319,6 +368,107 @@ } } }, + "suppressJITOptimizations": { + "type": "boolean", + "description": "If true, when an optimized module (.dll compiled in the Release configuration) loads in the target process, the debugger will ask the Just-In-Time compiler to generate code with optimizations disabled. For more information: https://aka.ms/VSCode-CS-LaunchJson#suppress-jit-optimizations", + "default": false + }, + "symbolOptions": { + "description": "Options to control how symbols (.pdb files) are found and loaded.", + "default": { + "searchPaths": [], + "searchMicrosoftSymbolServer": false + }, + "type": "object", + "properties": { + "searchPaths": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Array of symbol server URLs (example: http\u200b://MyExampleSymbolServer) or directories (example: /build/symbols) to search for .pdb files. These directories will be searched in addition to the default locations -- next to the module and the path where the pdb was originally dropped to.", + "default": [] + }, + "searchMicrosoftSymbolServer": { + "type": "boolean", + "description": "If 'true' the Microsoft Symbol server (https\u200b://msdl.microsoft.com\u200b/download/symbols) is added to the symbols search path. If unspecified, this option defaults to 'false'.", + "default": false + }, + "cachePath": { + "type": "string", + "description": "Directory where symbols downloaded from symbol servers should be cached. If unspecified, on Windows the debugger will default to %TEMP%\\SymbolCache, and on Linux and macOS the debugger will default to ~/.vsdbg/SymbolCache.", + "default": "~/.vsdbg/SymbolCache" + }, + "moduleFilter": { + "description": "Provides options to control which modules (.dll files) the debugger will attempt to load symbols (.pdb files) for.", + "default": { + "mode": "loadAllButExcluded", + "excludedModules": [] + }, + "type": "object", + "required": [ + "mode" + ], + "properties": { + "mode": { + "type": "string", + "enum": [ + "loadAllButExcluded", + "loadOnlyIncluded" + ], + "enumDescriptions": [ + "Load symbols for all modules unless the module is in the 'excludedModules' array.", + "Do not attempt to load symbols for ANY module unless it is in the 'includedModules' array, or it is included through the 'includeSymbolsNextToModules' setting." + ], + "description": "Controls which of the two basic operating modes the module filter operates in.", + "default": "loadAllButExcluded" + }, + "excludedModules": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Array of modules that the debugger should NOT load symbols for. Wildcards (example: MyCompany.*.dll) are supported.\n\nThis property is ignored unless 'mode' is set to 'loadAllButExcluded'.", + "default": [] + }, + "includedModules": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Array of modules that the debugger should load symbols for. Wildcards (example: MyCompany.*.dll) are supported.\n\nThis property is ignored unless 'mode' is set to 'loadOnlyIncluded'.", + "default": [ + "MyExampleModule.dll" + ] + }, + "includeSymbolsNextToModules": { + "type": "boolean", + "description": "If true, for any module NOT in the 'includedModules' array, the debugger will still check next to the module itself and the launching executable, but it will not check paths on the symbol search list. This option defaults to 'true'.\n\nThis property is ignored unless 'mode' is set to 'loadOnlyIncluded'.", + "default": true + } + } + } + } + }, + "sourceLinkOptions": { + "description": "Options to control how Source Link connects to web servers. For more information: https://aka.ms/VSCode-CS-LaunchJson#source-link-options", + "default": { + "*": { + "enabled": true + } + }, + "type": "object", + "additionalItems": { + "type": "object", + "properties": { + "enabled": { + "title": "boolean", + "description": "Is Source Link enabled for this URL? If unspecified, this option defaults to 'true'.", + "default": "true" + } + } + } + }, "type": { "type": "string", "enum": [ @@ -327,6 +477,11 @@ ], "description": "Type type of code to debug. Can be either 'coreclr' for .NET Core debugging, or 'clr' for Desktop .NET Framework. 'clr' only works on Windows as the Desktop framework is Windows-only.", "default": "coreclr" + }, + "debugServer": { + "type": "number", + "description": "For debug extension development only: if a port is specified VS Code tries to connect to a debug adapter running in server mode", + "default": 4711 } } }, @@ -361,7 +516,7 @@ "null" ], "default": null, - "description": "Specifies the full path to the OmniSharp server." + "description": "Specifies the path to OmniSharp. This can be the absolute path to an OmniSharp executable, a specific version number, or \"latest\". If a version number or \"latest\" is specified, the appropriate version of OmniSharp will be downloaded on your behalf." }, "omnisharp.useMono": { "type": "boolean", @@ -667,14 +822,6 @@ "description": "Optional flag to only show user code.", "default": true }, - "symbolPath": { - "type": "array", - "description": "Array of directories to use to search for .pdb files. These directories will be searched in addition to the default locations -- next to the module and the path where the pdb was originally dropped to. Example: '[ \"/Volumes/symbols\" ]", - "items": { - "type": "string" - }, - "default": [] - }, "requireExactSource": { "type": "boolean", "description": "Optional flag to require current source code to match the pdb.", @@ -934,6 +1081,107 @@ } } } + }, + "suppressJITOptimizations": { + "type": "boolean", + "description": "If true, when an optimized module (.dll compiled in the Release configuration) loads in the target process, the debugger will ask the Just-In-Time compiler to generate code with optimizations disabled. For more information: https://aka.ms/VSCode-CS-LaunchJson#suppress-jit-optimizations", + "default": false + }, + "symbolOptions": { + "description": "Options to control how symbols (.pdb files) are found and loaded.", + "default": { + "searchPaths": [], + "searchMicrosoftSymbolServer": false + }, + "type": "object", + "properties": { + "searchPaths": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Array of symbol server URLs (example: http\u200b://MyExampleSymbolServer) or directories (example: /build/symbols) to search for .pdb files. These directories will be searched in addition to the default locations -- next to the module and the path where the pdb was originally dropped to.", + "default": [] + }, + "searchMicrosoftSymbolServer": { + "type": "boolean", + "description": "If 'true' the Microsoft Symbol server (https\u200b://msdl.microsoft.com\u200b/download/symbols) is added to the symbols search path. If unspecified, this option defaults to 'false'.", + "default": false + }, + "cachePath": { + "type": "string", + "description": "Directory where symbols downloaded from symbol servers should be cached. If unspecified, on Windows the debugger will default to %TEMP%\\SymbolCache, and on Linux and macOS the debugger will default to ~/.vsdbg/SymbolCache.", + "default": "~/.vsdbg/SymbolCache" + }, + "moduleFilter": { + "description": "Provides options to control which modules (.dll files) the debugger will attempt to load symbols (.pdb files) for.", + "default": { + "mode": "loadAllButExcluded", + "excludedModules": [] + }, + "type": "object", + "required": [ + "mode" + ], + "properties": { + "mode": { + "type": "string", + "enum": [ + "loadAllButExcluded", + "loadOnlyIncluded" + ], + "enumDescriptions": [ + "Load symbols for all modules unless the module is in the 'excludedModules' array.", + "Do not attempt to load symbols for ANY module unless it is in the 'includedModules' array, or it is included through the 'includeSymbolsNextToModules' setting." + ], + "description": "Controls which of the two basic operating modes the module filter operates in.", + "default": "loadAllButExcluded" + }, + "excludedModules": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Array of modules that the debugger should NOT load symbols for. Wildcards (example: MyCompany.*.dll) are supported.\n\nThis property is ignored unless 'mode' is set to 'loadAllButExcluded'.", + "default": [] + }, + "includedModules": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Array of modules that the debugger should load symbols for. Wildcards (example: MyCompany.*.dll) are supported.\n\nThis property is ignored unless 'mode' is set to 'loadOnlyIncluded'.", + "default": [ + "MyExampleModule.dll" + ] + }, + "includeSymbolsNextToModules": { + "type": "boolean", + "description": "If true, for any module NOT in the 'includedModules' array, the debugger will still check next to the module itself and the launching executable, but it will not check paths on the symbol search list. This option defaults to 'true'.\n\nThis property is ignored unless 'mode' is set to 'loadOnlyIncluded'.", + "default": true + } + } + } + } + }, + "sourceLinkOptions": { + "description": "Options to control how Source Link connects to web servers. For more information: https://aka.ms/VSCode-CS-LaunchJson#source-link-options", + "default": { + "*": { + "enabled": true + } + }, + "type": "object", + "additionalItems": { + "type": "object", + "properties": { + "enabled": { + "title": "boolean", + "description": "Is Source Link enabled for this URL? If unspecified, this option defaults to 'true'.", + "default": "true" + } + } + } } } }, @@ -975,14 +1223,6 @@ "description": "Optional flag to only show user code.", "default": true }, - "symbolPath": { - "type": "array", - "description": "Array of directories to use to search for .pdb files. These directories will be searched in addition to the default locations -- next to the module and the path where the pdb was originally dropped to. Example: '[ \"/Volumes/symbols\" ]", - "items": { - "type": "string" - }, - "default": [] - }, "requireExactSource": { "type": "boolean", "description": "Optional flag to require current source code to match the pdb.", @@ -1242,6 +1482,107 @@ } } } + }, + "suppressJITOptimizations": { + "type": "boolean", + "description": "If true, when an optimized module (.dll compiled in the Release configuration) loads in the target process, the debugger will ask the Just-In-Time compiler to generate code with optimizations disabled. For more information: https://aka.ms/VSCode-CS-LaunchJson#suppress-jit-optimizations", + "default": false + }, + "symbolOptions": { + "description": "Options to control how symbols (.pdb files) are found and loaded.", + "default": { + "searchPaths": [], + "searchMicrosoftSymbolServer": false + }, + "type": "object", + "properties": { + "searchPaths": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Array of symbol server URLs (example: http\u200b://MyExampleSymbolServer) or directories (example: /build/symbols) to search for .pdb files. These directories will be searched in addition to the default locations -- next to the module and the path where the pdb was originally dropped to.", + "default": [] + }, + "searchMicrosoftSymbolServer": { + "type": "boolean", + "description": "If 'true' the Microsoft Symbol server (https\u200b://msdl.microsoft.com\u200b/download/symbols) is added to the symbols search path. If unspecified, this option defaults to 'false'.", + "default": false + }, + "cachePath": { + "type": "string", + "description": "Directory where symbols downloaded from symbol servers should be cached. If unspecified, on Windows the debugger will default to %TEMP%\\SymbolCache, and on Linux and macOS the debugger will default to ~/.vsdbg/SymbolCache.", + "default": "~/.vsdbg/SymbolCache" + }, + "moduleFilter": { + "description": "Provides options to control which modules (.dll files) the debugger will attempt to load symbols (.pdb files) for.", + "default": { + "mode": "loadAllButExcluded", + "excludedModules": [] + }, + "type": "object", + "required": [ + "mode" + ], + "properties": { + "mode": { + "type": "string", + "enum": [ + "loadAllButExcluded", + "loadOnlyIncluded" + ], + "enumDescriptions": [ + "Load symbols for all modules unless the module is in the 'excludedModules' array.", + "Do not attempt to load symbols for ANY module unless it is in the 'includedModules' array, or it is included through the 'includeSymbolsNextToModules' setting." + ], + "description": "Controls which of the two basic operating modes the module filter operates in.", + "default": "loadAllButExcluded" + }, + "excludedModules": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Array of modules that the debugger should NOT load symbols for. Wildcards (example: MyCompany.*.dll) are supported.\n\nThis property is ignored unless 'mode' is set to 'loadAllButExcluded'.", + "default": [] + }, + "includedModules": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Array of modules that the debugger should load symbols for. Wildcards (example: MyCompany.*.dll) are supported.\n\nThis property is ignored unless 'mode' is set to 'loadOnlyIncluded'.", + "default": [ + "MyExampleModule.dll" + ] + }, + "includeSymbolsNextToModules": { + "type": "boolean", + "description": "If true, for any module NOT in the 'includedModules' array, the debugger will still check next to the module itself and the launching executable, but it will not check paths on the symbol search list. This option defaults to 'true'.\n\nThis property is ignored unless 'mode' is set to 'loadOnlyIncluded'.", + "default": true + } + } + } + } + }, + "sourceLinkOptions": { + "description": "Options to control how Source Link connects to web servers. For more information: https://aka.ms/VSCode-CS-LaunchJson#source-link-options", + "default": { + "*": { + "enabled": true + } + }, + "type": "object", + "additionalItems": { + "type": "object", + "properties": { + "enabled": { + "title": "boolean", + "description": "Is Source Link enabled for this URL? If unspecified, this option defaults to 'true'.", + "default": "true" + } + } + } } } } @@ -1543,14 +1884,6 @@ "description": "Optional flag to only show user code.", "default": true }, - "symbolPath": { - "type": "array", - "description": "Array of directories to use to search for .pdb files. These directories will be searched in addition to the default locations -- next to the module and the path where the pdb was originally dropped to. Example: '[ \"/Volumes/symbols\" ]", - "items": { - "type": "string" - }, - "default": [] - }, "requireExactSource": { "type": "boolean", "description": "Optional flag to require current source code to match the pdb.", @@ -1810,6 +2143,107 @@ } } } + }, + "suppressJITOptimizations": { + "type": "boolean", + "description": "If true, when an optimized module (.dll compiled in the Release configuration) loads in the target process, the debugger will ask the Just-In-Time compiler to generate code with optimizations disabled. For more information: https://aka.ms/VSCode-CS-LaunchJson#suppress-jit-optimizations", + "default": false + }, + "symbolOptions": { + "description": "Options to control how symbols (.pdb files) are found and loaded.", + "default": { + "searchPaths": [], + "searchMicrosoftSymbolServer": false + }, + "type": "object", + "properties": { + "searchPaths": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Array of symbol server URLs (example: http\u200b://MyExampleSymbolServer) or directories (example: /build/symbols) to search for .pdb files. These directories will be searched in addition to the default locations -- next to the module and the path where the pdb was originally dropped to.", + "default": [] + }, + "searchMicrosoftSymbolServer": { + "type": "boolean", + "description": "If 'true' the Microsoft Symbol server (https\u200b://msdl.microsoft.com\u200b/download/symbols) is added to the symbols search path. If unspecified, this option defaults to 'false'.", + "default": false + }, + "cachePath": { + "type": "string", + "description": "Directory where symbols downloaded from symbol servers should be cached. If unspecified, on Windows the debugger will default to %TEMP%\\SymbolCache, and on Linux and macOS the debugger will default to ~/.vsdbg/SymbolCache.", + "default": "~/.vsdbg/SymbolCache" + }, + "moduleFilter": { + "description": "Provides options to control which modules (.dll files) the debugger will attempt to load symbols (.pdb files) for.", + "default": { + "mode": "loadAllButExcluded", + "excludedModules": [] + }, + "type": "object", + "required": [ + "mode" + ], + "properties": { + "mode": { + "type": "string", + "enum": [ + "loadAllButExcluded", + "loadOnlyIncluded" + ], + "enumDescriptions": [ + "Load symbols for all modules unless the module is in the 'excludedModules' array.", + "Do not attempt to load symbols for ANY module unless it is in the 'includedModules' array, or it is included through the 'includeSymbolsNextToModules' setting." + ], + "description": "Controls which of the two basic operating modes the module filter operates in.", + "default": "loadAllButExcluded" + }, + "excludedModules": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Array of modules that the debugger should NOT load symbols for. Wildcards (example: MyCompany.*.dll) are supported.\n\nThis property is ignored unless 'mode' is set to 'loadAllButExcluded'.", + "default": [] + }, + "includedModules": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Array of modules that the debugger should load symbols for. Wildcards (example: MyCompany.*.dll) are supported.\n\nThis property is ignored unless 'mode' is set to 'loadOnlyIncluded'.", + "default": [ + "MyExampleModule.dll" + ] + }, + "includeSymbolsNextToModules": { + "type": "boolean", + "description": "If true, for any module NOT in the 'includedModules' array, the debugger will still check next to the module itself and the launching executable, but it will not check paths on the symbol search list. This option defaults to 'true'.\n\nThis property is ignored unless 'mode' is set to 'loadOnlyIncluded'.", + "default": true + } + } + } + } + }, + "sourceLinkOptions": { + "description": "Options to control how Source Link connects to web servers. For more information: https://aka.ms/VSCode-CS-LaunchJson#source-link-options", + "default": { + "*": { + "enabled": true + } + }, + "type": "object", + "additionalItems": { + "type": "object", + "properties": { + "enabled": { + "title": "boolean", + "description": "Is Source Link enabled for this URL? If unspecified, this option defaults to 'true'.", + "default": "true" + } + } + } } } }, @@ -1851,14 +2285,6 @@ "description": "Optional flag to only show user code.", "default": true }, - "symbolPath": { - "type": "array", - "description": "Array of directories to use to search for .pdb files. These directories will be searched in addition to the default locations -- next to the module and the path where the pdb was originally dropped to. Example: '[ \"/Volumes/symbols\" ]", - "items": { - "type": "string" - }, - "default": [] - }, "requireExactSource": { "type": "boolean", "description": "Optional flag to require current source code to match the pdb.", @@ -2118,6 +2544,107 @@ } } } + }, + "suppressJITOptimizations": { + "type": "boolean", + "description": "If true, when an optimized module (.dll compiled in the Release configuration) loads in the target process, the debugger will ask the Just-In-Time compiler to generate code with optimizations disabled. For more information: https://aka.ms/VSCode-CS-LaunchJson#suppress-jit-optimizations", + "default": false + }, + "symbolOptions": { + "description": "Options to control how symbols (.pdb files) are found and loaded.", + "default": { + "searchPaths": [], + "searchMicrosoftSymbolServer": false + }, + "type": "object", + "properties": { + "searchPaths": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Array of symbol server URLs (example: http\u200b://MyExampleSymbolServer) or directories (example: /build/symbols) to search for .pdb files. These directories will be searched in addition to the default locations -- next to the module and the path where the pdb was originally dropped to.", + "default": [] + }, + "searchMicrosoftSymbolServer": { + "type": "boolean", + "description": "If 'true' the Microsoft Symbol server (https\u200b://msdl.microsoft.com\u200b/download/symbols) is added to the symbols search path. If unspecified, this option defaults to 'false'.", + "default": false + }, + "cachePath": { + "type": "string", + "description": "Directory where symbols downloaded from symbol servers should be cached. If unspecified, on Windows the debugger will default to %TEMP%\\SymbolCache, and on Linux and macOS the debugger will default to ~/.vsdbg/SymbolCache.", + "default": "~/.vsdbg/SymbolCache" + }, + "moduleFilter": { + "description": "Provides options to control which modules (.dll files) the debugger will attempt to load symbols (.pdb files) for.", + "default": { + "mode": "loadAllButExcluded", + "excludedModules": [] + }, + "type": "object", + "required": [ + "mode" + ], + "properties": { + "mode": { + "type": "string", + "enum": [ + "loadAllButExcluded", + "loadOnlyIncluded" + ], + "enumDescriptions": [ + "Load symbols for all modules unless the module is in the 'excludedModules' array.", + "Do not attempt to load symbols for ANY module unless it is in the 'includedModules' array, or it is included through the 'includeSymbolsNextToModules' setting." + ], + "description": "Controls which of the two basic operating modes the module filter operates in.", + "default": "loadAllButExcluded" + }, + "excludedModules": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Array of modules that the debugger should NOT load symbols for. Wildcards (example: MyCompany.*.dll) are supported.\n\nThis property is ignored unless 'mode' is set to 'loadAllButExcluded'.", + "default": [] + }, + "includedModules": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Array of modules that the debugger should load symbols for. Wildcards (example: MyCompany.*.dll) are supported.\n\nThis property is ignored unless 'mode' is set to 'loadOnlyIncluded'.", + "default": [ + "MyExampleModule.dll" + ] + }, + "includeSymbolsNextToModules": { + "type": "boolean", + "description": "If true, for any module NOT in the 'includedModules' array, the debugger will still check next to the module itself and the launching executable, but it will not check paths on the symbol search list. This option defaults to 'true'.\n\nThis property is ignored unless 'mode' is set to 'loadOnlyIncluded'.", + "default": true + } + } + } + } + }, + "sourceLinkOptions": { + "description": "Options to control how Source Link connects to web servers. For more information: https://aka.ms/VSCode-CS-LaunchJson#source-link-options", + "default": { + "*": { + "enabled": true + } + }, + "type": "object", + "additionalItems": { + "type": "object", + "properties": { + "enabled": { + "title": "boolean", + "description": "Is Source Link enabled for this URL? If unspecified, this option defaults to 'true'.", + "default": "true" + } + } + } } } } diff --git a/release.vscodeignore b/release.vscodeignore new file mode 100644 index 000000000..43eb03177 --- /dev/null +++ b/release.vscodeignore @@ -0,0 +1,37 @@ +.debugger/** +.logs/** +.nyc_output/** +.omnisharp/** +.rpt2_cache/** +.travis/** +.vscode/** +.vscode-test/** +coverage/** +out/test/** +src/** +tasks/** +test/** +typings/** +vsix/** + +**/*.map +*.vsix + +.editorconfig +.gitignore +.travis.yml +gulpfile.ts +install.Lock +ISSUE_TEMPLATE +mocha.opts +*.vscodeignore +package-lock.json +package.json +test-plan.md +tsconfig.json +tslint.json +wallaby.js + + ++RuntimeLicenses/dependencies/* +coreclr-debug/install.log \ No newline at end of file diff --git a/src/CSharpExtDownloader.ts b/src/CSharpExtDownloader.ts index 27b58ef77..03c738878 100644 --- a/src/CSharpExtDownloader.ts +++ b/src/CSharpExtDownloader.ts @@ -3,138 +3,61 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as vscode from 'vscode'; -import TelemetryReporter from 'vscode-extension-telemetry'; import * as util from './common'; -import { Logger } from './logger'; -import { PackageManager, Status, PackageError } from './packages'; import { PlatformInformation } from './platform'; +import { PackageInstallation, LogPlatformInfo, InstallationSuccess, InstallationFailure } from './omnisharp/loggingEvents'; +import { EventStream } from './EventStream'; +import { DownloadAndInstallPackages } from './packageManager/PackageManager'; +import { Package } from './packageManager/Package'; +import { NetworkSettingsProvider } from './NetworkSettings'; +import { ResolveFilePaths } from './packageManager/PackageFilePathResolver'; /* * Class used to download the runtime dependencies of the C# Extension */ -export class CSharpExtDownloader -{ +export class CSharpExtDownloader { + public constructor( - private channel: vscode.OutputChannel, - private logger: Logger, - private reporter: TelemetryReporter /* optional */, - private packageJSON: any) { + private networkSettingsProvider: NetworkSettingsProvider, + private eventStream: EventStream, + private packageJSON: any, + private platformInfo: PlatformInformation) { } - public installRuntimeDependencies(): Promise { - this.logger.append('Installing C# dependencies...'); - this.channel.show(); + public async installRuntimeDependencies(): Promise { + this.eventStream.post(new PackageInstallation("C# dependencies")); + let installationStage = 'touchBeginFile'; - let statusItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right); - let status: Status = { - setMessage: text => { - statusItem.text = text; - statusItem.show(); - }, - setDetail: text => { - statusItem.tooltip = text; - statusItem.show(); + try { + await util.touchInstallFile(util.InstallFileType.Begin); + // Display platform information and RID + this.eventStream.post(new LogPlatformInfo(this.platformInfo)); + let runTimeDependencies = GetRunTimeDependenciesPackages(this.packageJSON); + runTimeDependencies.forEach(pkg => ResolveFilePaths(pkg)); + installationStage = 'downloadAndInstallPackages'; + await DownloadAndInstallPackages(runTimeDependencies, this.networkSettingsProvider, this.platformInfo, this.eventStream); + installationStage = 'touchLockFile'; + await util.touchInstallFile(util.InstallFileType.Lock); + this.eventStream.post(new InstallationSuccess()); + return true; + } + catch (error) { + this.eventStream.post(new InstallationFailure(installationStage, error)); + return false; + } + finally { + try { + util.deleteInstallFile(util.InstallFileType.Begin); } - }; - - // Sends "AcquisitionStart" telemetry to indicate an acquisition started. - if (this.reporter) { - this.reporter.sendTelemetryEvent("AcquisitionStart"); + catch (error) { } } - - let platformInfo: PlatformInformation; - let packageManager: PackageManager; - let installationStage = 'touchBeginFile'; - let errorMessage = ''; - let success = false; - - let telemetryProps: any = {}; - - return util.touchInstallFile(util.InstallFileType.Begin) - .then(() => { - installationStage = 'getPlatformInfo'; - return PlatformInformation.GetCurrent(); - }) - .then(info => { - platformInfo = info; - packageManager = new PackageManager(info, this.packageJSON); - this.logger.appendLine(); - - // Display platform information and RID followed by a blank line - this.logger.appendLine(`Platform: ${info.toString()}`); - this.logger.appendLine(); - - installationStage = 'downloadPackages'; - - const config = vscode.workspace.getConfiguration(); - const proxy = config.get('http.proxy'); - const strictSSL = config.get('http.proxyStrictSSL', true); - - return packageManager.DownloadPackages(this.logger, status, proxy, strictSSL); - }) - .then(() => { - this.logger.appendLine(); - - installationStage = 'installPackages'; - return packageManager.InstallPackages(this.logger, status); - }) - .then(() => { - installationStage = 'touchLockFile'; - return util.touchInstallFile(util.InstallFileType.Lock); - }) - .then(() => { - installationStage = 'completeSuccess'; - success = true; - }) - .catch(error => { - if (error instanceof PackageError) { - // we can log the message in a PackageError to telemetry as we do not put PII in PackageError messages - telemetryProps['error.message'] = error.message; - - if (error.innerError) { - errorMessage = error.innerError.toString(); - } else { - errorMessage = error.message; - } - - if (error.pkg) { - telemetryProps['error.packageUrl'] = error.pkg.url; - } - - } else { - // do not log raw errorMessage in telemetry as it is likely to contain PII. - errorMessage = error.toString(); - } - - this.logger.appendLine(`Failed at stage: ${installationStage}`); - this.logger.appendLine(errorMessage); - }) - .then(() => { - telemetryProps['installStage'] = installationStage; - telemetryProps['platform.architecture'] = platformInfo.architecture; - telemetryProps['platform.platform'] = platformInfo.platform; - if (platformInfo.distribution) { - telemetryProps['platform.distribution'] = platformInfo.distribution.toTelemetryString(); - } - - if (this.reporter) { - this.reporter.sendTelemetryEvent('Acquisition', telemetryProps); - } - - this.logger.appendLine(); - installationStage = ''; - this.logger.appendLine('Finished'); - - statusItem.dispose(); - }) - .then(() => { - // We do this step at the end so that we clean up the begin file in the case that we hit above catch block - // Attach a an empty catch to this so that errors here do not propogate - return util.deleteInstallFile(util.InstallFileType.Begin).catch((error) => { }); - }).then(() => { - return success; - }); - } } + +export function GetRunTimeDependenciesPackages(packageJSON: any): Package[] { + if (packageJSON.runtimeDependencies) { + return JSON.parse(JSON.stringify(packageJSON.runtimeDependencies)); + } + + throw new Error("No runtime dependencies found"); +} \ No newline at end of file diff --git a/src/CSharpExtensionExports.ts b/src/CSharpExtensionExports.ts new file mode 100644 index 000000000..f5eefaf41 --- /dev/null +++ b/src/CSharpExtensionExports.ts @@ -0,0 +1,8 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + + export default interface CSharpExtensionExports { + initializationFinished: () => Promise; + } \ No newline at end of file diff --git a/src/CompositeDisposable.ts b/src/CompositeDisposable.ts new file mode 100644 index 000000000..ddecd2725 --- /dev/null +++ b/src/CompositeDisposable.ts @@ -0,0 +1,37 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Subscription } from "rxjs/Subscription"; +import Disposable from "./Disposable"; + +export default class CompositeDisposable extends Disposable { + private disposables = new Subscription(); + + constructor (...disposables: Disposable[]){ + super(() => this.disposables.unsubscribe()); + + for (const disposable of disposables) { + if (disposable) { + this.disposables.add(disposable.dispose); + } + else { + throw new Error("null disposables are not supported"); + } + } + } + + public add(disposable: Disposable | {(): void}) { + if (!disposable) { + throw new Error("disposable cannot be null"); + } + + const actualDisposable = + disposable.constructor.name === Disposable.name + ? disposable + : new Disposable(<{(): void}>disposable); + + this.disposables.add(actualDisposable.dispose); + } +} diff --git a/src/CreateTmpAsset.ts b/src/CreateTmpAsset.ts new file mode 100644 index 000000000..adfd93ffb --- /dev/null +++ b/src/CreateTmpAsset.ts @@ -0,0 +1,59 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import * as tmp from 'tmp'; +import { rimraf } from 'async-file'; +import { NestedError } from './NestedError'; + +export async function CreateTmpFile(): Promise { + const tmpFile = await new Promise((resolve, reject) => { + tmp.file({ prefix: 'package-' }, (err, path, fd, cleanupCallback) => { + if (err) { + return reject(new NestedError('Error from tmp.file', err)); + } + if (fd == 0) { + return reject(new NestedError("Temporary package file unavailable")); + } + + resolve({ name: path, fd: fd, removeCallback: cleanupCallback }); + }); + }); + + return { + fd: tmpFile.fd, + name: tmpFile.name, + dispose: tmpFile.removeCallback + }; +} + +export async function CreateTmpDir(unsafeCleanup: boolean): Promise { + const tmpDir = await new Promise((resolve, reject) => { + tmp.dir({ unsafeCleanup }, (err, path, cleanupCallback) => { + if (err) { + return reject(new NestedError('Error from tmp.dir', err)); + } + + resolve({ name: path, removeCallback: cleanupCallback }); + }); + }); + + return { + fd: tmpDir.fd, + name: tmpDir.name, + dispose: () => { + if (unsafeCleanup) { + rimraf(tmpDir.name);//to delete directories that have folders inside them + } + else { + tmpDir.removeCallback(); + } + } + }; +} + +export interface TmpAsset { + fd: number; + name: string; + dispose: () => void; +} \ No newline at end of file diff --git a/src/Disposable.ts b/src/Disposable.ts new file mode 100644 index 000000000..83a08dc32 --- /dev/null +++ b/src/Disposable.ts @@ -0,0 +1,20 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +export default class Disposable { + private onDispose: { (): void }; + + constructor(onDispose: { (): void }) { + if (!onDispose) { + throw new Error("onDispose cannot be null or empty."); + } + + this.onDispose = onDispose; + } + + public dispose = (): void => { + this.onDispose(); + } +} diff --git a/src/EventStream.ts b/src/EventStream.ts new file mode 100644 index 000000000..1fb988ccf --- /dev/null +++ b/src/EventStream.ts @@ -0,0 +1,22 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import { Subject } from "rxjs/Subject"; +import { BaseEvent } from "./omnisharp/loggingEvents"; + +export class EventStream { + private sink: Subject; + + constructor() { + this.sink = new Subject(); + } + + public post(event: BaseEvent) { + this.sink.next(event); + } + + public subscribe(eventHandler: (event: BaseEvent) => void) { + this.sink.subscribe(eventHandler); + } +} \ No newline at end of file diff --git a/src/NestedError.ts b/src/NestedError.ts new file mode 100644 index 000000000..26de1e87d --- /dev/null +++ b/src/NestedError.ts @@ -0,0 +1,10 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +export class NestedError extends Error { + constructor(public message: string, public err: Error = null) { + super(message); + } +} \ No newline at end of file diff --git a/src/NetworkSettings.ts b/src/NetworkSettings.ts new file mode 100644 index 000000000..1ae77fe0b --- /dev/null +++ b/src/NetworkSettings.ts @@ -0,0 +1,24 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { vscode } from "./vscodeAdapter"; + +export default class NetworkSettings { + constructor(public readonly proxy: string, public readonly strictSSL: boolean) { + } +} + +export interface NetworkSettingsProvider { + (): NetworkSettings; +} + +export function vscodeNetworkSettingsProvider(vscode: vscode): NetworkSettingsProvider { + return () => { + const config = vscode.workspace.getConfiguration(); + const proxy = config.get('http.proxy'); + const strictSSL = config.get('http.proxyStrictSSL', true); + return new NetworkSettings(proxy, strictSSL); + }; +} \ No newline at end of file diff --git a/src/assets.ts b/src/assets.ts index 6fc9328c1..4665f5b01 100644 --- a/src/assets.ts +++ b/src/assets.ts @@ -60,7 +60,7 @@ export class AssetGenerator { this.initializeProjectData(workspaceInfo); } - private initializeProjectData(workspaceInfo: protocol.WorkspaceInformationResponse) { + private initializeProjectData(workspaceInfo: protocol.WorkspaceInformationResponse): void { // TODO: For now, assume the Debug configuration. Eventually, we'll need to revisit // this when we allow selecting configurations. const configurationName = 'Debug'; @@ -105,7 +105,7 @@ export class AssetGenerator { } } - return undefined; + return; } public hasWebServerDependency(): boolean { @@ -295,8 +295,8 @@ function hasAddOperations(operations: Operations) { return operations.addLaunchJson || operations.addLaunchJson; } -function getOperations(generator: AssetGenerator) { - return getBuildOperations(generator.tasksJsonPath).then(operations => +async function getOperations(generator: AssetGenerator) { + return getBuildOperations(generator.tasksJsonPath).then(async operations => getLaunchOperations(generator.launchJsonPath, operations)); } @@ -343,7 +343,7 @@ function getBuildTasks(tasksConfiguration: tasks.TaskConfiguration): tasks.TaskD return result; } -function getBuildOperations(tasksJsonPath: string) { +async function getBuildOperations(tasksJsonPath: string) { return new Promise((resolve, reject) => { fs.exists(tasksJsonPath, exists => { if (exists) { @@ -375,7 +375,7 @@ function getBuildOperations(tasksJsonPath: string) { }); } -function getLaunchOperations(launchJsonPath: string, operations: Operations) { +async function getLaunchOperations(launchJsonPath: string, operations: Operations) { return new Promise((resolve, reject) => { return fs.exists(launchJsonPath, exists => { if (exists) { @@ -399,7 +399,7 @@ interface PromptItem extends vscode.MessageItem { result: PromptResult; } -function promptToAddAssets(workspaceFolder: vscode.WorkspaceFolder) { +async function promptToAddAssets(workspaceFolder: vscode.WorkspaceFolder) { return new Promise((resolve, reject) => { const yesItem: PromptItem = { title: 'Yes', result: PromptResult.Yes }; const noItem: PromptItem = { title: 'Not Now', result: PromptResult.No, isCloseAffordance: true }; @@ -413,7 +413,7 @@ function promptToAddAssets(workspaceFolder: vscode.WorkspaceFolder) { }); } -export function addTasksJsonIfNecessary(generator: AssetGenerator, operations: Operations) { +export async function addTasksJsonIfNecessary(generator: AssetGenerator, operations: Operations) { return new Promise((resolve, reject) => { if (!operations.addTasksJson) { return resolve(); @@ -443,7 +443,7 @@ function indentJsonString(json: string, numSpaces: number = 4): string { return json.split('\n').map(line => ' '.repeat(numSpaces) + line).join('\n').trim(); } -function addLaunchJsonIfNecessary(generator: AssetGenerator, operations: Operations) { +async function addLaunchJsonIfNecessary(generator: AssetGenerator, operations: Operations) { return new Promise((resolve, reject) => { if (!operations.addLaunchJson) { return resolve(); @@ -489,7 +489,7 @@ function addLaunchJsonIfNecessary(generator: AssetGenerator, operations: Operati }); } -function addAssets(generator: AssetGenerator, operations: Operations) { +async function addAssets(generator: AssetGenerator, operations: Operations) { const promises = [ addTasksJsonIfNecessary(generator, operations), addLaunchJsonIfNecessary(generator, operations) @@ -505,13 +505,13 @@ export enum AddAssetResult { Cancelled } -export function addAssetsIfNecessary(server: OmniSharpServer): Promise { +export async function addAssetsIfNecessary(server: OmniSharpServer): Promise { return new Promise((resolve, reject) => { if (!vscode.workspace.workspaceFolders) { return resolve(AddAssetResult.NotApplicable); } - serverUtils.requestWorkspaceInformation(server).then(info => { + serverUtils.requestWorkspaceInformation(server).then(async info => { // If there are no .NET Core projects, we won't bother offering to add assets. if (protocol.containsDotNetCoreProjects(info)) { const generator = new AssetGenerator(info); @@ -541,7 +541,7 @@ export function addAssetsIfNecessary(server: OmniSharpServer): Promise((resolve, reject) => { fs.exists(generator.launchJsonPath, exists => { if (exists) { @@ -556,14 +556,14 @@ function doesAnyAssetExist(generator: AssetGenerator) { }); } -function deleteAssets(generator: AssetGenerator) { +async function deleteAssets(generator: AssetGenerator) { return Promise.all([ util.deleteIfExists(generator.launchJsonPath), util.deleteIfExists(generator.tasksJsonPath) ]); } -function shouldGenerateAssets(generator: AssetGenerator) { +async function shouldGenerateAssets(generator: AssetGenerator) { return new Promise((resolve, reject) => { doesAnyAssetExist(generator).then(res => { if (res) { diff --git a/src/common.ts b/src/common.ts index 8a31a6d16..df7bcc1af 100644 --- a/src/common.ts +++ b/src/common.ts @@ -35,13 +35,13 @@ export function safeLength(arr: T[] | undefined) { return arr ? arr.length : 0; } -export function buildPromiseChain(array: T[], builder: (item: T) => Promise): Promise { +export async function buildPromiseChain(array: T[], builder: (item: T) => Promise): Promise { return array.reduce( - (promise, n) => promise.then(() => builder(n)), + async (promise, n) => promise.then(async () => builder(n)), Promise.resolve(null)); } -export function execChildProcess(command: string, workingDirectory: string = getExtensionPath()): Promise { +export async function execChildProcess(command: string, workingDirectory: string = getExtensionPath()): Promise { return new Promise((resolve, reject) => { cp.exec(command, { cwd: workingDirectory, maxBuffer: 500 * 1024 }, (error, stdout, stderr) => { if (error) { @@ -57,7 +57,7 @@ export function execChildProcess(command: string, workingDirectory: string = get }); } -export function getUnixChildProcessIds(pid: number): Promise { +export async function getUnixChildProcessIds(pid: number): Promise { return new Promise((resolve, reject) => { let ps = cp.exec('ps -A -o ppid,pid', (error, stdout, stderr) => { @@ -92,7 +92,7 @@ export function getUnixChildProcessIds(pid: number): Promise { }); } -export function fileExists(filePath: string): Promise { +export async function fileExists(filePath: string): Promise { return new Promise((resolve, reject) => { fs.stat(filePath, (err, stats) => { if (stats && stats.isFile()) { @@ -105,9 +105,9 @@ export function fileExists(filePath: string): Promise { }); } -export function deleteIfExists(filePath: string): Promise { +export async function deleteIfExists(filePath: string): Promise { return fileExists(filePath) - .then((exists: boolean) => { + .then(async (exists: boolean) => { return new Promise((resolve, reject) => { if (!exists) { return resolve(); @@ -134,11 +134,11 @@ function getInstallFilePath(type: InstallFileType): string { return path.resolve(getExtensionPath(), installFile); } -export function installFileExists(type: InstallFileType): Promise { +export async function installFileExists(type: InstallFileType): Promise { return fileExists(getInstallFilePath(type)); } -export function touchInstallFile(type: InstallFileType): Promise { +export async function touchInstallFile(type: InstallFileType): Promise { return new Promise((resolve, reject) => { fs.writeFile(getInstallFilePath(type), '', err => { if (err) { @@ -151,7 +151,7 @@ export function touchInstallFile(type: InstallFileType): Promise { }); } -export function deleteInstallFile(type: InstallFileType): Promise { +export async function deleteInstallFile(type: InstallFileType): Promise { return new Promise((resolve, reject) => { fs.unlink(getInstallFilePath(type), err => { if (err) { diff --git a/src/configurationProvider.ts b/src/configurationProvider.ts index 34edf902e..bf48d0400 100644 --- a/src/configurationProvider.ts +++ b/src/configurationProvider.ts @@ -28,7 +28,7 @@ export class CSharpConfigurationProvider implements vscode.DebugConfigurationPro * Note: serverUtils.requestWorkspaceInformation only retrieves one folder for multi-root workspaces. Therefore, generator will be incorrect for all folders * except the first in a workspace. Currently, this only works if the requested folder is the same as the server's solution path or folder. */ - private checkWorkspaceInformationMatchesWorkspaceFolder(folder: vscode.WorkspaceFolder | undefined): Promise { + private async checkWorkspaceInformationMatchesWorkspaceFolder(folder: vscode.WorkspaceFolder | undefined): Promise { const solutionPathOrFolder: string = this.server.getSolutionPathOrFolder(); // Make sure folder, folder.uri, and solutionPathOrFolder are defined. @@ -59,18 +59,18 @@ export class CSharpConfigurationProvider implements vscode.DebugConfigurationPro * Returns a list of initial debug configurations based on contextual information, e.g. package.json or folder. */ provideDebugConfigurations(folder: vscode.WorkspaceFolder | undefined, token?: vscode.CancellationToken): vscode.ProviderResult { - return serverUtils.requestWorkspaceInformation(this.server).then(info => { - return this.checkWorkspaceInformationMatchesWorkspaceFolder(folder).then(workspaceMatches => { + return serverUtils.requestWorkspaceInformation(this.server).then(async info => { + return this.checkWorkspaceInformationMatchesWorkspaceFolder(folder).then(async workspaceMatches => { const generator = new AssetGenerator(info); if (workspaceMatches && containsDotNetCoreProjects(info)) { const dotVscodeFolder: string = path.join(folder.uri.fsPath, '.vscode'); const tasksJsonPath: string = path.join(dotVscodeFolder, 'tasks.json'); // Make sure .vscode folder exists, addTasksJsonIfNecessary will fail to create tasks.json if the folder does not exist. - return fs.ensureDir(dotVscodeFolder).then(() => { + return fs.ensureDir(dotVscodeFolder).then(async () => { // Check to see if tasks.json exists. return fs.pathExists(tasksJsonPath); - }).then(tasksJsonExists => { + }).then(async tasksJsonExists => { // Enable addTasksJson if it does not exist. return addTasksJsonIfNecessary(generator, {addTasksJson: !tasksJsonExists}); }).then(() => { diff --git a/src/coreclr-debug/activate.ts b/src/coreclr-debug/activate.ts index df401ad9b..4565cb079 100644 --- a/src/coreclr-debug/activate.ts +++ b/src/coreclr-debug/activate.ts @@ -2,63 +2,60 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; -import * as os from 'os'; import * as path from 'path'; import * as vscode from 'vscode'; import * as common from './../common'; - import { CoreClrDebugUtil, DotnetInfo, } from './util'; - -import { Logger } from './../logger'; import { PlatformInformation } from './../platform'; -import TelemetryReporter from 'vscode-extension-telemetry'; +import { DebuggerPrerequisiteWarning, DebuggerPrerequisiteFailure, DebuggerNotInstalledFailure } from '../omnisharp/loggingEvents'; +import { EventStream } from '../EventStream'; +import CSharpExtensionExports from '../CSharpExtensionExports'; let _debugUtil: CoreClrDebugUtil = null; -let _logger: Logger = null; -export async function activate(thisExtension : vscode.Extension, context: vscode.ExtensionContext, reporter: TelemetryReporter, logger: Logger, channel: vscode.OutputChannel) { - _debugUtil = new CoreClrDebugUtil(context.extensionPath, logger); - _logger = logger; +export async function activate(thisExtension: vscode.Extension, context: vscode.ExtensionContext, platformInformation: PlatformInformation, eventStream: EventStream) { + _debugUtil = new CoreClrDebugUtil(context.extensionPath); if (!CoreClrDebugUtil.existsSync(_debugUtil.debugAdapterDir())) { - let platformInformation: PlatformInformation; - - try { - platformInformation = await PlatformInformation.GetCurrent(); + let isInvalidArchitecture: boolean = await checkForInvalidArchitecture(platformInformation, eventStream); + if (!isInvalidArchitecture) { + eventStream.post(new DebuggerPrerequisiteFailure("[ERROR]: C# Extension failed to install the debugger package.")); + showInstallErrorMessage(eventStream); } - catch (err) { - // Somehow we couldn't figure out the platform we are on - logger.appendLine("[ERROR]: C# Extension failed to install the debugger package"); - showInstallErrorMessage(channel); + } else if (!CoreClrDebugUtil.existsSync(_debugUtil.installCompleteFilePath())) { + completeDebuggerInstall(platformInformation, eventStream); + } +} + +async function checkForInvalidArchitecture(platformInformation: PlatformInformation, eventStream: EventStream): Promise { + if (platformInformation) { + if (platformInformation.isMacOS() && !CoreClrDebugUtil.isMacOSSupported()) { + eventStream.post(new DebuggerPrerequisiteFailure("[ERROR] The debugger cannot be installed. The debugger requires macOS 10.12 (Sierra) or newer.")); + return true; } - - if (platformInformation) { - if (platformInformation.architecture !== "x86_64") { - if (platformInformation.isWindows() && platformInformation.architecture === "x86") { - logger.appendLine(`[WARNING]: x86 Windows is not currently supported by the .NET Core debugger. Debugging will not be available.`); - } else { - logger.appendLine(`[WARNING]: Processor architecture '${platformInformation.architecture}' is not currently supported by the .NET Core debugger. Debugging will not be available.`); - } + else if (platformInformation.architecture !== "x86_64") { + if (platformInformation.isWindows() && platformInformation.architecture === "x86") { + eventStream.post(new DebuggerPrerequisiteWarning(`[WARNING]: x86 Windows is not currently supported by the .NET Core debugger. Debugging will not be available.`)); } else { - logger.appendLine("[ERROR]: C# Extension failed to install the debugger package"); - showInstallErrorMessage(channel); + eventStream.post(new DebuggerPrerequisiteWarning(`[WARNING]: Processor architecture '${platformInformation.architecture}' is not currently supported by the .NET Core debugger. Debugging will not be available.`)); } + return true; } - } else if (!CoreClrDebugUtil.existsSync(_debugUtil.installCompleteFilePath())) { - completeDebuggerInstall(logger, channel); } + + return false; } -async function completeDebuggerInstall(logger: Logger, channel: vscode.OutputChannel) : Promise { +async function completeDebuggerInstall(platformInformation: PlatformInformation, eventStream: EventStream): Promise { return _debugUtil.checkDotNetCli() - .then((dotnetInfo: DotnetInfo) => { + .then(async (dotnetInfo: DotnetInfo) => { - if (os.platform() === "darwin" && !CoreClrDebugUtil.isMacOSSupported()) { - logger.appendLine("[ERROR] The debugger cannot be installed. The debugger requires macOS 10.12 (Sierra) or newer."); - channel.show(); + let isInvalidArchitecture: boolean = await checkForInvalidArchitecture(platformInformation, eventStream); + if (isInvalidArchitecture) { + eventStream.post(new DebuggerNotInstalledFailure()); + vscode.window.showErrorMessage('Failed to complete the installation of the C# extension. Please see the error in the output window below.'); return false; } @@ -71,20 +68,18 @@ async function completeDebuggerInstall(logger: Logger, channel: vscode.OutputCha // Check for dotnet tools failed. pop the UI // err is a DotNetCliError but use defaults in the unexpected case that it's not showDotnetToolsWarning(err.ErrorMessage || _debugUtil.defaultDotNetCliErrorMessage()); - _logger.appendLine(err.ErrorString || err); + eventStream.post(new DebuggerPrerequisiteWarning(err.ErrorString || err)); // TODO: log telemetry? - return false; }); } -function showInstallErrorMessage(channel: vscode.OutputChannel) { - channel.show(); +function showInstallErrorMessage(eventStream : EventStream) { + eventStream.post(new DebuggerNotInstalledFailure()); vscode.window.showErrorMessage("An error occured during installation of the .NET Core Debugger. The C# extension may need to be reinstalled."); } -function showDotnetToolsWarning(message: string) : void -{ +function showDotnetToolsWarning(message: string): void { const config = vscode.workspace.getConfiguration('csharp'); if (!config.get('suppressDotnetInstallWarning', false)) { const getDotNetMessage = 'Get .NET CLI tools'; @@ -98,8 +93,7 @@ function showDotnetToolsWarning(message: string) : void let dotnetcoreURL = 'https://www.microsoft.com/net/core'; // Windows redirects https://www.microsoft.com/net/core to https://www.microsoft.com/net/core#windowsvs2015 - if (process.platform == "win32") - { + if (process.platform == "win32") { dotnetcoreURL = dotnetcoreURL + '#windowscmd'; } @@ -118,13 +112,11 @@ interface AdapterExecutableCommand { // The default extension manifest calls this command as the adapterExecutableCommand // If the debugger components have not finished downloading, the proxy displays an error message to the user // Else it will launch the debug adapter -export async function getAdapterExecutionCommand(channel: vscode.OutputChannel): Promise { - let logger = new Logger(text => channel.append(text)); - let util = new CoreClrDebugUtil(common.getExtensionPath(), logger); +export async function getAdapterExecutionCommand(platformInfo: PlatformInformation, eventStream: EventStream): Promise { + let util = new CoreClrDebugUtil(common.getExtensionPath()); // Check for .debugger folder. Handle if it does not exist. - if (!CoreClrDebugUtil.existsSync(util.debugAdapterDir())) - { + if (!CoreClrDebugUtil.existsSync(util.debugAdapterDir())) { // our install.complete file does not exist yet, meaning we have not completed the installation. Try to figure out what if anything the package manager is doing // the order in which files are dealt with is this: // 1. install.Begin is created @@ -135,22 +127,21 @@ export async function getAdapterExecutionCommand(channel: vscode.OutputChannel): // install.Lock does not exist, need to wait for packages to finish downloading. let installLock: boolean = await common.installFileExists(common.InstallFileType.Lock); if (!installLock) { - channel.show(); + eventStream.post(new DebuggerNotInstalledFailure()); throw new Error('The C# extension is still downloading packages. Please see progress in the output window below.'); } // install.complete does not exist, check dotnetCLI to see if we can complete. else if (!CoreClrDebugUtil.existsSync(util.installCompleteFilePath())) { - let success: boolean = await completeDebuggerInstall(logger, channel); + let success: boolean = await completeDebuggerInstall(platformInfo, eventStream); - if (!success) - { - channel.show(); + if (!success) { + eventStream.post(new DebuggerNotInstalledFailure()); throw new Error('Failed to complete the installation of the C# extension. Please see the error in the output window below.'); } } } - // debugger has finished install, kick off our debugger process + // debugger has finished installation, kick off our debugger process return { command: path.join(common.getExtensionPath(), ".debugger", "vsdbg-ui" + CoreClrDebugUtil.getPlatformExeExtension()) }; diff --git a/src/coreclr-debug/debuggerEventsProtocol.ts b/src/coreclr-debug/debuggerEventsProtocol.ts index 00f631028..69a57b0c0 100644 --- a/src/coreclr-debug/debuggerEventsProtocol.ts +++ b/src/coreclr-debug/debuggerEventsProtocol.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; - // This contains the definition of messages that VsDbg-UI can send back to a listener which registers itself via the 'debuggerEventsPipeName' // property on a launch or attach request. // diff --git a/src/coreclr-debug/util.ts b/src/coreclr-debug/util.ts index 51340de69..74b680040 100644 --- a/src/coreclr-debug/util.ts +++ b/src/coreclr-debug/util.ts @@ -2,14 +2,12 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; import * as path from 'path'; import * as fs from 'fs'; import * as semver from 'semver'; import * as os from 'os'; import { execChildProcess } from './../common'; -import { Logger } from './../logger'; const MINIMUM_SUPPORTED_DOTNET_CLI: string = '1.0.0-preview2-003121'; @@ -31,7 +29,7 @@ export class CoreClrDebugUtil private _debugAdapterDir: string = ''; private _installCompleteFilePath: string = ''; - constructor(extensionDir: string, logger: Logger) { + constructor(extensionDir: string) { this._extensionDir = extensionDir; this._debugAdapterDir = path.join(this._extensionDir, '.debugger'); this._installCompleteFilePath = path.join(this._debugAdapterDir, 'install.complete'); @@ -60,7 +58,7 @@ export class CoreClrDebugUtil return this._installCompleteFilePath; } - public static writeEmptyFile(path: string) : Promise { + public static async writeEmptyFile(path: string) : Promise { return new Promise((resolve, reject) => { fs.writeFile(path, '', (err) => { if (err) { @@ -80,7 +78,7 @@ export class CoreClrDebugUtil // is new enough for us. // Returns: a promise that returns a DotnetInfo class // Throws: An DotNetCliError() from the return promise if either dotnet does not exist or is too old. - public checkDotNetCli(): Promise + public async checkDotNetCli(): Promise { let dotnetInfo = new DotnetInfo(); diff --git a/src/features/abstractProvider.ts b/src/features/abstractProvider.ts index d1d9a8952..94ecc9ee6 100644 --- a/src/features/abstractProvider.ts +++ b/src/features/abstractProvider.ts @@ -3,21 +3,16 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; - -import { OmniSharpServer } from '../omnisharp/server'; import { Disposable } from 'vscode'; -import TelemetryReporter from 'vscode-extension-telemetry'; +import { OmniSharpServer } from '../omnisharp/server'; export default abstract class AbstractProvider { protected _server: OmniSharpServer; - protected _reporter: TelemetryReporter; private _disposables: Disposable[]; - constructor(server: OmniSharpServer, reporter: TelemetryReporter) { + constructor(server: OmniSharpServer) { this._server = server; - this._reporter = reporter; this._disposables = []; } diff --git a/src/features/changeForwarding.ts b/src/features/changeForwarding.ts index 798c037dd..ba2cb3913 100644 --- a/src/features/changeForwarding.ts +++ b/src/features/changeForwarding.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; - import {Disposable, Uri, workspace} from 'vscode'; import {OmniSharpServer} from '../omnisharp/server'; import * as serverUtils from '../omnisharp/utils'; @@ -32,7 +30,7 @@ function forwardDocumentChanges(server: OmniSharpServer): Disposable { function forwardFileChanges(server: OmniSharpServer): Disposable { - function onFileSystemEvent(changeType: FileChangeType): (Uri) => void { + function onFileSystemEvent(changeType: FileChangeType): (uri: Uri) => void { return function(uri: Uri) { if (!server.isRunning()) { diff --git a/src/features/codeActionProvider.ts b/src/features/codeActionProvider.ts index ccfd1b635..2c529605e 100644 --- a/src/features/codeActionProvider.ts +++ b/src/features/codeActionProvider.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; - import * as vscode from 'vscode'; import { OmniSharpServer } from '../omnisharp/server'; import AbstractProvider from './abstractProvider'; @@ -12,7 +10,6 @@ import * as protocol from '../omnisharp/protocol'; import { toRange2 } from '../omnisharp/typeConvertion'; import * as serverUtils from '../omnisharp/utils'; import { Options } from '../omnisharp/options'; -import TelemetryReporter from 'vscode-extension-telemetry'; import { FileModificationType } from '../omnisharp/protocol'; import { Uri } from 'vscode'; @@ -21,8 +18,8 @@ export default class CodeActionProvider extends AbstractProvider implements vsco private _options: Options; private _commandId: string; - constructor(server: OmniSharpServer, reporter: TelemetryReporter) { - super(server, reporter); + constructor(server: OmniSharpServer) { + super(server); this._commandId = 'omnisharp.runCodeAction'; @@ -37,7 +34,7 @@ export default class CodeActionProvider extends AbstractProvider implements vsco this._options = Options.Read(); } - public provideCodeActions(document: vscode.TextDocument, range: vscode.Range, context: vscode.CodeActionContext, token: vscode.CancellationToken): Promise { + public async provideCodeActions(document: vscode.TextDocument, range: vscode.Range, context: vscode.CodeActionContext, token: vscode.CancellationToken): Promise { if (this._options.disableCodeActions) { return; } @@ -102,12 +99,12 @@ export default class CodeActionProvider extends AbstractProvider implements vsco arguments: [runRequest] }; }); - }, (error) => { + }, async (error) => { return Promise.reject(`Problem invoking 'GetCodeActions' on OmniSharp server: ${error}`); }); } - private _runCodeAction(req: protocol.V2.RunCodeActionRequest): Promise { + private async _runCodeAction(req: protocol.V2.RunCodeActionRequest): Promise { return serverUtils.runCodeAction(this._server, req).then(response => { @@ -179,7 +176,7 @@ export default class CodeActionProvider extends AbstractProvider implements vsco }) : next; } - }, (error) => { + }, async (error) => { return Promise.reject(`Problem invoking 'RunCodeAction' on OmniSharp server: ${error}`); }); } diff --git a/src/features/codeLensProvider.ts b/src/features/codeLensProvider.ts index 2f58640e9..6c3300b82 100644 --- a/src/features/codeLensProvider.ts +++ b/src/features/codeLensProvider.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; - import * as protocol from '../omnisharp/protocol'; import * as serverUtils from '../omnisharp/utils'; import * as vscode from 'vscode'; @@ -14,7 +12,6 @@ import { toLocation, toRange } from '../omnisharp/typeConvertion'; import AbstractProvider from './abstractProvider'; import { OmniSharpServer } from '../omnisharp/server'; import { Options } from '../omnisharp/options'; -import TelemetryReporter from 'vscode-extension-telemetry'; import TestManager from './dotnetTest'; class OmniSharpCodeLens extends vscode.CodeLens { @@ -31,9 +28,8 @@ export default class OmniSharpCodeLensProvider extends AbstractProvider implemen private _options: Options; - constructor(server: OmniSharpServer, reporter: TelemetryReporter, testManager: TestManager) - { - super(server, reporter); + constructor(server: OmniSharpServer, testManager: TestManager) { + super(server); this._resetCachedOptions(); @@ -52,20 +48,23 @@ export default class OmniSharpCodeLensProvider extends AbstractProvider implemen 'ToString': true }; - provideCodeLenses(document: vscode.TextDocument, token: vscode.CancellationToken): vscode.CodeLens[] | Thenable { - if (!this._options.showReferencesCodeLens && !this._options.showTestsCodeLens) - { + async provideCodeLenses(document: vscode.TextDocument, token: vscode.CancellationToken) { + if (!this._options.showReferencesCodeLens && !this._options.showTestsCodeLens) { return []; } - return serverUtils.currentFileMembersAsTree(this._server, { FileName: document.fileName }, token).then(tree => { - let ret: vscode.CodeLens[] = []; - tree.TopLevelTypeDefinitions.forEach(node => this._convertQuickFix(ret, document.fileName, node)); - return ret; - }); + let tree = await serverUtils.currentFileMembersAsTree(this._server, { FileName: document.fileName }, token); + let ret: vscode.CodeLens[] = []; + + for (let node of tree.TopLevelTypeDefinitions) { + await this._convertQuickFix(ret, document.fileName, node); + } + + return ret; } - private _convertQuickFix(bucket: vscode.CodeLens[], fileName: string, node: protocol.Node): void { + + private async _convertQuickFix(bucket: vscode.CodeLens[], fileName: string, node: protocol.Node): Promise { if (node.Kind === 'MethodDeclaration' && OmniSharpCodeLensProvider.filteredSymbolNames[node.Location.Text]) { return; @@ -81,7 +80,7 @@ export default class OmniSharpCodeLensProvider extends AbstractProvider implemen } if (this._options.showTestsCodeLens) { - this._updateCodeLensForTest(bucket, fileName, node); + await this._updateCodeLensForTest(bucket, fileName, node); } } @@ -113,15 +112,64 @@ export default class OmniSharpCodeLensProvider extends AbstractProvider implemen } } - private _updateCodeLensForTest(bucket: vscode.CodeLens[], fileName: string, node: protocol.Node) { + private async _updateCodeLensForTest(bucket: vscode.CodeLens[], fileName: string, node: protocol.Node): Promise { // backward compatible check: Features property doesn't present on older version OmniSharp if (node.Features === undefined) { return; } + if (node.Kind === "ClassDeclaration" && node.ChildNodes.length > 0) { + let projectInfo = await serverUtils.requestProjectInformation(this._server, { FileName: fileName }); + if (!projectInfo.DotNetProject && projectInfo.MsBuildProject) { + this._updateCodeLensForTestClass(bucket, fileName, node); + } + } + + let [testFeature, testFrameworkName] = this._getTestFeatureAndFramework(node); + if (testFeature) { + bucket.push(new vscode.CodeLens( + toRange(node.Location), + { title: "Run Test", command: 'dotnet.test.run', arguments: [testFeature.Data, fileName, testFrameworkName] })); + + bucket.push(new vscode.CodeLens( + toRange(node.Location), + { title: "Debug Test", command: 'dotnet.test.debug', arguments: [testFeature.Data, fileName, testFrameworkName] })); + } + } + + private _updateCodeLensForTestClass(bucket: vscode.CodeLens[], fileName: string, node: protocol.Node) { + // if the class doesnot contain any method then return + if (!node.ChildNodes.find(value => (value.Kind === "MethodDeclaration"))) { + return; + } + + let testMethods = new Array(); + let testFrameworkName: string = null; + for (let child of node.ChildNodes) { + let [testFeature, frameworkName] = this._getTestFeatureAndFramework(child); + if (testFeature) { + // this test method has a test feature + if (!testFrameworkName) { + testFrameworkName = frameworkName; + } + + testMethods.push(testFeature.Data); + } + } + + if (testMethods.length > 0) { + bucket.push(new vscode.CodeLens( + toRange(node.Location), + { title: "Run All Tests", command: 'dotnet.classTests.run', arguments: [testMethods, fileName, testFrameworkName] })); + bucket.push(new vscode.CodeLens( + toRange(node.Location), + { title: "Debug All Tests", command: 'dotnet.classTests.debug', arguments: [testMethods, fileName, testFrameworkName] })); + } + } + + private _getTestFeatureAndFramework(node: protocol.Node): [protocol.SyntaxFeature, string] { let testFeature = node.Features.find(value => (value.Name == 'XunitTestMethod' || value.Name == 'NUnitTestMethod' || value.Name == 'MSTestMethod')); if (testFeature) { - // this test method has a test feature let testFrameworkName = 'xunit'; if (testFeature.Name == 'NUnitTestMethod') { testFrameworkName = 'nunit'; @@ -130,13 +178,9 @@ export default class OmniSharpCodeLensProvider extends AbstractProvider implemen testFrameworkName = 'mstest'; } - bucket.push(new vscode.CodeLens( - toRange(node.Location), - { title: "run test", command: 'dotnet.test.run', arguments: [testFeature.Data, fileName, testFrameworkName] })); - - bucket.push(new vscode.CodeLens( - toRange(node.Location), - { title: "debug test", command: 'dotnet.test.debug', arguments: [testFeature.Data, fileName, testFrameworkName] })); + return [testFeature, testFrameworkName]; } + + return [null, null]; } } diff --git a/src/features/commands.ts b/src/features/commands.ts index 2a5c628b0..28dd9fa9a 100644 --- a/src/features/commands.ts +++ b/src/features/commands.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; - import { OmniSharpServer } from '../omnisharp/server'; import * as serverUtils from '../omnisharp/utils'; import { findLaunchTargets } from '../omnisharp/launcher'; @@ -15,16 +13,23 @@ import * as protocol from '../omnisharp/protocol'; import * as vscode from 'vscode'; import { DotNetAttachItemsProviderFactory, AttachPicker, RemoteAttachPicker } from './processPicker'; import { generateAssets } from '../assets'; -import TelemetryReporter from 'vscode-extension-telemetry'; import { getAdapterExecutionCommand } from '../coreclr-debug/activate'; +import { CommandShowOutput, CommandDotNetRestoreStart, CommandDotNetRestoreProgress, CommandDotNetRestoreSucceeded, CommandDotNetRestoreFailed } from '../omnisharp/loggingEvents'; +import { EventStream } from '../EventStream'; +import { PlatformInformation } from '../platform'; -let channel = vscode.window.createOutputChannel('.NET'); - -export default function registerCommands(server: OmniSharpServer, reporter: TelemetryReporter, channel: vscode.OutputChannel) { +export default function registerCommands(server: OmniSharpServer, eventStream: EventStream, platformInfo: PlatformInformation) { let d1 = vscode.commands.registerCommand('o.restart', () => restartOmniSharp(server)); let d2 = vscode.commands.registerCommand('o.pickProjectAndStart', () => pickProjectAndStart(server)); - let d3 = vscode.commands.registerCommand('o.showOutput', () => server.getChannel().show(vscode.ViewColumn.Three)); - let d4 = vscode.commands.registerCommand('dotnet.restore', () => dotnetRestoreAllProjects(server)); + let d3 = vscode.commands.registerCommand('o.showOutput', () => eventStream.post(new CommandShowOutput())); + let d4 = vscode.commands.registerCommand('dotnet.restore', fileName => { + if (fileName) { + dotnetRestoreForProject(server, fileName, eventStream); + } + else { + dotnetRestoreAllProjects(server, eventStream); + } + }); // register empty handler for csharp.installDebugger // running the command activates the extension, which is all we need for installation to kickoff @@ -33,17 +38,17 @@ export default function registerCommands(server: OmniSharpServer, reporter: Tele // register process picker for attach let attachItemsProvider = DotNetAttachItemsProviderFactory.Get(); let attacher = new AttachPicker(attachItemsProvider); - let d6 = vscode.commands.registerCommand('csharp.listProcess', () => attacher.ShowAttachEntries()); + let d6 = vscode.commands.registerCommand('csharp.listProcess', async () => attacher.ShowAttachEntries()); // Register command for generating tasks.json and launch.json assets. - let d7 = vscode.commands.registerCommand('dotnet.generateAssets', () => generateAssets(server)); + let d7 = vscode.commands.registerCommand('dotnet.generateAssets', async () => generateAssets(server)); // Register command for remote process picker for attach - let d8 = vscode.commands.registerCommand('csharp.listRemoteProcess', (args) => RemoteAttachPicker.ShowAttachEntries(args)); + let d8 = vscode.commands.registerCommand('csharp.listRemoteProcess', async (args) => RemoteAttachPicker.ShowAttachEntries(args)); // Register command for adapter executable command. - let d9 = vscode.commands.registerCommand('csharp.coreclrAdapterExecutableCommand', (args) => getAdapterExecutionCommand(channel)); - let d10 = vscode.commands.registerCommand('csharp.clrAdapterExecutableCommand', (args) => getAdapterExecutionCommand(channel)); + let d9 = vscode.commands.registerCommand('csharp.coreclrAdapterExecutableCommand', async (args) => getAdapterExecutionCommand(platformInfo, eventStream)); + let d10 = vscode.commands.registerCommand('csharp.clrAdapterExecutableCommand', async (args) => getAdapterExecutionCommand(platformInfo, eventStream)); return vscode.Disposable.from(d1, d2, d3, d4, d5, d6, d7, d8, d9, d10); } @@ -73,7 +78,7 @@ function pickProjectAndStart(server: OmniSharpServer) { return vscode.window.showQuickPick(targets, { matchOnDescription: true, placeHolder: `Select 1 of ${targets.length} projects` - }).then(launchTarget => { + }).then(async launchTarget => { if (launchTarget) { return server.restart(launchTarget); } @@ -84,11 +89,11 @@ function pickProjectAndStart(server: OmniSharpServer) { interface Command { label: string; description: string; - execute(): Thenable; + execute(): Thenable; } -function projectsToCommands(projects: protocol.ProjectDescriptor[]): Promise[] { - return projects.map(project => { +function projectsToCommands(projects: protocol.ProjectDescriptor[], eventStream: EventStream): Promise[] { + return projects.map(async project => { let projectDirectory = project.Directory; return new Promise((resolve, reject) => { @@ -104,8 +109,8 @@ function projectsToCommands(projects: protocol.ProjectDescriptor[]): Promise { +export async function dotnetRestoreAllProjects(server: OmniSharpServer, eventStream: EventStream): Promise { if (!server.isRunning()) { return Promise.reject('OmniSharp server is not running.'); } - return serverUtils.requestWorkspaceInformation(server).then(info => { + return serverUtils.requestWorkspaceInformation(server).then(async info => { let descriptors = protocol.getDotNetCoreProjectDescriptors(info); @@ -127,7 +132,7 @@ export function dotnetRestoreAllProjects(server: OmniSharpServer) : Promise { return vscode.window.showQuickPick(commands); @@ -139,13 +144,13 @@ export function dotnetRestoreAllProjects(server: OmniSharpServer) : Promise { + return serverUtils.requestWorkspaceInformation(server).then(async info => { let descriptors = protocol.getDotNetCoreProjectDescriptors(info); @@ -155,16 +160,15 @@ export function dotnetRestoreForProject(server: OmniSharpServer, filePath: strin for (let descriptor of descriptors) { if (descriptor.FilePath === filePath) { - return dotnetRestore(descriptor.Directory, filePath); + return dotnetRestore(descriptor.Directory, eventStream, filePath); } } }); } -function dotnetRestore(cwd: string, filePath?: string) { +async function dotnetRestore(cwd: string, eventStream: EventStream, filePath?: string) { return new Promise((resolve, reject) => { - channel.clear(); - channel.show(); + eventStream.post(new CommandDotNetRestoreStart()); let cmd = 'dotnet'; let args = ['restore']; @@ -177,11 +181,11 @@ function dotnetRestore(cwd: string, filePath?: string) { function handleData(stream: NodeJS.ReadableStream) { stream.on('data', chunk => { - channel.append(chunk.toString()); + eventStream.post(new CommandDotNetRestoreProgress(chunk.toString())); }); stream.on('err', err => { - channel.append(`ERROR: ${err}`); + eventStream.post(new CommandDotNetRestoreProgress(`ERROR: ${err}`)); }); } @@ -189,12 +193,12 @@ function dotnetRestore(cwd: string, filePath?: string) { handleData(dotnet.stderr); dotnet.on('close', (code, signal) => { - channel.appendLine(`Done: ${code}.`); + eventStream.post(new CommandDotNetRestoreSucceeded(`Done: ${code}.`)); resolve(); }); dotnet.on('error', err => { - channel.appendLine(`ERROR: ${err}`); + eventStream.post(new CommandDotNetRestoreFailed(`ERROR: ${err}`)); reject(err); }); }); diff --git a/src/features/completionItemProvider.ts b/src/features/completionItemProvider.ts index 0119c2c38..a7181dbf3 100644 --- a/src/features/completionItemProvider.ts +++ b/src/features/completionItemProvider.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; - import {extractSummaryText} from './documentation'; import AbstractSupport from './abstractProvider'; import * as protocol from '../omnisharp/protocol'; @@ -25,7 +23,7 @@ export default class OmniSharpCompletionItemProvider extends AbstractSupport imp ';', '+', '-', '*', '/', '%', '&', '|', '^', '!', '~', '=', '<', '>', '?', '@', '#', '\'', '\"', '\\']; - public provideCompletionItems(document: TextDocument, position: Position, token: CancellationToken, context: CompletionContext): Promise { + public async provideCompletionItems(document: TextDocument, position: Position, token: CancellationToken, context: CompletionContext): Promise { let wordToComplete = ''; let range = document.getWordRangeAtPosition(position); diff --git a/src/features/definitionProvider.ts b/src/features/definitionProvider.ts index 61514c391..23906b680 100644 --- a/src/features/definitionProvider.ts +++ b/src/features/definitionProvider.ts @@ -3,26 +3,24 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; - -import AbstractSupport from './abstractProvider'; -import {MetadataRequest, GoToDefinitionRequest, MetadataSource} from '../omnisharp/protocol'; import * as serverUtils from '../omnisharp/utils'; +import {CancellationToken, DefinitionProvider, Location, Position, TextDocument, Uri} from 'vscode'; +import {GoToDefinitionRequest, MetadataRequest, MetadataSource} from '../omnisharp/protocol'; import {createRequest, toLocation, toLocationFromUri} from '../omnisharp/typeConvertion'; -import {Uri, TextDocument, Position, Location, CancellationToken, DefinitionProvider} from 'vscode'; +import AbstractSupport from './abstractProvider'; import DefinitionMetadataDocumentProvider from './definitionMetadataDocumentProvider'; -import TelemetryReporter from 'vscode-extension-telemetry'; +import { OmniSharpServer } from '../omnisharp/server'; export default class CSharpDefinitionProvider extends AbstractSupport implements DefinitionProvider { private _definitionMetadataDocumentProvider: DefinitionMetadataDocumentProvider; - constructor(server,reporter: TelemetryReporter, definitionMetadataDocumentProvider: DefinitionMetadataDocumentProvider) { - super(server, reporter); + constructor(server: OmniSharpServer, definitionMetadataDocumentProvider: DefinitionMetadataDocumentProvider) { + super(server); this._definitionMetadataDocumentProvider = definitionMetadataDocumentProvider; } - public provideDefinition(document: TextDocument, position: Position, token: CancellationToken): Promise { + public async provideDefinition(document: TextDocument, position: Position, token: CancellationToken): Promise { let req = createRequest(document, position); req.WantMetadata = true; diff --git a/src/features/diagnosticsProvider.ts b/src/features/diagnosticsProvider.ts index fce318e7b..dc315fed4 100644 --- a/src/features/diagnosticsProvider.ts +++ b/src/features/diagnosticsProvider.ts @@ -9,7 +9,6 @@ import * as protocol from '../omnisharp/protocol'; import * as serverUtils from '../omnisharp/utils'; import { toRange } from '../omnisharp/typeConvertion'; import * as vscode from 'vscode'; -import TelemetryReporter from 'vscode-extension-telemetry'; export class Advisor { @@ -60,11 +59,11 @@ export class Advisor { private _removeProjectFileCount(info: protocol.ProjectInformationResponse): void { if (info.DotNetProject && info.DotNetProject.SourceFiles) { - delete this._updateProjectFileCount[info.DotNetProject.Path]; + delete this._projectSourceFileCounts[info.DotNetProject.Path]; } if (info.MsBuildProject && info.MsBuildProject.SourceFiles) { - delete this._updateProjectFileCount[info.MsBuildProject.Path]; + delete this._projectSourceFileCounts[info.MsBuildProject.Path]; } } @@ -109,8 +108,8 @@ export class Advisor { } } -export default function reportDiagnostics(server: OmniSharpServer, reporter: TelemetryReporter, advisor: Advisor): vscode.Disposable { - return new DiagnosticsProvider(server, reporter, advisor); +export default function reportDiagnostics(server: OmniSharpServer, advisor: Advisor): vscode.Disposable { + return new DiagnosticsProvider(server, advisor); } class DiagnosticsProvider extends AbstractSupport { @@ -121,8 +120,8 @@ class DiagnosticsProvider extends AbstractSupport { private _projectValidation: vscode.CancellationTokenSource; private _diagnostics: vscode.DiagnosticCollection; - constructor(server: OmniSharpServer, reporter: TelemetryReporter, validationAdvisor: Advisor) { - super(server, reporter); + constructor(server: OmniSharpServer, validationAdvisor: Advisor) { + super(server); this._validationAdvisor = validationAdvisor; this._diagnostics = vscode.languages.createDiagnosticCollection('csharp'); @@ -163,17 +162,19 @@ class DiagnosticsProvider extends AbstractSupport { } private _onDocumentRemove(document: vscode.TextDocument) { - let key = document.uri.toString(); + let key = document.uri; let didChange = false; - if (this._diagnostics[key]) { + if (this._diagnostics.get(key)) { didChange = true; - this._diagnostics[key].dispose(); - delete this._diagnostics[key]; + this._diagnostics.delete(key); } - if (this._documentValidations[key]) { + + let keyString = key.toString(); + + if (this._documentValidations[keyString]) { didChange = true; - this._documentValidations[key].cancel(); - delete this._documentValidations[key]; + this._documentValidations[keyString].cancel(); + delete this._documentValidations[keyString]; } if (didChange) { this._validateProject(); diff --git a/src/features/documentHighlightProvider.ts b/src/features/documentHighlightProvider.ts index aaac73ada..355b0f82f 100644 --- a/src/features/documentHighlightProvider.ts +++ b/src/features/documentHighlightProvider.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; - import AbstractSupport from './abstractProvider'; import * as protocol from '../omnisharp/protocol'; import * as serverUtils from '../omnisharp/utils'; @@ -13,7 +11,7 @@ import {DocumentHighlightProvider, DocumentHighlight, DocumentHighlightKind, Can export default class OmnisharpDocumentHighlightProvider extends AbstractSupport implements DocumentHighlightProvider { - public provideDocumentHighlights(resource: TextDocument, position: Position, token: CancellationToken): Promise { + public async provideDocumentHighlights(resource: TextDocument, position: Position, token: CancellationToken): Promise { let req = createRequest(resource, position); req.OnlyThisFile = true; diff --git a/src/features/documentSymbolProvider.ts b/src/features/documentSymbolProvider.ts index a112e8a9a..753e85af6 100644 --- a/src/features/documentSymbolProvider.ts +++ b/src/features/documentSymbolProvider.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; - import AbstractSupport from './abstractProvider'; import * as serverUtils from '../omnisharp/utils'; import {toDocumentSymbol} from '../omnisharp/typeConvertion'; @@ -12,7 +10,7 @@ import {DocumentSymbolProvider, SymbolInformation, TextDocument, CancellationTok export default class OmnisharpDocumentSymbolProvider extends AbstractSupport implements DocumentSymbolProvider { - public provideDocumentSymbols(document: TextDocument, token: CancellationToken): Promise { + public async provideDocumentSymbols(document: TextDocument, token: CancellationToken): Promise { return serverUtils.currentFileMembersAsTree(this._server, { FileName: document.fileName }, token).then(tree => { let ret: SymbolInformation[] = []; diff --git a/src/features/documentation.ts b/src/features/documentation.ts index fd85261c1..6a6a9af6c 100644 --- a/src/features/documentation.ts +++ b/src/features/documentation.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; import * as protocol from '../omnisharp/protocol'; const summaryStartTag = //i; diff --git a/src/features/dotnetTest.ts b/src/features/dotnetTest.ts index 27a2c0bac..a3d056da7 100644 --- a/src/features/dotnetTest.ts +++ b/src/features/dotnetTest.ts @@ -3,17 +3,19 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { OmniSharpServer } from '../omnisharp/server'; -import { DebuggerEventsProtocol } from '../coreclr-debug/debuggerEventsProtocol'; -import * as vscode from 'vscode'; -import * as serverUtils from "../omnisharp/utils"; -import * as protocol from '../omnisharp/protocol'; -import * as utils from '../common'; import * as net from 'net'; import * as os from 'os'; import * as path from 'path'; -import TelemetryReporter from 'vscode-extension-telemetry'; +import * as protocol from '../omnisharp/protocol'; +import * as serverUtils from "../omnisharp/utils"; +import * as utils from '../common'; +import * as vscode from 'vscode'; import AbstractProvider from './abstractProvider'; +import { DebuggerEventsProtocol } from '../coreclr-debug/debuggerEventsProtocol'; +import { OmniSharpServer } from '../omnisharp/server'; +import { TestExecutionCountReport } from '../omnisharp/loggingEvents'; +import { EventStream } from '../EventStream'; +import LaunchConfiguration from './launchConfiguration'; const TelemetryReportingDelay = 2 * 60 * 1000; // two minutes @@ -23,18 +25,28 @@ export default class TestManager extends AbstractProvider { private _runCounts: { [testFrameworkName: string]: number }; private _debugCounts: { [testFrameworkName: string]: number }; private _telemetryIntervalId: NodeJS.Timer = undefined; + private _eventStream: EventStream; - constructor(server: OmniSharpServer, reporter: TelemetryReporter) { - super(server, reporter); + constructor(server: OmniSharpServer, eventStream: EventStream) { + super(server); + this._eventStream = eventStream; // register commands let d1 = vscode.commands.registerCommand( 'dotnet.test.run', - (testMethod, fileName, testFrameworkName) => this._runDotnetTest(testMethod, fileName, testFrameworkName)); + async (testMethod, fileName, testFrameworkName) => this._runDotnetTest(testMethod, fileName, testFrameworkName)); let d2 = vscode.commands.registerCommand( 'dotnet.test.debug', - (testMethod, fileName, testFrameworkName) => this._debugDotnetTest(testMethod, fileName, testFrameworkName)); + async (testMethod, fileName, testFrameworkName) => this._debugDotnetTest(testMethod, fileName, testFrameworkName)); + + let d4 = vscode.commands.registerCommand( + 'dotnet.classTests.run', + async (methodsInClass, fileName, testFrameworkName) => this._runDotnetTestsInClass(methodsInClass, fileName, testFrameworkName)); + + let d5 = vscode.commands.registerCommand( + 'dotnet.classTests.debug', + async (methodsInClass, fileName, testFrameworkName) => this._debugDotnetTestsInClass(methodsInClass, fileName, testFrameworkName)); this._telemetryIntervalId = setInterval(() => this._reportTelemetry(), TelemetryReportingDelay); @@ -48,7 +60,7 @@ export default class TestManager extends AbstractProvider { } }); - this.addDisposables(d1, d2, d3); + this.addDisposables(d1, d2, d3, d4, d5); } private _getOutputChannel(): vscode.OutputChannel { @@ -95,24 +107,17 @@ export default class TestManager extends AbstractProvider { } private _reportTelemetry(): void { - if (this._runCounts) { - this._reporter.sendTelemetryEvent('RunTest', null, this._runCounts); - } - - if (this._debugCounts) { - this._reporter.sendTelemetryEvent('DebugTest', null, this._debugCounts); - } - + this._eventStream.post(new TestExecutionCountReport(this._debugCounts, this._runCounts)); this._runCounts = undefined; this._debugCounts = undefined; } - private _saveDirtyFiles(): Promise { + private async _saveDirtyFiles(): Promise { return Promise.resolve( vscode.workspace.saveAll(/*includeUntitled*/ false)); } - private _runTest(fileName: string, testMethod: string, testFrameworkName: string, targetFrameworkVersion: string): Promise { + private async _runTest(fileName: string, testMethod: string, testFrameworkName: string, targetFrameworkVersion: string): Promise { const request: protocol.V2.RunTestRequest = { FileName: fileName, MethodName: testMethod, @@ -124,11 +129,13 @@ export default class TestManager extends AbstractProvider { .then(response => response.Results); } - private _reportResults(results: protocol.V2.DotNetTestResult[]): Promise { + private async _reportResults(results: protocol.V2.DotNetTestResult[]): Promise { const totalTests = results.length; + const output = this._getOutputChannel(); let totalPassed = 0, totalFailed = 0, totalSkipped = 0; for (let result of results) { + output.appendLine(`${result.MethodName}: ${result.Outcome}`); switch (result.Outcome) { case protocol.V2.TestOutcomes.Failed: totalFailed += 1; @@ -142,7 +149,6 @@ export default class TestManager extends AbstractProvider { } } - const output = this._getOutputChannel(); output.appendLine(''); output.appendLine(`Total tests: ${totalTests}. Passed: ${totalPassed}. Failed: ${totalFailed}. Skipped: ${totalSkipped}`); output.appendLine(''); @@ -150,7 +156,28 @@ export default class TestManager extends AbstractProvider { return Promise.resolve(); } - private _runDotnetTest(testMethod: string, fileName: string, testFrameworkName: string) { + private async _recordRunAndGetFrameworkVersion(fileName: string, testFrameworkName: string) { + + await this._saveDirtyFiles(); + this._recordRunRequest(testFrameworkName); + let projectInfo = await serverUtils.requestProjectInformation(this._server, { FileName: fileName }); + + let targetFrameworkVersion: string; + + if (projectInfo.DotNetProject) { + targetFrameworkVersion = undefined; + } + else if (projectInfo.MsBuildProject) { + targetFrameworkVersion = projectInfo.MsBuildProject.TargetFramework; + } + else { + throw new Error('Expected project.json or .csproj project.'); + } + + return targetFrameworkVersion; + } + + private async _runDotnetTest(testMethod: string, fileName: string, testFrameworkName: string) { const output = this._getOutputChannel(); output.show(); @@ -161,26 +188,10 @@ export default class TestManager extends AbstractProvider { output.appendLine(e.Message); }); - this._saveDirtyFiles() - .then(_ => this._recordRunRequest(testFrameworkName)) - .then(_ => serverUtils.requestProjectInformation(this._server, { FileName: fileName })) - .then(projectInfo => - { - let targetFrameworkVersion: string; + let targetFrameworkVersion = await this._recordRunAndGetFrameworkVersion(fileName, testFrameworkName); - if (projectInfo.DotNetProject) { - targetFrameworkVersion = undefined; - } - else if (projectInfo.MsBuildProject) { - targetFrameworkVersion = projectInfo.MsBuildProject.TargetFramework; - } - else { - throw new Error('Expected project.json or .csproj project.'); - } - - return this._runTest(fileName, testMethod, testFrameworkName, targetFrameworkVersion); - }) - .then(results => this._reportResults(results)) + return this._runTest(fileName, testMethod, testFrameworkName, targetFrameworkVersion) + .then(async results => this._reportResults(results)) .then(() => listener.dispose()) .catch(reason => { listener.dispose(); @@ -188,6 +199,37 @@ export default class TestManager extends AbstractProvider { }); } + private async _runDotnetTestsInClass(methodsInClass: string[], fileName: string, testFrameworkName: string) { + const output = this._getOutputChannel(); + + output.show(); + const listener = this._server.onTestMessage(e => { + output.appendLine(e.Message); + }); + + let targetFrameworkVersion = await this._recordRunAndGetFrameworkVersion(fileName, testFrameworkName); + + return this._runTestsInClass(fileName, testFrameworkName, targetFrameworkVersion, methodsInClass) + .then(async results => this._reportResults(results)) + .then(() => listener.dispose()) + .catch(reason => { + listener.dispose(); + vscode.window.showErrorMessage(`Failed to run tests because ${reason}.`); + }); + } + + private async _runTestsInClass(fileName: string, testFrameworkName: string, targetFrameworkVersion: string, methodsToRun: string[]): Promise { + const request: protocol.V2.RunTestsInClassRequest = { + FileName: fileName, + TestFrameworkName: testFrameworkName, + TargetFrameworkVersion: targetFrameworkVersion, + MethodNames: methodsToRun + }; + + return serverUtils.runTestsInClass(this._server, request) + .then(response => response.Results); + } + private _createLaunchConfiguration(program: string, args: string, cwd: string, debuggerEventsPipeName: string) { let debugOptions = vscode.workspace.getConfiguration('csharp').get('unitTestDebuggingOptions'); @@ -200,22 +242,29 @@ export default class TestManager extends AbstractProvider { result = {}; } - if (!result.type) { - result.type = "coreclr"; - } + let launchConfiguration: LaunchConfiguration = { + ...result, + type: result.type || "coreclr", + name: ".NET Test Launch", + request: "launch", + debuggerEventsPipeName: debuggerEventsPipeName, + program: program, + args: args, + cwd: cwd + }; + // Now fill in the rest of the options - result.name = ".NET Test Launch"; - result.request = "launch"; - result.debuggerEventsPipeName = debuggerEventsPipeName; - result.program = program; - result.args = args; - result.cwd = cwd; - - return result; + + return launchConfiguration; } - private _getLaunchConfigurationForVSTest(fileName: string, testMethod: string, testFrameworkName: string, targetFrameworkVersion: string, debugEventListener: DebugEventListener): Promise { + private async _getLaunchConfigurationForVSTest( + fileName: string, + testMethod: string, + testFrameworkName: string, + targetFrameworkVersion: string, + debugEventListener: DebugEventListener): Promise { const output = this._getOutputChannel(); // Listen for test messages while getting start info. @@ -233,11 +282,15 @@ export default class TestManager extends AbstractProvider { return serverUtils.debugTestGetStartInfo(this._server, request) .then(response => { listener.dispose(); - return this._createLaunchConfiguration(response.FileName, response.Arguments, response.WorkingDirectory, debugEventListener.pipePath()); + return this._createLaunchConfiguration( + response.FileName, + response.Arguments, + response.WorkingDirectory, + debugEventListener.pipePath()); }); } - private _getLaunchConfigurationForLegacy(fileName: string, testMethod: string, testFrameworkName: string, targetFrameworkVersion: string): Promise { + private async _getLaunchConfigurationForLegacy(fileName: string, testMethod: string, testFrameworkName: string, targetFrameworkVersion: string): Promise { const output = this._getOutputChannel(); // Listen for test messages while getting start info. @@ -259,7 +312,13 @@ export default class TestManager extends AbstractProvider { }); } - private _getLaunchConfiguration(debugType: string, fileName: string, testMethod: string, testFrameworkName: string, targetFrameworkVersion: string, debugEventListener: DebugEventListener): Promise { + private async _getLaunchConfiguration( + debugType: string, + fileName: string, + testMethod: string, + testFrameworkName: string, + targetFrameworkVersion: string, + debugEventListener: DebugEventListener): Promise { switch (debugType) { case 'legacy': return this._getLaunchConfigurationForLegacy(fileName, testMethod, testFrameworkName, targetFrameworkVersion); @@ -271,39 +330,64 @@ export default class TestManager extends AbstractProvider { } } - private _debugDotnetTest(testMethod: string, fileName: string, testFrameworkName: string) { - // We support to styles of 'dotnet test' for debugging: The legacy 'project.json' testing, and the newer csproj support - // using VS Test. These require a different level of communication. + private async _recordDebugAndGetDebugValues(fileName: string, testFrameworkName: string, output: vscode.OutputChannel) { + await this._saveDirtyFiles(); + this._recordDebugRequest(testFrameworkName); + let projectInfo = await serverUtils.requestProjectInformation(this._server, { FileName: fileName }); + let debugType: string; let debugEventListener: DebugEventListener = null; let targetFrameworkVersion: string; + if (projectInfo.DotNetProject) { + debugType = 'legacy'; + targetFrameworkVersion = ''; + } + else if (projectInfo.MsBuildProject) { + debugType = 'vstest'; + targetFrameworkVersion = projectInfo.MsBuildProject.TargetFramework; + debugEventListener = new DebugEventListener(fileName, this._server, output); + debugEventListener.start(); + } + else { + throw new Error('Expected project.json or .csproj project.'); + } + + return { debugType, debugEventListener, targetFrameworkVersion }; + } + + private async _debugDotnetTest(testMethod: string, fileName: string, testFrameworkName: string) { + // We support to styles of 'dotnet test' for debugging: The legacy 'project.json' testing, and the newer csproj support + // using VS Test. These require a different level of communication. + const output = this._getOutputChannel(); output.show(); output.appendLine(`Debugging method '${testMethod}'...`); output.appendLine(''); - return this._saveDirtyFiles() - .then(_ => this._recordDebugRequest(testFrameworkName)) - .then(_ => serverUtils.requestProjectInformation(this._server, { FileName: fileName })) - .then(projectInfo => { - if (projectInfo.DotNetProject) { - debugType = 'legacy'; - targetFrameworkVersion = ''; - return Promise.resolve(); - } - else if (projectInfo.MsBuildProject) { - debugType = 'vstest'; - targetFrameworkVersion = projectInfo.MsBuildProject.TargetFramework; - debugEventListener = new DebugEventListener(fileName, this._server, output); - return debugEventListener.start(); - } - else { - throw new Error('Expected project.json or .csproj project.'); - } + let { debugType, debugEventListener, targetFrameworkVersion } = await this._recordDebugAndGetDebugValues(fileName, testFrameworkName, output); + + return this._getLaunchConfiguration(debugType, fileName, testMethod, testFrameworkName, targetFrameworkVersion, debugEventListener) + .then(config => { + const workspaceFolder = vscode.workspace.getWorkspaceFolder(vscode.Uri.file(fileName)); + return vscode.debug.startDebugging(workspaceFolder, config); }) - .then(() => this._getLaunchConfiguration(debugType, fileName, testMethod, testFrameworkName, targetFrameworkVersion, debugEventListener)) + .catch(reason => { + vscode.window.showErrorMessage(`Failed to start debugger: ${reason}`); + if (debugEventListener != null) { + debugEventListener.close(); + } + }); + } + + private async _debugDotnetTestsInClass(methodsToRun: string[], fileName: string, testFrameworkName: string) { + + const output = this._getOutputChannel(); + + let { debugType, debugEventListener, targetFrameworkVersion } = await this._recordDebugAndGetDebugValues(fileName, testFrameworkName, output); + + return await this._getLaunchConfigurationForClass(debugType, fileName, methodsToRun, testFrameworkName, targetFrameworkVersion, debugEventListener) .then(config => { const workspaceFolder = vscode.workspace.getWorkspaceFolder(vscode.Uri.file(fileName)); return vscode.debug.startDebugging(workspaceFolder, config); @@ -315,6 +399,45 @@ export default class TestManager extends AbstractProvider { } }); } + + private async _getLaunchConfigurationForClass( + debugType: string, + fileName: string, + methodsToRun: string[], + testFrameworkName: string, + targetFrameworkVersion: string, + debugEventListener: DebugEventListener): Promise { + if (debugType == 'vstest') { + return this._getLaunchConfigurationForVSTestClass(fileName, methodsToRun, testFrameworkName, targetFrameworkVersion, debugEventListener); + } + throw new Error(`Unexpected debug type: ${debugType}`); + } + + private async _getLaunchConfigurationForVSTestClass( + fileName: string, + methodsToRun: string[], + testFrameworkName: string, + targetFrameworkVersion: string, + debugEventListener: DebugEventListener): Promise { + const output = this._getOutputChannel(); + + const listener = this._server.onTestMessage(e => { + output.appendLine(e.Message); + }); + + const request: protocol.V2.DebugTestClassGetStartInfoRequest = { + FileName: fileName, + MethodNames: methodsToRun, + TestFrameworkName: testFrameworkName, + TargetFrameworkVersion: targetFrameworkVersion + }; + + return serverUtils.debugTestClassGetStartInfo(this._server, request) + .then(response => { + listener.dispose(); + return this._createLaunchConfiguration(response.FileName, response.Arguments, response.WorkingDirectory, debugEventListener.pipePath()); + }); + } } class DebugEventListener { @@ -340,7 +463,7 @@ class DebugEventListener { } } - public start(): Promise { + public async start(): Promise { // We use our process id as part of the pipe name, so if we still somehow have an old instance running, close it. if (DebugEventListener.s_activeInstance !== null) { @@ -379,7 +502,7 @@ class DebugEventListener { }); }); - return this.removeSocketFileIfExists().then(() => { + return this.removeSocketFileIfExists().then(async () => { return new Promise((resolve, reject) => { let isStarted: boolean = false; this._serverSocket.on('error', (err: Error) => { @@ -448,7 +571,7 @@ class DebugEventListener { this.close(); } - private removeSocketFileIfExists(): Promise { + private async removeSocketFileIfExists(): Promise { if (os.platform() === 'win32') { // Win32 doesn't use the file system for pipe names return Promise.resolve(); diff --git a/src/features/formattingEditProvider.ts b/src/features/formattingEditProvider.ts index e5eabd487..07cfc02b7 100644 --- a/src/features/formattingEditProvider.ts +++ b/src/features/formattingEditProvider.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; - import AbstractSupport from './abstractProvider'; import * as protocol from '../omnisharp/protocol'; import * as serverUtils from '../omnisharp/utils'; @@ -12,7 +10,7 @@ import {DocumentRangeFormattingEditProvider, FormattingOptions, CancellationToke export default class FormattingSupport extends AbstractSupport implements DocumentRangeFormattingEditProvider { - public provideDocumentRangeFormattingEdits(document: TextDocument, range: Range, options: FormattingOptions, token: CancellationToken): Promise { + public async provideDocumentRangeFormattingEdits(document: TextDocument, range: Range, options: FormattingOptions, token: CancellationToken): Promise { let request = { FileName: document.fileName, @@ -29,7 +27,7 @@ export default class FormattingSupport extends AbstractSupport implements Docume }); } - public provideOnTypeFormattingEdits(document: TextDocument, position: Position, ch: string, options: FormattingOptions, token: CancellationToken): Promise { + public async provideOnTypeFormattingEdits(document: TextDocument, position: Position, ch: string, options: FormattingOptions, token: CancellationToken): Promise { let request = { FileName: document.fileName, diff --git a/src/features/hoverProvider.ts b/src/features/hoverProvider.ts index 03c40d051..188e8bb0b 100644 --- a/src/features/hoverProvider.ts +++ b/src/features/hoverProvider.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; - import AbstractSupport from './abstractProvider'; import * as protocol from '../omnisharp/protocol'; import * as serverUtils from '../omnisharp/utils'; @@ -14,7 +12,7 @@ import { GetDocumentationString } from './documentation'; export default class OmniSharpHoverProvider extends AbstractSupport implements HoverProvider { - public provideHover(document: TextDocument, position: Position, token: CancellationToken): Promise { + public async provideHover(document: TextDocument, position: Position, token: CancellationToken): Promise { let req = createRequest(document, position); req.IncludeDocumentation = true; diff --git a/src/features/implementationProvider.ts b/src/features/implementationProvider.ts index 75c1261ac..4e8227f84 100644 --- a/src/features/implementationProvider.ts +++ b/src/features/implementationProvider.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; - import AbstractSupport from './abstractProvider'; import { FindImplementationsRequest } from '../omnisharp/protocol'; import * as serverUtils from '../omnisharp/utils'; diff --git a/src/features/json/NuGetFlatContainerPackageResponse.ts b/src/features/json/NuGetFlatContainerPackageResponse.ts new file mode 100644 index 000000000..0ba5559ed --- /dev/null +++ b/src/features/json/NuGetFlatContainerPackageResponse.ts @@ -0,0 +1,10 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + + // Sample Request: https://api.nuget.org/v3-flatcontainer/FluentAssertions/index.json + +export default interface NuGetFlatContainerPackageResponse { + versions: string[]; +} diff --git a/src/features/json/NuGetIndexResponse.ts b/src/features/json/NuGetIndexResponse.ts new file mode 100644 index 000000000..4055fd819 --- /dev/null +++ b/src/features/json/NuGetIndexResponse.ts @@ -0,0 +1,14 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +// Sample Request: https://api.nuget.org/v3/index.json + export default interface NuGetIndexResponse { + resources: NuGetResource[]; + } + + interface NuGetResource { + '@type': string; + '@id': string; + } \ No newline at end of file diff --git a/test/runVsCodeTestsWithAbsolutePaths.js b/src/features/json/NuGetSearchAutocompleteServiceResponse.ts similarity index 54% rename from test/runVsCodeTestsWithAbsolutePaths.js rename to src/features/json/NuGetSearchAutocompleteServiceResponse.ts index a4a5176cb..d9f85dbae 100644 --- a/test/runVsCodeTestsWithAbsolutePaths.js +++ b/src/features/json/NuGetSearchAutocompleteServiceResponse.ts @@ -1,15 +1,10 @@ -#!/usr/bin/env node - /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -path=require('path'); +// Sample Query: https://api-v2v3search-0.nuget.org/autocomplete -if (process.env.CODE_TESTS_PATH - && process.env.CODE_TESTS_PATH.startsWith('.')){ - process.env.CODE_TESTS_PATH = path.join(process.cwd(), process.env.CODE_TESTS_PATH.substr(2)); + export default interface NuGetSearchAutocompleteServiceResponse { + data: string[]; } - -require(path.resolve(__dirname, '../node_modules/vscode/bin/test')); \ No newline at end of file diff --git a/src/features/json/NuGetSearchQueryServiceResponse.ts b/src/features/json/NuGetSearchQueryServiceResponse.ts new file mode 100644 index 000000000..2ff9522e0 --- /dev/null +++ b/src/features/json/NuGetSearchQueryServiceResponse.ts @@ -0,0 +1,16 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +// Sample Request: https://api-v2v3search-0.nuget.org/query?q=newtonsoft.json&take=5 + +export default interface NuGetSearchQueryServiceResponse { + data: NuGetSearchQueryServiceDataElement[]; +} + +interface NuGetSearchQueryServiceDataElement { + id: string; + description: string; + version: string; +} \ No newline at end of file diff --git a/src/features/json/jsonContributions.ts b/src/features/json/jsonContributions.ts index 2bb4dd3a5..b35c54214 100644 --- a/src/features/json/jsonContributions.ts +++ b/src/features/json/jsonContributions.ts @@ -2,7 +2,6 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; import { Location, getLocation, createScanner, SyntaxKind } from 'jsonc-parser'; import { ProjectJSONContribution } from './projectJSONContribution'; @@ -23,9 +22,9 @@ export interface ISuggestionsCollector { export interface IJSONContribution { getDocumentSelector(): DocumentSelector; getInfoContribution(fileName: string, location: Location): Thenable; - collectPropertySuggestions(fileName: string, location: Location, currentWord: string, addValue: boolean, isLast: boolean, result: ISuggestionsCollector): Thenable; - collectValueSuggestions(fileName: string, location: Location, result: ISuggestionsCollector): Thenable; - collectDefaultSuggestions(fileName: string, result: ISuggestionsCollector): Thenable; + collectPropertySuggestions(fileName: string, location: Location, currentWord: string, addValue: boolean, isLast: boolean, result: ISuggestionsCollector): Thenable; + collectValueSuggestions(fileName: string, location: Location, result: ISuggestionsCollector): Thenable; + collectDefaultSuggestions(fileName: string, result: ISuggestionsCollector): Thenable; resolveSuggestion?(item: CompletionItem): Thenable; } @@ -96,7 +95,7 @@ export class JSONCompletionItemProvider implements CompletionItemProvider { public provideCompletionItems(document: TextDocument, position: Position, token: CancellationToken): Thenable { let currentWord = this.getCurrentWord(document, position); - let overwriteRange = null; + let overwriteRange: Range = null; let items: CompletionItem[] = []; let isIncomplete = false; @@ -127,7 +126,7 @@ export class JSONCompletionItemProvider implements CompletionItemProvider { log: (message: string) => console.log(message) }; - let collectPromise: Thenable = null; + let collectPromise: Thenable = null; if (location.isAtPropertyKey) { let addValue = !location.previousNode || !location.previousNode.columnOffset && (offset == (location.previousNode.offset + location.previousNode.length)); diff --git a/src/features/json/projectJSONContribution.ts b/src/features/json/projectJSONContribution.ts index b22f127df..510499b16 100644 --- a/src/features/json/projectJSONContribution.ts +++ b/src/features/json/projectJSONContribution.ts @@ -2,7 +2,6 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; import * as nls from 'vscode-nls'; @@ -11,6 +10,10 @@ import { IJSONContribution, ISuggestionsCollector } from './jsonContributions'; import { XHRRequest, XHRResponse, getErrorStatusDescription } from 'request-light'; import { Location } from 'jsonc-parser'; +import NuGetIndexResponse from './NuGetIndexResponse'; +import NuGetSearchAutocompleteServiceResponse from './NuGetSearchAutocompleteServiceResponse'; +import NuGetFlatContainerPackageResponse from './NuGetFlatContainerPackageResponse'; +import NuGetSearchQueryServiceResponse from './NuGetSearchQueryServiceResponse'; const localize = nls.loadMessageBundle(); @@ -37,10 +40,10 @@ export class ProjectJSONContribution implements IJSONContribution { private getNugetIndex(): Thenable { if (!this.nugetIndexPromise) { - this.nugetIndexPromise = this.makeJSONRequest(FEED_INDEX_URL).then(indexContent => { + this.nugetIndexPromise = this.makeJSONRequest(FEED_INDEX_URL).then(indexContent => { let services: NugetServices = {}; if (indexContent && Array.isArray(indexContent.resources)) { - let resources = indexContent.resources; + let resources = indexContent.resources; for (let i = resources.length - 1; i >= 0; i--) { let type = resources[i]['@type']; let id = resources[i]['@id']; @@ -77,12 +80,18 @@ export class ProjectJSONContribution implements IJSONContribution { } } return Promise.reject(localize('json.nugget.error.indexaccess', 'Request to {0} failed: {1}', url, success.responseText)); - }, (error: XHRResponse) => { + }, async (error: XHRResponse) => { return Promise.reject(localize('json.nugget.error.access', 'Request to {0} failed: {1}', url, getErrorStatusDescription(error.status))); }); } - public collectPropertySuggestions(resource: string, location: Location, currentWord: string, addValue: boolean, isLast: boolean, result: ISuggestionsCollector): Thenable { + public collectPropertySuggestions( + resource: string, + location: Location, + currentWord: string, + addValue: boolean, + isLast: boolean, + result: ISuggestionsCollector): Thenable { if ((location.matches(['dependencies']) || location.matches(['frameworks', '*', 'dependencies']) || location.matches(['frameworks', '*', 'frameworkAssemblies']))) { return this.getNugetService('SearchAutocompleteService').then(service => { @@ -92,9 +101,9 @@ export class ProjectJSONContribution implements IJSONContribution { } else { queryUrl = service + '?take=' + LIMIT; } - return this.makeJSONRequest(queryUrl).then(resultObj => { + return this.makeJSONRequest(queryUrl).then(resultObj => { if (Array.isArray(resultObj.data)) { - let results = resultObj.data; + let results = resultObj.data; for (let i = 0; i < results.length; i++) { let name = results[i]; let insertText = JSON.stringify(name); @@ -124,15 +133,15 @@ export class ProjectJSONContribution implements IJSONContribution { return null; } - public collectValueSuggestions(resource: string, location: Location, result: ISuggestionsCollector): Thenable { + public collectValueSuggestions(resource: string, location: Location, result: ISuggestionsCollector): Thenable { if ((location.matches(['dependencies', '*']) || location.matches(['frameworks', '*', 'dependencies', '*']) || location.matches(['frameworks', '*', 'frameworkAssemblies', '*']))) { return this.getNugetService('PackageBaseAddress/3.0.0').then(service => { let currentKey = location.path[location.path.length - 1]; if (typeof currentKey === 'string') { let queryUrl = service + currentKey + '/index.json'; - return this.makeJSONRequest(queryUrl).then(obj => { + return this.makeJSONRequest(queryUrl).then(obj => { if (Array.isArray(obj.versions)) { - let results = obj.versions; + let results = obj.versions; for (let i = 0; i < results.length; i++) { let curr = results[i]; let name = JSON.stringify(curr); @@ -157,7 +166,7 @@ export class ProjectJSONContribution implements IJSONContribution { return null; } - public collectDefaultSuggestions(resource: string, result: ISuggestionsCollector): Thenable { + public collectDefaultSuggestions(resource: string, result: ISuggestionsCollector): Thenable { let defaultValue = { 'version': '{{1.0.0-*}}', 'dependencies': {}, @@ -193,9 +202,9 @@ export class ProjectJSONContribution implements IJSONContribution { private getInfo(pack: string): Thenable<{ description?: string; version?: string }> { return this.getNugetService('SearchQueryService').then(service => { let queryUrl = service + '?q=' + encodeURIComponent(pack) + '&take=' + 5; - return this.makeJSONRequest(queryUrl).then(resultObj => { + return this.makeJSONRequest(queryUrl).then(resultObj => { if (Array.isArray(resultObj.data)) { - let results = resultObj.data; + let results = resultObj.data; let info: { description?: string; version?: string } = {}; for (let i = 0; i < results.length; i++) { let res = results[i]; diff --git a/src/features/launchConfiguration.ts b/src/features/launchConfiguration.ts new file mode 100644 index 000000000..52d69e674 --- /dev/null +++ b/src/features/launchConfiguration.ts @@ -0,0 +1,13 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { DebugConfiguration } from "vscode"; + +export default interface LaunchConfiguration extends DebugConfiguration { + debuggerEventsPipeName?: string; + program?: string; + args?: string; + cwd?: string; +} \ No newline at end of file diff --git a/src/features/processPicker.ts b/src/features/processPicker.ts index 1a2d4fb0d..08df45c15 100644 --- a/src/features/processPicker.ts +++ b/src/features/processPicker.ts @@ -23,7 +23,7 @@ export interface AttachItemsProvider { export class AttachPicker { constructor(private attachItemsProvider: AttachItemsProvider) { } - public ShowAttachEntries(): Promise { + public async ShowAttachEntries(): Promise { return this.attachItemsProvider.getAttachItems() .then(processEntries => { let attachPickOptions: vscode.QuickPickOptions = { @@ -56,7 +56,7 @@ export class RemoteAttachPicker { private static _channel: vscode.OutputChannel = null; - public static ValidateAndFixPipeProgram(program: string): Promise { + public static async ValidateAndFixPipeProgram(program: string): Promise { return PlatformInformation.GetCurrent().then(platformInfo => { // Check if we are on a 64 bit Windows if (platformInfo.isWindows() && platformInfo.architecture === "x86_64") { @@ -122,8 +122,8 @@ export class RemoteAttachPicker { } // Creates a pipe command string based on the type of pipe args. - private static createPipeCmd(pipeProgram: string, pipeArgs: string | string[], quoteArgs: boolean): Promise { - return this.ValidateAndFixPipeProgram(pipeProgram).then(fixedPipeProgram => { + private static async createPipeCmd(pipeProgram: string, pipeArgs: string | string[], quoteArgs: boolean): Promise { + return this.ValidateAndFixPipeProgram(pipeProgram).then(async fixedPipeProgram => { if (typeof pipeArgs === "string") { return Promise.resolve(this.createPipeCmdFromString(fixedPipeProgram, pipeArgs, quoteArgs)); } @@ -191,7 +191,7 @@ export class RemoteAttachPicker { return args.map(arg => this.quoteArg(arg)).join(" "); } - public static ShowAttachEntries(args: any): Promise { + public static async ShowAttachEntries(args: any): Promise { // Create remote attach output channel for errors. if (!RemoteAttachPicker._channel) { RemoteAttachPicker._channel = vscode.window.createOutputChannel('remote-attach'); @@ -216,7 +216,7 @@ export class RemoteAttachPicker { let pipeTransport = this.getPipeTransportOptions(args.pipeTransport, os.platform()); return RemoteAttachPicker.createPipeCmd(pipeTransport.pipeProgram, pipeTransport.pipeArgs, pipeTransport.quoteArgs) - .then(pipeCmd => RemoteAttachPicker.getRemoteOSAndProcesses(pipeCmd)) + .then(async pipeCmd => RemoteAttachPicker.getRemoteOSAndProcesses(pipeCmd)) .then(processes => { let attachPickOptions: vscode.QuickPickOptions = { matchOnDescription: true, @@ -229,7 +229,7 @@ export class RemoteAttachPicker { } } - public static getRemoteOSAndProcesses(pipeCmd: string): Promise { + public static async getRemoteOSAndProcesses(pipeCmd: string): Promise { const scriptPath = path.join(getExtensionPath(), 'scripts', 'remoteProcessPickerScript'); return execChildProcessAndOutputErrorToChannel(`${pipeCmd} < ${scriptPath}`, null, RemoteAttachPicker._channel).then(output => { @@ -286,7 +286,7 @@ export class DotNetAttachItemsProviderFactory { abstract class DotNetAttachItemsProvider implements AttachItemsProvider { protected abstract getInternalProcessEntries(): Promise; - getAttachItems(): Promise { + async getAttachItems(): Promise { return this.getInternalProcessEntries().then(processEntries => { return sortProcessEntries(processEntries, os.platform()); }); @@ -314,7 +314,7 @@ function sortProcessEntries(processEntries: Process[], osPlatform: string): Atta } export class PsAttachItemsProvider extends DotNetAttachItemsProvider { - protected getInternalProcessEntries(): Promise { + protected async getInternalProcessEntries(): Promise { // the BSD version of ps uses '-c' to have 'comm' only output the executable name and not // the full path. The Linux version of ps has 'comm' to only display the name of the executable // Note that comm on Linux systems is truncated to 16 characters: @@ -414,7 +414,7 @@ export class PsOutputParser { } export class WmicAttachItemsProvider extends DotNetAttachItemsProvider { - protected getInternalProcessEntries(): Promise { + protected async getInternalProcessEntries(): Promise { const wmicCommand = 'wmic process get Name,ProcessId,CommandLine /FORMAT:list'; return execChildProcess(wmicCommand, null).then(processes => { return WmicOutputParser.parseProcessFromWmic(processes); @@ -483,7 +483,7 @@ export class WmicOutputParser { } -function execChildProcess(process: string, workingDirectory: string): Promise { +async function execChildProcess(process: string, workingDirectory: string): Promise { return new Promise((resolve, reject) => { child_process.exec(process, { cwd: workingDirectory, maxBuffer: 500 * 1024 }, (error: Error, stdout: string, stderr: string) => { if (error) { @@ -504,7 +504,7 @@ function execChildProcess(process: string, workingDirectory: string): Promise { +async function GetSysNativePathIfNeeded(): Promise { return PlatformInformation.GetCurrent().then(platformInfo => { let env = process.env; if (platformInfo.isWindows() && platformInfo.architecture === "x86_64") { @@ -516,10 +516,10 @@ function GetSysNativePathIfNeeded(): Promise { }); } -function execChildProcessAndOutputErrorToChannel(process: string, workingDirectory: string, channel: vscode.OutputChannel): Promise { +async function execChildProcessAndOutputErrorToChannel(process: string, workingDirectory: string, channel: vscode.OutputChannel): Promise { channel.appendLine(`Executing: ${process}`); - return new Promise((resolve, reject) => { + return new Promise(async (resolve, reject) => { return GetSysNativePathIfNeeded().then(newEnv => { child_process.exec(process, { cwd: workingDirectory, env: newEnv, maxBuffer: 500 * 1024 }, (error: Error, stdout: string, stderr: string) => { let channelOutput = ""; diff --git a/src/features/referenceProvider.ts b/src/features/referenceProvider.ts index a9cb97345..75a871f3e 100644 --- a/src/features/referenceProvider.ts +++ b/src/features/referenceProvider.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; - import AbstractSupport from './abstractProvider'; import * as protocol from '../omnisharp/protocol'; import * as serverUtils from '../omnisharp/utils'; @@ -13,7 +11,7 @@ import {ReferenceProvider, Location, TextDocument, CancellationToken, Position} export default class OmnisharpReferenceProvider extends AbstractSupport implements ReferenceProvider { - public provideReferences(document: TextDocument, position: Position, options: { includeDeclaration: boolean;}, token: CancellationToken): Promise { + public async provideReferences(document: TextDocument, position: Position, options: { includeDeclaration: boolean;}, token: CancellationToken): Promise { let req = createRequest(document, position); req.OnlyThisFile = false; diff --git a/src/features/renameProvider.ts b/src/features/renameProvider.ts index f3d820097..3e774c996 100644 --- a/src/features/renameProvider.ts +++ b/src/features/renameProvider.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; - import AbstractSupport from './abstractProvider'; import * as protocol from '../omnisharp/protocol'; import * as serverUtils from '../omnisharp/utils'; @@ -13,7 +11,7 @@ import {RenameProvider, WorkspaceEdit, TextDocument, Uri, CancellationToken, Pos export default class OmnisharpRenameProvider extends AbstractSupport implements RenameProvider { - public provideRenameEdits(document: TextDocument, position: Position, newName: string, token: CancellationToken): Promise { + public async provideRenameEdits(document: TextDocument, position: Position, newName: string, token: CancellationToken): Promise { let req = createRequest(document, position); req.WantsTextChanges = true; diff --git a/src/features/signatureHelpProvider.ts b/src/features/signatureHelpProvider.ts index f7c4bed0f..180c6f9a7 100644 --- a/src/features/signatureHelpProvider.ts +++ b/src/features/signatureHelpProvider.ts @@ -3,22 +3,21 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; - import AbstractSupport from './abstractProvider'; import * as serverUtils from '../omnisharp/utils'; -import {extractSummaryText} from './documentation'; -import {createRequest} from '../omnisharp/typeConvertion'; -import {SignatureHelpProvider, SignatureHelp, SignatureInformation, ParameterInformation, CancellationToken, TextDocument, Position} from 'vscode'; +import { createRequest } from '../omnisharp/typeConvertion'; +import { SignatureHelpProvider, SignatureHelp, SignatureInformation, ParameterInformation, CancellationToken, TextDocument, Position } from 'vscode'; +import { MarkdownString } from 'vscode'; +import { SignatureHelpParameter } from '../omnisharp/protocol'; export default class OmniSharpSignatureHelpProvider extends AbstractSupport implements SignatureHelpProvider { - public provideSignatureHelp(document: TextDocument, position: Position, token: CancellationToken): Promise { + public async provideSignatureHelp(document: TextDocument, position: Position, token: CancellationToken): Promise { let req = createRequest(document, position); return serverUtils.signatureHelp(this._server, req, token).then(res => { - + if (!res) { return undefined; } @@ -29,13 +28,13 @@ export default class OmniSharpSignatureHelpProvider extends AbstractSupport impl for (let signature of res.Signatures) { - let signatureInfo = new SignatureInformation(signature.Label, extractSummaryText(signature.Documentation)); + let signatureInfo = new SignatureInformation(signature.Label, signature.StructuredDocumentation.SummaryText); ret.signatures.push(signatureInfo); for (let parameter of signature.Parameters) { let parameterInfo = new ParameterInformation( parameter.Label, - extractSummaryText(parameter.Documentation)); + this.GetParameterDocumentation(parameter)); signatureInfo.parameters.push(parameterInfo); } @@ -44,4 +43,14 @@ export default class OmniSharpSignatureHelpProvider extends AbstractSupport impl return ret; }); } + + private GetParameterDocumentation(parameter: SignatureHelpParameter) { + let summary = parameter.Documentation; + if (summary.length > 0) { + let paramText = `**${parameter.Name}**: ${summary}`; + return new MarkdownString(paramText); + } + + return ""; + } } diff --git a/src/features/status.ts b/src/features/status.ts deleted file mode 100644 index 98a4a2644..000000000 --- a/src/features/status.ts +++ /dev/null @@ -1,296 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -'use strict'; - -import * as vscode from 'vscode'; -import {OmniSharpServer} from '../omnisharp/server'; -import {dotnetRestoreForProject} from './commands'; -import {basename} from 'path'; -import * as protocol from '../omnisharp/protocol'; -import * as serverUtils from '../omnisharp/utils'; - -const debounce = require('lodash.debounce'); - -export default function reportStatus(server: OmniSharpServer) { - return vscode.Disposable.from( - reportServerStatus(server), - forwardOutput(server), - reportDocumentStatus(server)); -} - -// --- document status - -let defaultSelector: vscode.DocumentSelector = [ - 'csharp', // c#-files OR - { pattern: '**/project.json' }, // project.json-files OR - { pattern: '**/*.sln' }, // any solution file OR - { pattern: '**/*.csproj' }, // an csproj file - { pattern: '**/*.csx' }, // C# script - { pattern: '**/*.cake' } // Cake script -]; - -class Status { - - selector: vscode.DocumentSelector; - text: string; - command: string; - color: string; - - constructor(selector: vscode.DocumentSelector) { - this.selector = selector; - } -} - -export function reportDocumentStatus(server: OmniSharpServer): vscode.Disposable { - - let disposables: vscode.Disposable[] = []; - let localDisposables: vscode.Disposable[]; - - let entry = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, Number.MIN_VALUE); - let defaultStatus = new Status(defaultSelector); - let projectStatus: Status; - - function render() { - - if (!vscode.window.activeTextEditor) { - entry.hide(); - return; - } - - let document = vscode.window.activeTextEditor.document; - let status: Status; - - if (projectStatus && vscode.languages.match(projectStatus.selector, document)) { - status = projectStatus; - } else if (defaultStatus.text && vscode.languages.match(defaultStatus.selector, document)) { - status = defaultStatus; - } - - if (status) { - entry.text = status.text; - entry.command = status.command; - entry.color = status.color; - entry.show(); - return; - } - - entry.hide(); - } - - disposables.push(vscode.window.onDidChangeActiveTextEditor(render)); - - disposables.push(server.onServerError(err => { - defaultStatus.text = '$(flame) Error starting OmniSharp'; - defaultStatus.command = 'o.showOutput'; - defaultStatus.color = ''; - render(); - })); - - disposables.push(server.onMultipleLaunchTargets(targets => { - defaultStatus.text = '$(flame) Select project'; - defaultStatus.command = 'o.pickProjectAndStart'; - defaultStatus.color = 'rgb(90, 218, 90)'; - render(); - })); - - disposables.push(server.onBeforeServerInstall(() => { - defaultStatus.text = '$(flame) Installing OmniSharp...'; - defaultStatus.command = 'o.showOutput'; - defaultStatus.color = ''; - render(); - })); - - disposables.push(server.onBeforeServerStart(path => { - defaultStatus.text = '$(flame) Starting...'; - defaultStatus.command = 'o.showOutput'; - defaultStatus.color = ''; - render(); - })); - - disposables.push(server.onServerStop(() => { - projectStatus = undefined; - defaultStatus.text = undefined; - - if (localDisposables) { - vscode.Disposable.from(...localDisposables).dispose(); - } - - localDisposables = undefined; - })); - - disposables.push(server.onServerStart(path => { - localDisposables = []; - - defaultStatus.text = '$(flame) Running'; - defaultStatus.command = 'o.pickProjectAndStart'; - defaultStatus.color = ''; - render(); - - function updateProjectInfo() { - serverUtils.requestWorkspaceInformation(server).then(info => { - - interface Project { - Path: string; - SourceFiles: string[]; - } - - let fileNames: vscode.DocumentFilter[] = []; - let label: string; - - function addProjectFileNames(project: Project) { - fileNames.push({ pattern: project.Path }); - - if (project.SourceFiles) { - for (let sourceFile of project.SourceFiles) { - fileNames.push({ pattern: sourceFile }); - } - } - } - - function addDnxOrDotNetProjects(projects: Project[]) { - let count = 0; - - for (let project of projects) { - count += 1; - addProjectFileNames(project); - } - - if (!label) { - if (count === 1) { - label = basename(projects[0].Path); //workspace.getRelativePath(info.Dnx.Projects[0].Path); - } - else { - label = `${count} projects`; - } - } - } - - // show sln-file if applicable - if (info.MsBuild && info.MsBuild.SolutionPath) { - label = basename(info.MsBuild.SolutionPath); //workspace.getRelativePath(info.MsBuild.SolutionPath); - fileNames.push({ pattern: info.MsBuild.SolutionPath }); - - for (let project of info.MsBuild.Projects) { - addProjectFileNames(project); - } - } - - // show .NET Core projects if applicable - if (info.DotNet) { - addDnxOrDotNetProjects(info.DotNet.Projects); - } - - // set project info - projectStatus = new Status(fileNames); - projectStatus.text = '$(flame) ' + label; - projectStatus.command = 'o.pickProjectAndStart'; - - // default is to change project - defaultStatus.text = '$(flame) Switch projects'; - defaultStatus.command = 'o.pickProjectAndStart'; - render(); - }); - } - - // Don't allow the same request to slam the server within a "short" window - let debouncedUpdateProjectInfo = debounce(updateProjectInfo, 1500, { leading: true }); - localDisposables.push(server.onProjectAdded(debouncedUpdateProjectInfo)); - localDisposables.push(server.onProjectChange(debouncedUpdateProjectInfo)); - localDisposables.push(server.onProjectRemoved(debouncedUpdateProjectInfo)); - })); - - return vscode.Disposable.from(...disposables); -} - - -// ---- server status - -export function reportServerStatus(server: OmniSharpServer): vscode.Disposable{ - - function appendLine(value: string = '') { - server.getChannel().appendLine(value); - } - - let d0 = server.onServerError(err => { - appendLine('[ERROR] ' + err); - }); - - let d1 = server.onError(message => { - if (message.FileName) { - appendLine(`${message.FileName}(${message.Line},${message.Column})`); - } - appendLine(message.Text); - appendLine(); - showMessageSoon(); - }); - - let d2 = server.onMsBuildProjectDiagnostics(message => { - - function asErrorMessage(message: protocol.MSBuildDiagnosticsMessage) { - let value = `${message.FileName}(${message.StartLine},${message.StartColumn}): Error: ${message.Text}`; - appendLine(value); - } - - function asWarningMessage(message: protocol.MSBuildDiagnosticsMessage) { - let value = `${message.FileName}(${message.StartLine},${message.StartColumn}): Warning: ${message.Text}`; - appendLine(value); - } - - if (message.Errors.length > 0 || message.Warnings.length > 0) { - appendLine(message.FileName); - message.Errors.forEach(error => asErrorMessage); - message.Warnings.forEach(warning => asWarningMessage); - appendLine(); - - if (message.Errors.length > 0) { - showMessageSoon(); - } - } - }); - - let d3 = server.onUnresolvedDependencies(message => { - let csharpConfig = vscode.workspace.getConfiguration('csharp'); - if (!csharpConfig.get('suppressDotnetRestoreNotification')) { - let info = `There are unresolved dependencies from '${vscode.workspace.asRelativePath(message.FileName) }'. Please execute the restore command to continue.`; - - return vscode.window.showInformationMessage(info, 'Restore').then(value => { - if (value) { - dotnetRestoreForProject(server, message.FileName); - } - }); - } - }); - - return vscode.Disposable.from(d0, d1, d2, d3); -} - -// show user message -let _messageHandle: NodeJS.Timer; -function showMessageSoon() { - clearTimeout(_messageHandle); - _messageHandle = setTimeout(function() { - - let message = "Some projects have trouble loading. Please review the output for more details."; - vscode.window.showWarningMessage(message, { title: "Show Output", command: 'o.showOutput' }).then(value => { - if (value) { - vscode.commands.executeCommand(value.command); - } - }); - }, 1500); -} - -// --- mirror output in channel - -function forwardOutput(server: OmniSharpServer) { - - const logChannel = server.getChannel(); - - function forward(message: string) { - logChannel.append(message); - } - - return vscode.Disposable.from( - server.onStderr(forward)); -} \ No newline at end of file diff --git a/src/features/workspaceSymbolProvider.ts b/src/features/workspaceSymbolProvider.ts index b87b699f8..37ddb5aaf 100644 --- a/src/features/workspaceSymbolProvider.ts +++ b/src/features/workspaceSymbolProvider.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; - import AbstractSupport from './abstractProvider'; import * as protocol from '../omnisharp/protocol'; import * as serverUtils from '../omnisharp/utils'; @@ -14,7 +12,7 @@ import {CancellationToken, Uri, WorkspaceSymbolProvider, SymbolInformation, Symb export default class OmnisharpWorkspaceSymbolProvider extends AbstractSupport implements WorkspaceSymbolProvider { - public provideWorkspaceSymbols(search: string, token: CancellationToken): Promise { + public async provideWorkspaceSymbols(search: string, token: CancellationToken): Promise { return serverUtils.findSymbols(this._server, { Filter: search, FileName: '' }, token).then(res => { if (res && Array.isArray(res.QuickFixes)) { diff --git a/src/json.ts b/src/json.ts index 81f9055ea..fc42143fa 100644 --- a/src/json.ts +++ b/src/json.ts @@ -144,7 +144,8 @@ function cleanJsonText(text: string) { // We just skip the byte-order mark parts.push(text.substring(partStart, index - 1)); partStart = index; - + break; + // strings case CharCode.doubleQuote: scanString(); @@ -200,6 +201,7 @@ function cleanJsonText(text: string) { } break; + default: } if (index >= length && index > partStart) { diff --git a/src/main.ts b/src/main.ts index 7301d7904..7337da393 100644 --- a/src/main.ts +++ b/src/main.ts @@ -8,55 +8,121 @@ import * as coreclrdebug from './coreclr-debug/activate'; import * as util from './common'; import * as vscode from 'vscode'; +import { ActivationFailure, ActiveTextEditorChanged } from './omnisharp/loggingEvents'; +import { WarningMessageObserver } from './observers/WarningMessageObserver'; import { CSharpExtDownloader } from './CSharpExtDownloader'; -import { Logger } from './logger'; +import { CsharpChannelObserver } from './observers/CsharpChannelObserver'; +import { CsharpLoggerObserver } from './observers/CsharpLoggerObserver'; +import { DotNetChannelObserver } from './observers/DotnetChannelObserver'; +import { DotnetLoggerObserver } from './observers/DotnetLoggerObserver'; +import { EventStream } from './EventStream'; +import { InformationMessageObserver } from './observers/InformationMessageObserver'; +import { OmnisharpChannelObserver } from './observers/OmnisharpChannelObserver'; +import { OmnisharpDebugModeLoggerObserver } from './observers/OmnisharpDebugModeLoggerObserver'; +import { OmnisharpLoggerObserver } from './observers/OmnisharpLoggerObserver'; +import { OmnisharpStatusBarObserver } from './observers/OmnisharpStatusBarObserver'; +import { PlatformInformation } from './platform'; +import { StatusBarItemAdapter } from './statusBarItemAdapter'; +import { TelemetryObserver } from './observers/TelemetryObserver'; import TelemetryReporter from 'vscode-extension-telemetry'; import { addJSONProviders } from './features/json/jsonContributions'; +import { ProjectStatusBarObserver } from './observers/ProjectStatusBarObserver'; +import CSharpExtensionExports from './CSharpExtensionExports'; +import { vscodeNetworkSettingsProvider, NetworkSettingsProvider } from './NetworkSettings'; -let _channel: vscode.OutputChannel = null; - -export async function activate(context: vscode.ExtensionContext): Promise<{ initializationFinished: Promise }> { +export async function activate(context: vscode.ExtensionContext): Promise { const extensionId = 'ms-vscode.csharp'; - const extension = vscode.extensions.getExtension(extensionId); + const extension = vscode.extensions.getExtension(extensionId); const extensionVersion = extension.packageJSON.version; const aiKey = extension.packageJSON.contributes.debuggers[0].aiKey; const reporter = new TelemetryReporter(extensionId, extensionVersion, aiKey); util.setExtensionPath(extension.extensionPath); - _channel = vscode.window.createOutputChannel('C#'); + const eventStream = new EventStream(); + + let dotnetChannel = vscode.window.createOutputChannel('.NET'); + let dotnetChannelObserver = new DotNetChannelObserver(dotnetChannel); + let dotnetLoggerObserver = new DotnetLoggerObserver(dotnetChannel); + eventStream.subscribe(dotnetChannelObserver.post); + eventStream.subscribe(dotnetLoggerObserver.post); + + let csharpChannel = vscode.window.createOutputChannel('C#'); + let csharpchannelObserver = new CsharpChannelObserver(csharpChannel); + let csharpLogObserver = new CsharpLoggerObserver(csharpChannel); + eventStream.subscribe(csharpchannelObserver.post); + eventStream.subscribe(csharpLogObserver.post); + + let omnisharpChannel = vscode.window.createOutputChannel('OmniSharp Log'); + let omnisharpLogObserver = new OmnisharpLoggerObserver(omnisharpChannel); + let omnisharpChannelObserver = new OmnisharpChannelObserver(omnisharpChannel); + eventStream.subscribe(omnisharpLogObserver.post); + eventStream.subscribe(omnisharpChannelObserver.post); + + let warningMessageObserver = new WarningMessageObserver(vscode); + eventStream.subscribe(warningMessageObserver.post); - let logger = new Logger(text => _channel.append(text)); + let informationMessageObserver = new InformationMessageObserver(vscode); + eventStream.subscribe(informationMessageObserver.post); + + let omnisharpStatusBar = new StatusBarItemAdapter(vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, Number.MIN_VALUE)); + let omnisharpStatusBarObserver = new OmnisharpStatusBarObserver(omnisharpStatusBar); + eventStream.subscribe(omnisharpStatusBarObserver.post); + + let projectStatusBar = new StatusBarItemAdapter(vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left)); + let projectStatusBarObserver = new ProjectStatusBarObserver(projectStatusBar); + eventStream.subscribe(projectStatusBarObserver.post); + + const debugMode = false; + if (debugMode) { + let omnisharpDebugModeLoggerObserver = new OmnisharpDebugModeLoggerObserver(omnisharpChannel); + eventStream.subscribe(omnisharpDebugModeLoggerObserver.post); + } - let runtimeDependenciesExist = await ensureRuntimeDependencies(extension, logger, reporter); + let platformInfo: PlatformInformation; + try { + platformInfo = await PlatformInformation.GetCurrent(); + } + catch (error) { + eventStream.post(new ActivationFailure()); + } + + let telemetryObserver = new TelemetryObserver(platformInfo, () => reporter); + eventStream.subscribe(telemetryObserver.post); + + let networkSettingsProvider = vscodeNetworkSettingsProvider(vscode); + let runtimeDependenciesExist = await ensureRuntimeDependencies(extension, eventStream, platformInfo, networkSettingsProvider); // activate language services - let omniSharpPromise = OmniSharp.activate(context, reporter, _channel); + let omniSharpPromise = OmniSharp.activate(context, eventStream, extension.packageJSON, platformInfo, networkSettingsProvider); // register JSON completion & hover providers for project.json context.subscriptions.push(addJSONProviders()); - + context.subscriptions.push(vscode.window.onDidChangeActiveTextEditor(() => { + eventStream.post(new ActiveTextEditorChanged()); + })); + let coreClrDebugPromise = Promise.resolve(); if (runtimeDependenciesExist) { // activate coreclr-debug - coreClrDebugPromise = coreclrdebug.activate(extension, context, reporter, logger, _channel); + coreClrDebugPromise = coreclrdebug.activate(extension, context, platformInfo, eventStream); } - + return { - initializationFinished: Promise.all([omniSharpPromise, coreClrDebugPromise]) - .then(promiseResult => { - // This promise resolver simply swallows the result of Promise.all. When we decide we want to expose this level of detail - // to other extensions then we will design that return type and implement it here. - }) + initializationFinished: async () => { + let omniSharp = await omniSharpPromise; + await omniSharp.waitForEmptyEventQueue(); + await coreClrDebugPromise; + } }; } -function ensureRuntimeDependencies(extension: vscode.Extension, logger: Logger, reporter: TelemetryReporter): Promise { +async function ensureRuntimeDependencies(extension: vscode.Extension, eventStream: EventStream, platformInfo: PlatformInformation, networkSettingsProvider : NetworkSettingsProvider): Promise { return util.installFileExists(util.InstallFileType.Lock) .then(exists => { if (!exists) { - const downloader = new CSharpExtDownloader(_channel, logger, reporter, extension.packageJSON); + const downloader = new CSharpExtDownloader(networkSettingsProvider, eventStream, extension.packageJSON, platformInfo); return downloader.installRuntimeDependencies(); } else { return true; diff --git a/src/observers/BaseChannelObserver.ts b/src/observers/BaseChannelObserver.ts new file mode 100644 index 000000000..cdebd5b09 --- /dev/null +++ b/src/observers/BaseChannelObserver.ts @@ -0,0 +1,23 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as vscode from '../vscodeAdapter'; +import { BaseEvent } from '../omnisharp/loggingEvents'; + +export abstract class BaseChannelObserver { + + constructor(private channel: vscode.OutputChannel) { + } + + abstract post: (event: BaseEvent) => void; + + public showChannel(preserveFocusOrColumn?: boolean) { + this.channel.show(preserveFocusOrColumn); + } + + public clearChannel() { + this.channel.clear(); + } +} \ No newline at end of file diff --git a/src/observers/BaseLoggerObserver.ts b/src/observers/BaseLoggerObserver.ts new file mode 100644 index 000000000..cedf31e7a --- /dev/null +++ b/src/observers/BaseLoggerObserver.ts @@ -0,0 +1,22 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as vscode from '../vscodeAdapter'; +import { Logger } from "../logger"; +import { BaseEvent } from '../omnisharp/loggingEvents'; + +export abstract class BaseLoggerObserver { + public logger: Logger; + constructor(channel: vscode.OutputChannel | Logger) { + if (channel instanceof Logger) { + this.logger = channel; + } + else { + this.logger = new Logger((message) => channel.append(message)); + } + } + + abstract post: (event: BaseEvent) => void; +} \ No newline at end of file diff --git a/src/observers/BaseStatusBarItemObserver.ts b/src/observers/BaseStatusBarItemObserver.ts new file mode 100644 index 000000000..3919f163d --- /dev/null +++ b/src/observers/BaseStatusBarItemObserver.ts @@ -0,0 +1,31 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { StatusBarItem } from '../vscodeAdapter'; +import { BaseEvent } from '../omnisharp/loggingEvents'; + +export abstract class BaseStatusBarItemObserver { + + constructor(private statusBarItem: StatusBarItem) { + } + + public SetAndShowStatusBar(text: string, command: string, color?: string, tooltip?: string) { + this.statusBarItem.text = text; + this.statusBarItem.command = command; + this.statusBarItem.color = color; + this.statusBarItem.tooltip = tooltip; + this.statusBarItem.show(); + } + + public ResetAndHideStatusBar() { + this.statusBarItem.text = undefined; + this.statusBarItem.command = undefined; + this.statusBarItem.color = undefined; + this.statusBarItem.tooltip = undefined; + this.statusBarItem.hide(); + } + + abstract post: (event: BaseEvent) => void; +} \ No newline at end of file diff --git a/src/observers/CsharpChannelObserver.ts b/src/observers/CsharpChannelObserver.ts new file mode 100644 index 000000000..4b40ec52e --- /dev/null +++ b/src/observers/CsharpChannelObserver.ts @@ -0,0 +1,21 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { BaseChannelObserver } from "./BaseChannelObserver"; +import { BaseEvent, InstallationFailure, DebuggerNotInstalledFailure, DebuggerPrerequisiteFailure, ProjectJsonDeprecatedWarning, DownloadStart } from "../omnisharp/loggingEvents"; + +export class CsharpChannelObserver extends BaseChannelObserver { + public post = (event: BaseEvent) => { + switch (event.constructor.name) { + case DownloadStart.name: + case InstallationFailure.name: + case DebuggerNotInstalledFailure.name: + case DebuggerPrerequisiteFailure.name: + case ProjectJsonDeprecatedWarning.name: + this.showChannel(); + break; + } + } +} \ No newline at end of file diff --git a/src/observers/CsharpLoggerObserver.ts b/src/observers/CsharpLoggerObserver.ts new file mode 100644 index 000000000..35fd4922d --- /dev/null +++ b/src/observers/CsharpLoggerObserver.ts @@ -0,0 +1,115 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { BaseLoggerObserver } from "./BaseLoggerObserver"; +import * as Event from "../omnisharp/loggingEvents"; +import { PackageError } from "../packageManager/PackageError"; + +export class CsharpLoggerObserver extends BaseLoggerObserver { + private dots: number; + + public post = (event: Event.BaseEvent) => { + switch (event.constructor.name) { + case Event.ActivationFailure.name: + this.logger.appendLine("[ERROR]: C# Extension failed to get platform information."); + break; + case Event.PackageInstallation.name: + this.handlePackageInstallation(event); + break; + case Event.LogPlatformInfo.name: + this.handlePlatformInfo(event); + break; + case Event.InstallationFailure.name: + this.handleInstallationFailure(event); + break; + case Event.InstallationSuccess.name: + this.logger.appendLine('Finished'); + this.logger.appendLine(); + break; + case Event.InstallationStart.name: + this.handleInstallationStart(event); + break; + case Event.DownloadStart.name: + this.handleDownloadStart(event); + break; + case Event.DownloadProgress.name: + this.handleDownloadProgress(event); + break; + case Event.DownloadSuccess.name: + case Event.DownloadFailure.name: + case Event.DebuggerPrerequisiteFailure.name: + case Event.DebuggerPrerequisiteWarning.name: + this.handleEventWithMessage(event); + break; + case Event.ProjectJsonDeprecatedWarning.name: + this.logger.appendLine("Warning: project.json is no longer a supported project format for .NET Core applications. Update to the latest version of .NET Core (https://aka.ms/netcoredownload) and use 'dotnet migrate' to upgrade your project (see https://aka.ms/netcoremigrate for details)."); + break; + case Event.DownloadFallBack.name: + this.handleDownloadFallback(event); + break; + case Event.DownloadSizeObtained.name: + this.handleDownloadSizeObtained(event); + break; + case Event.LatestBuildDownloadStart.name: + this.logger.appendLine("Getting latest OmniSharp version information"); + break; + } + } + + private handleDownloadSizeObtained(event: Event.DownloadSizeObtained) { + this.logger.append(`(${Math.ceil(event.packageSize / 1024)} KB)`); + } + + private handleDownloadFallback(event: Event.DownloadFallBack) { + this.logger.append(`\tRetrying from '${event.fallbackUrl}' `); + } + + private handleEventWithMessage(event: Event.EventWithMessage) { + this.logger.appendLine(event.message); + } + + private handlePackageInstallation(event: Event.PackageInstallation) { + this.logger.append(`Installing ${event.packageInfo}...`); + this.logger.appendLine(); + } + + private handlePlatformInfo(event: Event.LogPlatformInfo) { + this.logger.appendLine(`Platform: ${event.info.toString()}`); + this.logger.appendLine(); + } + + private handleInstallationFailure(event: Event.InstallationFailure) { + this.logger.appendLine(`Failed at stage: ${event.stage}`); + if (event.error instanceof PackageError) { + if (event.error.innerError) { + this.logger.appendLine(event.error.innerError.toString()); + } + else { + this.logger.appendLine(event.error.message); + } + } + else { + // do not log raw errorMessage in telemetry as it is likely to contain PII. + this.logger.appendLine(event.error.toString()); + } + this.logger.appendLine(); + } + + private handleDownloadProgress(event: Event.DownloadProgress) { + let newDots = Math.ceil(event.downloadPercentage / 5); + this.logger.append('.'.repeat(newDots - this.dots)); + this.dots = newDots; + } + + private handleDownloadStart(event: Event.DownloadStart) { + this.logger.append(`Downloading package '${event.packageDescription}' `); + this.dots = 0; + } + + private handleInstallationStart(event: Event.InstallationStart) { + this.logger.appendLine(`Installing package '${event.packageDescription}'`); + this.logger.appendLine(); + } +} \ No newline at end of file diff --git a/src/observers/DotnetChannelObserver.ts b/src/observers/DotnetChannelObserver.ts new file mode 100644 index 000000000..7e34c0bd9 --- /dev/null +++ b/src/observers/DotnetChannelObserver.ts @@ -0,0 +1,18 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { BaseChannelObserver } from "./BaseChannelObserver"; +import { BaseEvent, CommandDotNetRestoreStart } from "../omnisharp/loggingEvents"; + +export class DotNetChannelObserver extends BaseChannelObserver { + public post = (event: BaseEvent) => { + switch (event.constructor.name) { + case CommandDotNetRestoreStart.name: + this.clearChannel(); + this.showChannel(); + break; + } + } +} \ No newline at end of file diff --git a/src/observers/DotnetLoggerObserver.ts b/src/observers/DotnetLoggerObserver.ts new file mode 100644 index 000000000..703595f13 --- /dev/null +++ b/src/observers/DotnetLoggerObserver.ts @@ -0,0 +1,22 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import { BaseLoggerObserver } from "./BaseLoggerObserver"; +import { BaseEvent, CommandDotNetRestoreProgress, CommandDotNetRestoreSucceeded, CommandDotNetRestoreFailed } from "../omnisharp/loggingEvents"; + +export class DotnetLoggerObserver extends BaseLoggerObserver { + public post = (event: BaseEvent) => { + switch (event.constructor.name) { + case CommandDotNetRestoreProgress.name: + this.logger.append((event).message); + break; + case CommandDotNetRestoreSucceeded.name: + this.logger.appendLine((event).message); + break; + case CommandDotNetRestoreFailed.name: + this.logger.appendLine((event).message); + break; + } + } +} \ No newline at end of file diff --git a/src/observers/InformationMessageObserver.ts b/src/observers/InformationMessageObserver.ts new file mode 100644 index 000000000..6fbf4093c --- /dev/null +++ b/src/observers/InformationMessageObserver.ts @@ -0,0 +1,31 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as ObservableEvent from "../omnisharp/loggingEvents"; +import { vscode } from '../vscodeAdapter'; + +export class InformationMessageObserver { + constructor(private vscode: vscode) { + } + + public post = (event: ObservableEvent.BaseEvent) => { + switch (event.constructor.name) { + case ObservableEvent.OmnisharpServerUnresolvedDependencies.name: + this.handleOmnisharpServerUnresolvedDependencies(event); + break; + } + } + + private async handleOmnisharpServerUnresolvedDependencies(event: ObservableEvent.OmnisharpServerUnresolvedDependencies) { + let csharpConfig = this.vscode.workspace.getConfiguration('csharp'); + if (!csharpConfig.get('suppressDotnetRestoreNotification')) { + let info = `There are unresolved dependencies from '${this.vscode.workspace.asRelativePath(event.unresolvedDependencies.FileName)}'. Please execute the restore command to continue.`; + let value = await this.vscode.window.showInformationMessage(info, 'Restore'); + if (value) { + this.vscode.commands.executeCommand('dotnet.restore', event.unresolvedDependencies.FileName); + } + } + } +} diff --git a/src/observers/OmnisharpChannelObserver.ts b/src/observers/OmnisharpChannelObserver.ts new file mode 100644 index 000000000..6b41300e7 --- /dev/null +++ b/src/observers/OmnisharpChannelObserver.ts @@ -0,0 +1,21 @@ +/*--------------------------------------------------------------------------------------------- +* Copyright (c) Microsoft Corporation. All rights reserved. +* Licensed under the MIT License. See License.txt in the project root for license information. +*--------------------------------------------------------------------------------------------*/ + +import { BaseChannelObserver } from "./BaseChannelObserver"; +import { BaseEvent, CommandShowOutput, OmnisharpFailure } from '../omnisharp/loggingEvents'; + +export class OmnisharpChannelObserver extends BaseChannelObserver { + + public post = (event: BaseEvent) => { + switch (event.constructor.name) { + case CommandShowOutput.name: + this.showChannel(); + break; + case OmnisharpFailure.name: + this.showChannel(); + break; + } + } +} \ No newline at end of file diff --git a/src/observers/OmnisharpDebugModeLoggerObserver.ts b/src/observers/OmnisharpDebugModeLoggerObserver.ts new file mode 100644 index 000000000..eab518b1f --- /dev/null +++ b/src/observers/OmnisharpDebugModeLoggerObserver.ts @@ -0,0 +1,95 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { BaseLoggerObserver } from "./BaseLoggerObserver"; +import * as os from 'os'; +import { BaseEvent, OmnisharpRequestMessage, OmnisharpServerEnqueueRequest, OmnisharpServerDequeueRequest, OmnisharpServerProcessRequestComplete, OmnisharpServerVerboseMessage, OmnisharpServerProcessRequestStart, OmnisharpEventPacketReceived } from "../omnisharp/loggingEvents"; + +export class OmnisharpDebugModeLoggerObserver extends BaseLoggerObserver { + public post = (event: BaseEvent) => { + switch (event.constructor.name) { + case OmnisharpRequestMessage.name: + this.handleOmnisharpRequestMessage(event); + break; + case OmnisharpServerEnqueueRequest.name: + this.handleOmnisharpServerEnqueueRequest(event); + break; + case OmnisharpServerDequeueRequest.name: + this.handleOmnisharpServerDequeueRequest(event); + break; + case OmnisharpServerProcessRequestStart.name: + this.handleOmnisharpProcessRequestStart(event); + break; + case OmnisharpServerProcessRequestComplete.name: + this.logger.decreaseIndent(); + break; + case OmnisharpServerVerboseMessage.name: + this.handleOmnisharpServerVerboseMessage(event); + break; + case OmnisharpEventPacketReceived.name: + this.handleOmnisharpEventPacketReceived(event); + break; + } + } + + private handleOmnisharpRequestMessage(event: OmnisharpRequestMessage) { + this.logger.append(`makeRequest: ${event.request.command} (${event.id})`); + if (event.request.data) { + this.logger.append(`, data=${JSON.stringify(event.request.data)}`); + } + this.logger.appendLine(); + } + + private handleOmnisharpServerEnqueueRequest(event: OmnisharpServerEnqueueRequest) { + this.logger.appendLine(`Enqueue ${event.name} request for ${event.command}.`); + this.logger.appendLine(); + } + + private handleOmnisharpServerDequeueRequest(event: OmnisharpServerDequeueRequest) { + this.logger.appendLine(`Dequeue ${event.name} request for ${event.command} (${event.id}).`); + this.logger.appendLine(); + } + + private handleOmnisharpProcessRequestStart(event: OmnisharpServerProcessRequestStart) { + this.logger.appendLine(`Processing ${event.name} queue`); + this.logger.increaseIndent(); + } + + private handleOmnisharpServerVerboseMessage(event: OmnisharpServerVerboseMessage) { + this.logger.appendLine(event.message); + } + + private handleOmnisharpEventPacketReceived(event: OmnisharpEventPacketReceived) { + if (this._isFilterableOutput(event)) { + let output = `[${this.getLogLevelPrefix(event.logLevel)}]: ${event.name}${os.EOL}${event.message}`; + + const newLinePlusPadding = os.EOL + " "; + output = output.replace(os.EOL, newLinePlusPadding); + + this.logger.appendLine(output); + } + } + + private _isFilterableOutput(event: OmnisharpEventPacketReceived) { + // filter messages like: /codecheck: 200 339ms + const timing200Pattern = /^\/[\/\w]+: 200 \d+ms/; + + return event.logLevel === "INFORMATION" + && event.name === "OmniSharp.Middleware.LoggingMiddleware" + && timing200Pattern.test(event.message); + } + + private getLogLevelPrefix(logLevel: string) { + switch (logLevel) { + case "TRACE": return "trce"; + case "DEBUG": return "dbug"; + case "INFORMATION": return "info"; + case "WARNING": return "warn"; + case "ERROR": return "fail"; + case "CRITICAL": return "crit"; + default: throw new Error(`Unknown log level value: ${logLevel}`); + } + } +} \ No newline at end of file diff --git a/src/observers/OmnisharpLoggerObserver.ts b/src/observers/OmnisharpLoggerObserver.ts new file mode 100644 index 000000000..5a53f1268 --- /dev/null +++ b/src/observers/OmnisharpLoggerObserver.ts @@ -0,0 +1,121 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { BaseLoggerObserver } from "./BaseLoggerObserver"; +import { BaseEvent, OmnisharpInitialisation, OmnisharpLaunch, OmnisharpFailure, OmnisharpServerMessage, OmnisharpServerOnServerError, OmnisharpServerOnError, OmnisharpServerMsBuildProjectDiagnostics, OmnisharpServerOnStdErr, OmnisharpEventPacketReceived } from "../omnisharp/loggingEvents"; +import * as os from 'os'; + +export class OmnisharpLoggerObserver extends BaseLoggerObserver { + public post = (event: BaseEvent) => { + switch (event.constructor.name) { + case OmnisharpInitialisation.name: + this.handleOmnisharpInitialisation(event); + break; + case OmnisharpLaunch.name: + this.handleOmnisharpLaunch(event); + break; + case OmnisharpFailure.name: + this.logger.appendLine((event).message); + this.logger.appendLine(); + break; + case OmnisharpServerMessage.name: + this.logger.appendLine((event).message); + break; + case OmnisharpServerOnServerError.name: + this.handleOmnisharpServerOnServerError(event); + break; + case OmnisharpServerOnError.name: + this.handleOmnisharpServerOnError(event); + break; + case OmnisharpServerMsBuildProjectDiagnostics.name: + this.handleOmnisharpServerMsBuildProjectDiagnostics(event); + break; + case OmnisharpServerOnStdErr.name: + this.logger.append((event).message); + break; + case OmnisharpEventPacketReceived.name: + this.handleOmnisharpEventPacketReceived(event); + break; + } + } + + private handleOmnisharpServerOnServerError(event: OmnisharpServerOnServerError) { + this.logger.appendLine('[ERROR] ' + event.err); + } + + private handleOmnisharpInitialisation(event: OmnisharpInitialisation) { + this.logger.appendLine(`Starting OmniSharp server at ${event.timeStamp.toLocaleString()}`); + this.logger.increaseIndent(); + this.logger.appendLine(`Target: ${event.solutionPath}`); + this.logger.decreaseIndent(); + this.logger.appendLine(); + } + + private handleOmnisharpLaunch(event: OmnisharpLaunch) { + if (event.monoVersion) { + this.logger.appendLine(`OmniSharp server started with Mono ${event.monoVersion}`); + } + else { + this.logger.appendLine(`OmniSharp server started`); + } + + this.logger.increaseIndent(); + this.logger.appendLine(`Path: ${event.command}`); + this.logger.appendLine(`PID: ${event.pid}`); + this.logger.decreaseIndent(); + this.logger.appendLine(); + } + + private handleOmnisharpServerMsBuildProjectDiagnostics(event: OmnisharpServerMsBuildProjectDiagnostics) { + if (event.diagnostics.Errors.length > 0 || event.diagnostics.Warnings.length > 0) { + this.logger.appendLine(event.diagnostics.FileName); + event.diagnostics.Errors.forEach(error => { + this.logger.appendLine(`${error.FileName}(${error.StartLine},${error.StartColumn}): Error: ${error.Text}`); + }); + event.diagnostics.Warnings.forEach(warning => { + this.logger.appendLine(`${warning.FileName}(${warning.StartLine},${warning.StartColumn}): Warning: ${warning.Text}`); + }); + this.logger.appendLine(""); + } + } + + private handleOmnisharpServerOnError(event: OmnisharpServerOnError) { + if (event.errorMessage.FileName) { + this.logger.appendLine(`${event.errorMessage.FileName}(${event.errorMessage.Line},${event.errorMessage.Column})`); + } + this.logger.appendLine(event.errorMessage.Text); + this.logger.appendLine(""); + } + + private handleOmnisharpEventPacketReceived(event: OmnisharpEventPacketReceived) { + if (!this._isFilterableOutput(event)) { + let output = `[${this.getLogLevelPrefix(event.logLevel)}]: ${event.name}${os.EOL}${event.message}`; + const newLinePlusPadding = os.EOL + " "; + output = output.replace(os.EOL, newLinePlusPadding); + this.logger.appendLine(output); + } + } + + private _isFilterableOutput(event: OmnisharpEventPacketReceived) { + // filter messages like: /codecheck: 200 339ms + const timing200Pattern = /^\/[\/\w]+: 200 \d+ms/; + + return event.logLevel === "INFORMATION" + && event.name === "OmniSharp.Middleware.LoggingMiddleware" + && timing200Pattern.test(event.message); + } + + private getLogLevelPrefix(logLevel: string) { + switch (logLevel) { + case "TRACE": return "trce"; + case "DEBUG": return "dbug"; + case "INFORMATION": return "info"; + case "WARNING": return "warn"; + case "ERROR": return "fail"; + case "CRITICAL": return "crit"; + default: throw new Error(`Unknown log level value: ${logLevel}`); + } + } +} diff --git a/src/observers/OmnisharpStatusBarObserver.ts b/src/observers/OmnisharpStatusBarObserver.ts new file mode 100644 index 000000000..e25fe6812 --- /dev/null +++ b/src/observers/OmnisharpStatusBarObserver.ts @@ -0,0 +1,40 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { OmnisharpServerOnServerError, BaseEvent, OmnisharpOnBeforeServerInstall, OmnisharpOnBeforeServerStart, OmnisharpServerOnStop, OmnisharpServerOnStart, DownloadStart, InstallationStart, DownloadProgress } from "../omnisharp/loggingEvents"; +import { BaseStatusBarItemObserver } from './BaseStatusBarItemObserver'; + +export class OmnisharpStatusBarObserver extends BaseStatusBarItemObserver { + public post = (event: BaseEvent) => { + switch (event.constructor.name) { + case OmnisharpServerOnServerError.name: + this.SetAndShowStatusBar('$(flame)', 'o.showOutput', 'rgb(218,0,0)', 'Error starting OmniSharp'); + break; + case OmnisharpOnBeforeServerInstall.name: + this.SetAndShowStatusBar('$(flame) Installing OmniSharp...', 'o.showOutput'); + break; + case OmnisharpOnBeforeServerStart.name: + this.SetAndShowStatusBar('$(flame)', 'o.showOutput', 'rgb(218,218,0)', 'Starting OmniSharp server'); + break; + case OmnisharpServerOnStop.name: + this.ResetAndHideStatusBar(); + break; + case OmnisharpServerOnStart.name: + this.SetAndShowStatusBar('$(flame)', 'o.showOutput', 'rgb(0, 218, 0)', 'OmniSharp server is running'); + break; + case DownloadStart.name: + this.SetAndShowStatusBar("$(cloud-download) Downloading packages", '', '', `Downloading package '${(event).packageDescription}...' `); + break; + case InstallationStart.name: + this.SetAndShowStatusBar("$(desktop-download) Installing packages...", '', '', `Installing package '${(event).packageDescription}'`); + break; + case DownloadProgress.name: + let progressEvent = event; + this.SetAndShowStatusBar("$(cloud-download) Downloading packages", '', '', `Downloading package '${progressEvent.packageDescription}'... ${progressEvent.downloadPercentage}%`); + break; + } + } +} + diff --git a/src/observers/ProjectStatusBarObserver.ts b/src/observers/ProjectStatusBarObserver.ts new file mode 100644 index 000000000..fd37b7b20 --- /dev/null +++ b/src/observers/ProjectStatusBarObserver.ts @@ -0,0 +1,36 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { basename } from 'path'; +import { BaseEvent, OmnisharpOnMultipleLaunchTargets, WorkspaceInformationUpdated, OmnisharpServerOnStop } from "../omnisharp/loggingEvents"; +import { BaseStatusBarItemObserver } from './BaseStatusBarItemObserver'; + +export class ProjectStatusBarObserver extends BaseStatusBarItemObserver { + + public post = (event: BaseEvent) => { + switch (event.constructor.name) { + case OmnisharpOnMultipleLaunchTargets.name: + this.SetAndShowStatusBar('$(file-submodule) Select project', 'o.pickProjectAndStart', 'rgb(90, 218, 90)'); + break; + case OmnisharpServerOnStop.name: + this.ResetAndHideStatusBar(); + break; + case WorkspaceInformationUpdated.name: + this.handleWorkspaceInformationUpdated(event); + } + } + + private handleWorkspaceInformationUpdated(event: WorkspaceInformationUpdated) { + let label: string; + let info = event.info; + if (info.MsBuild && info.MsBuild.SolutionPath) { + label = basename(info.MsBuild.SolutionPath); //workspace.getRelativePath(info.MsBuild.SolutionPath); + this.SetAndShowStatusBar('$(file-directory) ' + label, 'o.pickProjectAndStart'); + } + else { + this.ResetAndHideStatusBar(); + } + } +} \ No newline at end of file diff --git a/src/observers/TelemetryObserver.ts b/src/observers/TelemetryObserver.ts new file mode 100644 index 000000000..6453df9aa --- /dev/null +++ b/src/observers/TelemetryObserver.ts @@ -0,0 +1,89 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { PlatformInformation } from "../platform"; +import { BaseEvent, PackageInstallation, InstallationFailure, InstallationSuccess, OmnisharpDelayTrackerEventMeasures, OmnisharpStart, TestExecutionCountReport, TelemetryEventWithMeasures } from "../omnisharp/loggingEvents"; +import { PackageError } from "../packageManager/PackageError"; + +export interface ITelemetryReporter { + sendTelemetryEvent(eventName: string, properties?: { [key: string]: string }, measures?: { [key: string]: number }): void; +} + +export class TelemetryObserver { + private reporter: ITelemetryReporter; + private platformInfo: PlatformInformation; + + constructor(platformInfo: PlatformInformation, reporterCreator: () => ITelemetryReporter) { + this.platformInfo = platformInfo; + this.reporter = reporterCreator(); + } + + public post = (event: BaseEvent) => { + let telemetryProps = this.getTelemetryProps(); + switch (event.constructor.name) { + case PackageInstallation.name: + this.reporter.sendTelemetryEvent("AcquisitionStart"); + break; + case InstallationFailure.name: + this.handleInstallationFailure(event, telemetryProps); + break; + case InstallationSuccess.name: + this.handleInstallationSuccess(telemetryProps); + break; + case OmnisharpDelayTrackerEventMeasures.name: + case OmnisharpStart.name: + this.handleTelemetryEventMeasures(event); + break; + case TestExecutionCountReport.name: + this.handleTestExecutionCountReport(event); + break; + } + } + + private handleTelemetryEventMeasures(event: TelemetryEventWithMeasures) { + this.reporter.sendTelemetryEvent(event.eventName, null, event.measures); + } + + private handleInstallationSuccess(telemetryProps: { [key: string]: string; }) { + telemetryProps['installStage'] = 'completeSuccess'; + this.reporter.sendTelemetryEvent('Acquisition', telemetryProps); + } + + private handleInstallationFailure(event: InstallationFailure, telemetryProps: { [key: string]: string; }) { + telemetryProps['installStage'] = event.stage; + if (event.error instanceof PackageError) { + // we can log the message in a PackageError to telemetry as we do not put PII in PackageError messages + telemetryProps['error.message'] = event.error.message; + + if (event.error.pkg) { + telemetryProps['error.packageUrl'] = event.error.pkg.url; + } + } + + this.reporter.sendTelemetryEvent('Acquisition', telemetryProps); + } + + private handleTestExecutionCountReport(event: TestExecutionCountReport) { + if (event.debugCounts) { + this.reporter.sendTelemetryEvent('DebugTest', null, event.debugCounts); + } + if (event.runCounts) { + this.reporter.sendTelemetryEvent('RunTest', null, event.runCounts); + } + } + + private getTelemetryProps() { + let telemetryProps: { [key: string]: string } = { + 'platform.architecture': this.platformInfo.architecture, + 'platform.platform': this.platformInfo.platform + }; + + if (this.platformInfo.distribution) { + telemetryProps['platform.distribution'] = this.platformInfo.distribution.toTelemetryString(); + } + + return telemetryProps; + } +} diff --git a/src/observers/WarningMessageObserver.ts b/src/observers/WarningMessageObserver.ts new file mode 100644 index 000000000..c8c70a009 --- /dev/null +++ b/src/observers/WarningMessageObserver.ts @@ -0,0 +1,57 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { MessageItem, vscode } from '../vscodeAdapter'; +import { BaseEvent, OmnisharpServerOnError, OmnisharpServerMsBuildProjectDiagnostics } from "../omnisharp/loggingEvents"; +import { Scheduler } from 'rxjs/Scheduler'; +import { Subject } from 'rxjs/Subject'; +import 'rxjs/add/operator/debounceTime'; + +export interface MessageItemWithCommand extends MessageItem { + command: string; +} + +export class WarningMessageObserver { + private warningMessageDebouncer: Subject; + + constructor(private vscode: vscode, scheduler?: Scheduler) { + this.warningMessageDebouncer = new Subject(); + this.warningMessageDebouncer.debounceTime(1500, scheduler).subscribe(async event => { + let message = "Some projects have trouble loading. Please review the output for more details."; + let value: MessageItemWithCommand; + try { + value = await this.vscode.window.showWarningMessage(message, { title: "Show Output", command: 'o.showOutput' }); + } + catch (err){ + console.log(err); + } + if (value) { + try { + await this.vscode.commands.executeCommand(value.command); + } + catch (err) { + console.log(err); + } + } + }); + } + + public post = (event: BaseEvent) => { + switch (event.constructor.name) { + case OmnisharpServerOnError.name: + this.warningMessageDebouncer.next(event); + break; + case OmnisharpServerMsBuildProjectDiagnostics.name: + this.handleOmnisharpServerMsBuildProjectDiagnostics(event); + break; + } + } + + private handleOmnisharpServerMsBuildProjectDiagnostics(event: OmnisharpServerMsBuildProjectDiagnostics) { + if (event.diagnostics.Errors.length > 0) { + this.warningMessageDebouncer.next(event); + } + } +} \ No newline at end of file diff --git a/src/omnisharp/OmnisharpDownloader.ts b/src/omnisharp/OmnisharpDownloader.ts new file mode 100644 index 000000000..ba40cfe18 --- /dev/null +++ b/src/omnisharp/OmnisharpDownloader.ts @@ -0,0 +1,65 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as fs from 'fs'; +import { GetPackagesFromVersion } from './OmnisharpPackageCreator'; +import { PlatformInformation } from '../platform'; +import { PackageInstallation, LogPlatformInfo, InstallationSuccess, InstallationFailure, LatestBuildDownloadStart } from './loggingEvents'; +import { EventStream } from '../EventStream'; +import { NetworkSettingsProvider } from '../NetworkSettings'; +import { DownloadAndInstallPackages } from '../packageManager/PackageManager'; +import { CreateTmpFile, TmpAsset } from '../CreateTmpAsset'; +import { DownloadFile } from '../packageManager/FileDownloader'; +import { ResolveFilePaths } from '../packageManager/PackageFilePathResolver'; + +export class OmnisharpDownloader { + + public constructor( + private networkSettingsProvider: NetworkSettingsProvider, + private eventStream: EventStream, + private packageJSON: any, + private platformInfo: PlatformInformation) { + } + + public async DownloadAndInstallOmnisharp(version: string, serverUrl: string, installPath: string) { + this.eventStream.post(new PackageInstallation(`OmniSharp Version = ${version}`)); + let installationStage = ''; + + try { + this.eventStream.post(new LogPlatformInfo(this.platformInfo)); + installationStage = 'getPackageInfo'; + let packages = GetPackagesFromVersion(version, this.packageJSON.runtimeDependencies, serverUrl, installPath); + packages.forEach(pkg => ResolveFilePaths(pkg)); + installationStage = 'downloadAndInstallPackages'; + await DownloadAndInstallPackages(packages, this.networkSettingsProvider, this.platformInfo, this.eventStream); + this.eventStream.post(new InstallationSuccess()); + } + catch (error) { + this.eventStream.post(new InstallationFailure(installationStage, error)); + throw error;// throw the error up to the server + } + } + + public async GetLatestVersion(serverUrl: string, latestVersionFileServerPath: string): Promise { + let description = "Latest Omnisharp Version Information"; + let url = `${serverUrl}/${latestVersionFileServerPath}`; + let tmpFile: TmpAsset; + try { + this.eventStream.post(new LatestBuildDownloadStart()); + tmpFile = await CreateTmpFile(); + await DownloadFile(tmpFile.fd, description, this.eventStream, this.networkSettingsProvider, url); + return fs.readFileSync(tmpFile.name, 'utf8'); + } + catch (error) { + this.eventStream.post(new InstallationFailure('getLatestVersionInfoFile', error)); + throw error; + } + finally { + if (tmpFile) { + tmpFile.dispose(); + } + } + } +} \ No newline at end of file diff --git a/src/omnisharp/OmnisharpManager.ts b/src/omnisharp/OmnisharpManager.ts new file mode 100644 index 000000000..5dbfedb15 --- /dev/null +++ b/src/omnisharp/OmnisharpManager.ts @@ -0,0 +1,85 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as path from 'path'; +import * as semver from 'semver'; +import * as util from '../common'; +import { OmnisharpDownloader } from './OmnisharpDownloader'; +import { PlatformInformation } from '../platform'; + +export interface LaunchInfo { + LaunchPath: string; + MonoLaunchPath?: string; +} + +export class OmnisharpManager { + public constructor( + private downloader: OmnisharpDownloader, + private platformInfo: PlatformInformation) { + } + + public async GetOmniSharpLaunchInfo(omnisharpPath: string, serverUrl: string, latestVersionFileServerPath: string, installPath: string, extensionPath: string): Promise { + if (!omnisharpPath) { + // If omnisharpPath was not specified, return the default path. + let basePath = path.resolve(extensionPath, '.omnisharp'); + return this.GetLaunchInfo(this.platformInfo, basePath); + } + + // Looks at the options path, installs the dependencies and returns the path to be loaded by the omnisharp server + if (path.isAbsolute(omnisharpPath)) { + if (!await util.fileExists(omnisharpPath)) { + throw new Error('The system could not find the specified path'); + } + + return { + LaunchPath: omnisharpPath + }; + } + else if (omnisharpPath === 'latest') { + return await this.InstallLatestAndReturnLaunchInfo(serverUrl, latestVersionFileServerPath, installPath, extensionPath); + } + + // If the path is neither a valid path on disk not the string "latest", treat it as a version + return await this.InstallVersionAndReturnLaunchInfo(omnisharpPath, serverUrl, installPath, extensionPath); + } + + private async InstallLatestAndReturnLaunchInfo(serverUrl: string, latestVersionFileServerPath: string, installPath: string, extensionPath: string): Promise { + let version = await this.downloader.GetLatestVersion(serverUrl, latestVersionFileServerPath); + return await this.InstallVersionAndReturnLaunchInfo(version, serverUrl, installPath, extensionPath); + } + + private async InstallVersionAndReturnLaunchInfo(version: string, serverUrl: string, installPath: string, extensionPath: string): Promise { + if (semver.valid(version)) { + await this.downloader.DownloadAndInstallOmnisharp(version, serverUrl, installPath); + return this.GetLaunchPathForVersion(this.platformInfo, version, installPath, extensionPath); + } + else { + throw new Error(`Invalid OmniSharp version - ${version}`); + } + } + + private GetLaunchPathForVersion(platformInfo: PlatformInformation, version: string, installPath: string, extensionPath: string): LaunchInfo { + if (!version) { + throw new Error('Invalid Version'); + } + + let basePath = path.resolve(extensionPath, installPath, version); + + return this.GetLaunchInfo(platformInfo, basePath); + } + + private GetLaunchInfo(platformInfo: PlatformInformation, basePath: string): LaunchInfo { + if (platformInfo.isWindows()) { + return { + LaunchPath: path.join(basePath, 'OmniSharp.exe') + }; + } + + return { + LaunchPath: path.join(basePath, 'run'), + MonoLaunchPath: path.join(basePath, 'omnisharp', 'OmniSharp.exe') + }; + } +} \ No newline at end of file diff --git a/src/omnisharp/OmnisharpPackageCreator.ts b/src/omnisharp/OmnisharpPackageCreator.ts new file mode 100644 index 000000000..c1dc9ce8c --- /dev/null +++ b/src/omnisharp/OmnisharpPackageCreator.ts @@ -0,0 +1,56 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Package } from "../packageManager/Package"; + +export function GetPackagesFromVersion(version: string, runTimeDependencies: Package[], serverUrl: string, installPath: string): Package[] { + if (!version) { + throw new Error('Invalid version'); + } + + let versionPackages = new Array(); + for (let inputPackage of runTimeDependencies) { + if (inputPackage.platformId) { + versionPackages.push(SetBinaryAndGetPackage(inputPackage, serverUrl, version, installPath)); + } + } + + return versionPackages; +} + +export function SetBinaryAndGetPackage(inputPackage: Package, serverUrl: string, version: string, installPath: string): Package { + let installBinary: string; + if (inputPackage.platformId == "win-x86" || inputPackage.platformId == "win-x64") { + installBinary = "OmniSharp.exe"; + } + else if (inputPackage.platformId == "osx") { + installBinary = "mono.osx"; + } + else if (inputPackage.platformId == "linux-x86") { + installBinary = "mono.linux-x86"; + } + else if (inputPackage.platformId == "linux-x64") { + installBinary = "mono.linux-x86_64"; + } + + return GetPackage(inputPackage, serverUrl, version, installPath, installBinary); +} + +function GetPackage(inputPackage: Package, serverUrl: string, version: string, installPath: string, installBinary: string): Package { + if (!version) { + throw new Error('Invalid version'); + } + + let versionPackage = {...inputPackage, + "description": `${inputPackage.description}, Version = ${version}`, + "url": `${serverUrl}/releases/${version}/omnisharp-${inputPackage.platformId}.zip`, + "installPath": `${installPath}/${version}`, + "installTestPath": `./${installPath}/${version}/${installBinary}`, + "fallbackUrl": "" //setting to empty so that we dont use the fallback url of the default packages + }; + + return versionPackage; +} + diff --git a/src/omnisharp/delayTracker.ts b/src/omnisharp/delayTracker.ts index eaf01459e..5217efc10 100644 --- a/src/omnisharp/delayTracker.ts +++ b/src/omnisharp/delayTracker.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; - const ImmedateDelayMax = 25; const NearImmediateDelayMax = 50; const ShortDelayMax = 250; diff --git a/src/omnisharp/extension.ts b/src/omnisharp/extension.ts index 968b836b4..5eee69dc6 100644 --- a/src/omnisharp/extension.ts +++ b/src/omnisharp/extension.ts @@ -5,11 +5,9 @@ import * as utils from './utils'; import * as vscode from 'vscode'; - import { AddAssetResult, addAssetsIfNecessary } from '../assets'; import reportDiagnostics, { Advisor } from '../features/diagnosticsProvider'; import { safeLength, sum } from '../common'; - import { CSharpConfigurationProvider } from '../configurationProvider'; import CodeActionProvider from '../features/codeActionProvider'; import CodeLensProvider from '../features/codeLensProvider'; @@ -26,24 +24,25 @@ import { Options } from './options'; import ReferenceProvider from '../features/referenceProvider'; import RenameProvider from '../features/renameProvider'; import SignatureHelpProvider from '../features/signatureHelpProvider'; -import TelemetryReporter from 'vscode-extension-telemetry'; import TestManager from '../features/dotnetTest'; import WorkspaceSymbolProvider from '../features/workspaceSymbolProvider'; import forwardChanges from '../features/changeForwarding'; import registerCommands from '../features/commands'; -import reportStatus from '../features/status'; +import { PlatformInformation } from '../platform'; +import { ProjectJsonDeprecatedWarning, OmnisharpStart } from './loggingEvents'; +import { EventStream } from '../EventStream'; +import { NetworkSettingsProvider } from '../NetworkSettings'; export let omnisharp: OmniSharpServer; -export function activate(context: vscode.ExtensionContext, reporter: TelemetryReporter, channel: vscode.OutputChannel) { +export async function activate(context: vscode.ExtensionContext, eventStream: EventStream, packageJSON: any, platformInfo: PlatformInformation, provider: NetworkSettingsProvider) { const documentSelector: vscode.DocumentSelector = { language: 'csharp', scheme: 'file' // only files from disk }; const options = Options.Read(); - - const server = new OmniSharpServer(reporter); + const server = new OmniSharpServer(vscode, provider, eventStream, packageJSON, platformInfo); omnisharp = server; const advisor = new Advisor(server); // create before server is started const disposables: vscode.Disposable[] = []; @@ -55,29 +54,29 @@ export function activate(context: vscode.ExtensionContext, reporter: TelemetryRe definitionMetadataDocumentProvider.register(); localDisposables.push(definitionMetadataDocumentProvider); - const definitionProvider = new DefinitionProvider(server, reporter, definitionMetadataDocumentProvider); + const definitionProvider = new DefinitionProvider(server, definitionMetadataDocumentProvider); localDisposables.push(vscode.languages.registerDefinitionProvider(documentSelector, definitionProvider)); localDisposables.push(vscode.languages.registerDefinitionProvider({ scheme: definitionMetadataDocumentProvider.scheme }, definitionProvider)); - localDisposables.push(vscode.languages.registerImplementationProvider(documentSelector, new ImplementationProvider(server, reporter))); - const testManager = new TestManager(server, reporter); + localDisposables.push(vscode.languages.registerImplementationProvider(documentSelector, new ImplementationProvider(server))); + const testManager = new TestManager(server, eventStream); localDisposables.push(testManager); - localDisposables.push(vscode.languages.registerCodeLensProvider(documentSelector, new CodeLensProvider(server, reporter, testManager))); - localDisposables.push(vscode.languages.registerDocumentHighlightProvider(documentSelector, new DocumentHighlightProvider(server, reporter))); - localDisposables.push(vscode.languages.registerDocumentSymbolProvider(documentSelector, new DocumentSymbolProvider(server, reporter))); - localDisposables.push(vscode.languages.registerReferenceProvider(documentSelector, new ReferenceProvider(server, reporter))); - localDisposables.push(vscode.languages.registerHoverProvider(documentSelector, new HoverProvider(server, reporter))); - localDisposables.push(vscode.languages.registerRenameProvider(documentSelector, new RenameProvider(server, reporter))); + localDisposables.push(vscode.languages.registerCodeLensProvider(documentSelector, new CodeLensProvider(server, testManager))); + localDisposables.push(vscode.languages.registerDocumentHighlightProvider(documentSelector, new DocumentHighlightProvider(server))); + localDisposables.push(vscode.languages.registerDocumentSymbolProvider(documentSelector, new DocumentSymbolProvider(server))); + localDisposables.push(vscode.languages.registerReferenceProvider(documentSelector, new ReferenceProvider(server))); + localDisposables.push(vscode.languages.registerHoverProvider(documentSelector, new HoverProvider(server))); + localDisposables.push(vscode.languages.registerRenameProvider(documentSelector, new RenameProvider(server))); if (options.useFormatting) { - localDisposables.push(vscode.languages.registerDocumentRangeFormattingEditProvider(documentSelector, new FormatProvider(server, reporter))); - localDisposables.push(vscode.languages.registerOnTypeFormattingEditProvider(documentSelector, new FormatProvider(server, reporter), '}', ';')); + localDisposables.push(vscode.languages.registerDocumentRangeFormattingEditProvider(documentSelector, new FormatProvider(server))); + localDisposables.push(vscode.languages.registerOnTypeFormattingEditProvider(documentSelector, new FormatProvider(server), '}', ';')); } - localDisposables.push(vscode.languages.registerCompletionItemProvider(documentSelector, new CompletionItemProvider(server, reporter), '.', ' ')); - localDisposables.push(vscode.languages.registerWorkspaceSymbolProvider(new WorkspaceSymbolProvider(server, reporter))); - localDisposables.push(vscode.languages.registerSignatureHelpProvider(documentSelector, new SignatureHelpProvider(server, reporter), '(', ',')); - const codeActionProvider = new CodeActionProvider(server, reporter); + localDisposables.push(vscode.languages.registerCompletionItemProvider(documentSelector, new CompletionItemProvider(server), '.', ' ')); + localDisposables.push(vscode.languages.registerWorkspaceSymbolProvider(new WorkspaceSymbolProvider(server))); + localDisposables.push(vscode.languages.registerSignatureHelpProvider(documentSelector, new SignatureHelpProvider(server), '(', ',')); + const codeActionProvider = new CodeActionProvider(server); localDisposables.push(codeActionProvider); localDisposables.push(vscode.languages.registerCodeActionsProvider(documentSelector, codeActionProvider)); - localDisposables.push(reportDiagnostics(server, reporter, advisor)); + localDisposables.push(reportDiagnostics(server, advisor)); localDisposables.push(forwardChanges(server)); })); @@ -86,8 +85,7 @@ export function activate(context: vscode.ExtensionContext, reporter: TelemetryRe vscode.Disposable.from(...localDisposables).dispose(); })); - disposables.push(registerCommands(server, reporter, channel)); - disposables.push(reportStatus(server)); + disposables.push(registerCommands(server, eventStream,platformInfo)); if (!context.workspaceState.get('assetPromptDisabled')) { disposables.push(server.onServerStart(() => { @@ -109,12 +107,10 @@ export function activate(context: vscode.ExtensionContext, reporter: TelemetryRe .then(workspaceInfo => { if (workspaceInfo.DotNet && workspaceInfo.DotNet.Projects.length > 0) { const shortMessage = 'project.json is no longer a supported project format for .NET Core applications.'; - const detailedMessage = "Warning: project.json is no longer a supported project format for .NET Core applications. Update to the latest version of .NET Core (https://aka.ms/netcoredownload) and use 'dotnet migrate' to upgrade your project (see https://aka.ms/netcoremigrate for details)."; const moreDetailItem: vscode.MessageItem = { title: 'More Detail' }; vscode.window.showWarningMessage(shortMessage, moreDetailItem) .then(item => { - channel.appendLine(detailedMessage); - channel.show(); + eventStream.post(new ProjectJsonDeprecatedWarning()); }); } }); @@ -125,7 +121,7 @@ export function activate(context: vscode.ExtensionContext, reporter: TelemetryRe disposables.push(server.onServerStart(() => { let measures: { [key: string]: number } = {}; - utils.requestWorkspaceInformation(server) + utils.requestWorkspaceInformation(server) .then(workspaceInfo => { if (workspaceInfo.DotNet && workspaceInfo.DotNet.Projects.length > 0) { measures['projectjson.projectcount'] = workspaceInfo.DotNet.Projects.length; @@ -141,7 +137,7 @@ export function activate(context: vscode.ExtensionContext, reporter: TelemetryRe // TODO: Add measurements for script. - reporter.sendTelemetryEvent('OmniSharp.Start', null, measures); + eventStream.post(new OmnisharpStart('OmniSharp.Start', measures)); }); })); @@ -162,6 +158,8 @@ export function activate(context: vscode.ExtensionContext, reporter: TelemetryRe disposables.push(vscode.debug.registerDebugConfigurationProvider('coreclr', new CSharpConfigurationProvider(server))); context.subscriptions.push(...disposables); - - return new Promise(resolve => server.onServerStart(e => resolve(e))); + + return new Promise(resolve => + server.onServerStart(e => + resolve(server))); } \ No newline at end of file diff --git a/src/omnisharp/launcher.ts b/src/omnisharp/launcher.ts index 2a70ac273..84d76f5a3 100644 --- a/src/omnisharp/launcher.ts +++ b/src/omnisharp/launcher.ts @@ -3,15 +3,13 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; - import { spawn, ChildProcess } from 'child_process'; import { satisfies } from 'semver'; import { PlatformInformation } from '../platform'; import * as path from 'path'; import * as vscode from 'vscode'; -import * as util from '../common'; import { Options } from './options'; +import { LaunchInfo } from './OmnisharpManager'; export enum LaunchTargetKind { Solution, @@ -46,7 +44,7 @@ export function findLaunchTargets(): Thenable { const options = Options.Read(); return vscode.workspace.findFiles( - /*include*/ '{**/*.sln,**/*.csproj,**/project.json,**/*.csx,**/*.cake}', + /*include*/ '{**/*.sln,**/*.csproj,**/project.json,**/*.csx,**/*.cake}', /*exclude*/ '{**/node_modules/**,**/.git/**,**/bower_components/**}', /*maxResults*/ options.maxProjectResults) .then(resourcesToLaunchTargets); @@ -88,8 +86,7 @@ function resourcesToLaunchTargets(resources: vscode.Uri[]): LaunchTarget[] { let targets: LaunchTarget[] = []; - workspaceFolderToUriMap.forEach((resources, folderIndex) => - { + workspaceFolderToUriMap.forEach((resources, folderIndex) => { let hasCsProjFiles = false, hasSlnFile = false, hasProjectJson = false, @@ -98,15 +95,15 @@ function resourcesToLaunchTargets(resources: vscode.Uri[]): LaunchTarget[] { hasCake = false; hasCsProjFiles = resources.some(isCSharpProject); - + let folder = vscode.workspace.workspaceFolders[folderIndex]; let folderPath = folder.uri.fsPath; - + resources.forEach(resource => { // Add .sln files if there are .csproj files if (hasCsProjFiles && isSolution(resource)) { hasSlnFile = true; - + targets.push({ label: path.basename(resource.fsPath), description: vscode.workspace.asRelativePath(path.dirname(resource.fsPath)), @@ -115,13 +112,13 @@ function resourcesToLaunchTargets(resources: vscode.Uri[]): LaunchTarget[] { kind: LaunchTargetKind.Solution }); } - + // Add project.json files if (isProjectJson(resource)) { const dirname = path.dirname(resource.fsPath); hasProjectJson = true; hasProjectJsonAtRoot = hasProjectJsonAtRoot || dirname === folderPath; - + targets.push({ label: path.basename(resource.fsPath), description: vscode.workspace.asRelativePath(path.dirname(resource.fsPath)), @@ -130,18 +127,18 @@ function resourcesToLaunchTargets(resources: vscode.Uri[]): LaunchTarget[] { kind: LaunchTargetKind.ProjectJson }); } - + // Discover if there is any CSX file if (!hasCSX && isCsx(resource)) { hasCSX = true; } - + // Discover if there is any Cake file if (!hasCake && isCake(resource)) { hasCake = true; } }); - + // Add the root folder under the following circumstances: // * If there are .csproj files, but no .sln file, and none in the root. // * If there are project.json files, but none in the root. @@ -154,7 +151,7 @@ function resourcesToLaunchTargets(resources: vscode.Uri[]): LaunchTarget[] { kind: LaunchTargetKind.Folder }); } - + // if we noticed any CSX file(s), add a single CSX-specific target pointing at the root folder if (hasCSX) { targets.push({ @@ -165,7 +162,7 @@ function resourcesToLaunchTargets(resources: vscode.Uri[]): LaunchTarget[] { kind: LaunchTargetKind.Csx }); } - + // if we noticed any Cake file(s), add a single Cake-specific target pointing at the root folder if (hasCake) { targets.push({ @@ -204,12 +201,12 @@ function isCake(resource: vscode.Uri): boolean { export interface LaunchResult { process: ChildProcess; command: string; - usingMono: boolean; + monoVersion?: string; } -export function launchOmniSharp(cwd: string, args: string[]): Promise { +export async function launchOmniSharp(cwd: string, args: string[], launchInfo: LaunchInfo): Promise { return new Promise((resolve, reject) => { - launch(cwd, args) + launch(cwd, args, launchInfo) .then(result => { // async error - when target not not ENEOT result.process.on('error', err => { @@ -225,60 +222,51 @@ export function launchOmniSharp(cwd: string, args: string[]): Promise { - return PlatformInformation.GetCurrent().then(platformInfo => { - const options = Options.Read(); - - if (options.useEditorFormattingSettings) - { - let globalConfig = vscode.workspace.getConfiguration(); - let csharpConfig = vscode.workspace.getConfiguration('[csharp]'); +async function launch(cwd: string, args: string[], launchInfo: LaunchInfo): Promise { + const platformInfo = await PlatformInformation.GetCurrent(); + const options = Options.Read(); - args.push(`formattingOptions:useTabs=${!getConfigurationValue(globalConfig, csharpConfig, 'editor.insertSpaces', true)}`); - args.push(`formattingOptions:tabSize=${getConfigurationValue(globalConfig, csharpConfig, 'editor.tabSize', 4)}`); - args.push(`formattingOptions:indentationSize=${getConfigurationValue(globalConfig, csharpConfig, 'editor.tabSize', 4)}`); - } + if (options.useEditorFormattingSettings) { + let globalConfig = vscode.workspace.getConfiguration(); + let csharpConfig = vscode.workspace.getConfiguration('[csharp]'); - // If the user has provide a path to OmniSharp, we'll use that. - if (options.path) { - if (platformInfo.isWindows()) { - return launchWindows(options.path, cwd, args); - } + args.push(`formattingOptions:useTabs=${!getConfigurationValue(globalConfig, csharpConfig, 'editor.insertSpaces', true)}`); + args.push(`formattingOptions:tabSize=${getConfigurationValue(globalConfig, csharpConfig, 'editor.tabSize', 4)}`); + args.push(`formattingOptions:indentationSize=${getConfigurationValue(globalConfig, csharpConfig, 'editor.tabSize', 4)}`); + } - // If we're launching on macOS/Linux, we have two possibilities: - // 1. Launch using Mono - // 2. Launch process directly (e.g. a 'run' script) - return options.useMono - ? launchNixMono(options.path, cwd, args) - : launchNix(options.path, cwd, args); - } + if (platformInfo.isWindows()) { + return launchWindows(launchInfo.LaunchPath, cwd, args); + } - // If the user has not provided a path, we'll use the locally-installed OmniSharp - const basePath = path.resolve(util.getExtensionPath(), '.omnisharp'); + let monoVersion = await getMonoVersion(); + let isValidMonoAvailable = await satisfies(monoVersion, '>=5.2.0'); - if (platformInfo.isWindows()) { - return launchWindows(path.join(basePath, 'OmniSharp.exe'), cwd, args); + // If the user specifically said that they wanted to launch on Mono, respect their wishes. + if (options.useMono) { + if (!isValidMonoAvailable) { + throw new Error('Cannot start OmniSharp because Mono version >=5.2.0 is required.'); } - // If it's possible to launch on a global Mono, we'll do that. Otherwise, run with our - // locally installed Mono runtime. - return canLaunchMono() - .then(() => { - return launchNixMono(path.join(basePath, 'omnisharp', 'OmniSharp.exe'), cwd, args); - }) - .catch(_ => { - return launchNix(path.join(basePath, 'run'), cwd, args); - }); - }); + return launchNixMono(launchInfo.LaunchPath, monoVersion, cwd, args); + } + + // If we can launch on the global Mono, do so; otherwise, launch directly; + if (isValidMonoAvailable && launchInfo.MonoLaunchPath) { + return launchNixMono(launchInfo.MonoLaunchPath, monoVersion, cwd, args); + } + else { + return launchNix(launchInfo.LaunchPath, cwd, args); + } } function getConfigurationValue(globalConfig: vscode.WorkspaceConfiguration, csharpConfig: vscode.WorkspaceConfiguration, configurationPath: string, defaultValue: any): any { - + if (csharpConfig[configurationPath] != undefined) { return csharpConfig[configurationPath]; } - + return globalConfig.get(configurationPath, defaultValue); } @@ -287,7 +275,7 @@ function launchWindows(launchPath: string, cwd: string, args: string[]): LaunchR const hasSpaceWithoutQuotes = /^[^"].* .*[^"]/; return hasSpaceWithoutQuotes.test(arg) ? `"${arg}"` - : arg.replace("&","^&"); + : arg.replace("&", "^&"); } let argsCopy = args.slice(0); // create copy of args @@ -298,7 +286,7 @@ function launchWindows(launchPath: string, cwd: string, args: string[]): LaunchR '"' + argsCopy.map(escapeIfNeeded).join(' ') + '"' ].join(' ')]; - let process = spawn('cmd', argsCopy, { + let process = spawn('cmd', argsCopy, { windowsVerbatimArguments: true, detached: false, cwd: cwd @@ -307,7 +295,6 @@ function launchWindows(launchPath: string, cwd: string, args: string[]): LaunchR return { process, command: launchPath, - usingMono: false }; } @@ -319,58 +306,41 @@ function launchNix(launchPath: string, cwd: string, args: string[]): LaunchResul return { process, - command: launchPath, - usingMono: true + command: launchPath }; } -function launchNixMono(launchPath: string, cwd: string, args: string[]): Promise { - return canLaunchMono() - .then(() => { - let argsCopy = args.slice(0); // create copy of details args - argsCopy.unshift(launchPath); - argsCopy.unshift("--assembly-loader=strict"); - - let process = spawn('mono', argsCopy, { - detached: false, - cwd: cwd - }); - - return { - process, - command: launchPath, - usingMono: true - }; - }); -} +function launchNixMono(launchPath: string, monoVersion: string, cwd: string, args: string[]): LaunchResult { + let argsCopy = args.slice(0); // create copy of details args + argsCopy.unshift(launchPath); + argsCopy.unshift("--assembly-loader=strict"); -function canLaunchMono(): Promise { - return new Promise((resolve, reject) => { - hasMono('>=5.2.0').then(success => { - if (success) { - resolve(); - } - else { - reject(new Error('Cannot start Omnisharp because Mono version >=5.2.0 is required.')); - } - }); + let process = spawn('mono', argsCopy, { + detached: false, + cwd: cwd }); + + return { + process, + command: launchPath, + monoVersion, + }; } -export function hasMono(range?: string): Promise { +async function getMonoVersion(): Promise { const versionRegexp = /(\d+\.\d+\.\d+)/; - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { let childprocess: ChildProcess; try { childprocess = spawn('mono', ['--version']); } catch (e) { - return resolve(false); + return resolve(undefined); } childprocess.on('error', function (err: any) { - resolve(false); + resolve(undefined); }); let stdout = ''; @@ -379,20 +349,14 @@ export function hasMono(range?: string): Promise { }); childprocess.stdout.on('close', () => { - let match = versionRegexp.exec(stdout), - ret: boolean; + let match = versionRegexp.exec(stdout); - if (!match) { - ret = false; - } - else if (!range) { - ret = true; + if (match && match.length > 1) { + resolve(match[1]); } else { - ret = satisfies(match[1], range); + resolve(undefined); } - - resolve(ret); }); }); } \ No newline at end of file diff --git a/src/omnisharp/loggingEvents.ts b/src/omnisharp/loggingEvents.ts new file mode 100644 index 000000000..0a7f70fa6 --- /dev/null +++ b/src/omnisharp/loggingEvents.ts @@ -0,0 +1,145 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { PlatformInformation } from "../platform"; +import { Request } from "./requestQueue"; +import * as protocol from './protocol'; +import { LaunchTarget } from "./launcher"; + +export interface BaseEvent { +} + +export class TelemetryEventWithMeasures implements BaseEvent { + constructor(public eventName: string, public measures: { [key: string]: number }) { + } +} + +export class OmnisharpDelayTrackerEventMeasures extends TelemetryEventWithMeasures { +} + +export class OmnisharpStart extends TelemetryEventWithMeasures { +} + +export class OmnisharpInitialisation implements BaseEvent { + constructor(public timeStamp: Date, public solutionPath: string) { } +} + +export class OmnisharpLaunch implements BaseEvent { + constructor(public monoVersion: string, public command: string, public pid: number) { } +} + +export class PackageInstallation implements BaseEvent { + constructor(public packageInfo: string) { } +} + +export class LogPlatformInfo implements BaseEvent { + constructor(public info: PlatformInformation) { } +} + +export class InstallationStart implements BaseEvent { + constructor(public packageDescription: string) { } +} + +export class InstallationFailure implements BaseEvent { + constructor(public stage: string, public error: any) { } +} + +export class DownloadProgress implements BaseEvent { + constructor(public downloadPercentage: number, public packageDescription: string) { } +} + +export class OmnisharpFailure implements BaseEvent { + constructor(public message: string, public error: Error) { } +} + +export class OmnisharpRequestMessage implements BaseEvent { + constructor(public request: Request, public id: number) { } +} + +export class TestExecutionCountReport implements BaseEvent { + constructor(public debugCounts: { [testFrameworkName: string]: number }, public runCounts: { [testFrameworkName: string]: number }) { } +} + +export class OmnisharpServerOnError implements BaseEvent { + constructor(public errorMessage: protocol.ErrorMessage) { } +} + +export class OmnisharpServerMsBuildProjectDiagnostics implements BaseEvent { + constructor(public diagnostics: protocol.MSBuildProjectDiagnostics) { } +} + +export class OmnisharpServerUnresolvedDependencies implements BaseEvent { + constructor(public unresolvedDependencies: protocol.UnresolvedDependenciesMessage) { } +} + +export class OmnisharpServerEnqueueRequest implements BaseEvent { + constructor(public name: string, public command: string) { } +} + +export class OmnisharpServerDequeueRequest implements BaseEvent { + constructor(public name: string, public command: string, public id: number) { } +} + +export class OmnisharpServerProcessRequestStart implements BaseEvent { + constructor(public name: string) { } +} + +export class OmnisharpEventPacketReceived implements BaseEvent { + constructor(public logLevel: string, public name: string, public message: string) { } +} + +export class OmnisharpServerOnServerError implements BaseEvent { + constructor(public err: any) { } +} + +export class OmnisharpOnMultipleLaunchTargets implements BaseEvent { + constructor(public targets: LaunchTarget[]) { } +} + +export class WorkspaceInformationUpdated implements BaseEvent { + constructor(public info: protocol.WorkspaceInformationResponse) { } +} + +export class EventWithMessage implements BaseEvent { + constructor(public message: string) { } +} + +export class DownloadStart implements BaseEvent { + constructor(public packageDescription: string) { } +} + +export class DownloadFallBack implements BaseEvent { + constructor(public fallbackUrl: string) { } +} + +export class DownloadSizeObtained implements BaseEvent { + constructor(public packageSize: number) { } +} + +export class DebuggerPrerequisiteFailure extends EventWithMessage { } +export class DebuggerPrerequisiteWarning extends EventWithMessage { } +export class CommandDotNetRestoreProgress extends EventWithMessage { } +export class CommandDotNetRestoreSucceeded extends EventWithMessage { } +export class CommandDotNetRestoreFailed extends EventWithMessage { } +export class DownloadSuccess extends EventWithMessage { } +export class DownloadFailure extends EventWithMessage { } +export class OmnisharpServerOnStdErr extends EventWithMessage { } +export class OmnisharpServerMessage extends EventWithMessage { } +export class OmnisharpServerVerboseMessage extends EventWithMessage { } + +export class ProjectModified implements BaseEvent { } +export class ActivationFailure implements BaseEvent { } +export class CommandShowOutput implements BaseEvent { } +export class DebuggerNotInstalledFailure implements BaseEvent { } +export class CommandDotNetRestoreStart implements BaseEvent { } +export class InstallationSuccess implements BaseEvent { } +export class OmnisharpServerProcessRequestComplete implements BaseEvent { } +export class ProjectJsonDeprecatedWarning implements BaseEvent { } +export class OmnisharpOnBeforeServerStart implements BaseEvent { } +export class OmnisharpOnBeforeServerInstall implements BaseEvent { } +export class ActiveTextEditorChanged implements BaseEvent { } +export class OmnisharpServerOnStop implements BaseEvent { } +export class OmnisharpServerOnStart implements BaseEvent { } +export class LatestBuildDownloadStart implements BaseEvent { } \ No newline at end of file diff --git a/src/omnisharp/protocol.ts b/src/omnisharp/protocol.ts index 94e0835e0..4cd44950e 100644 --- a/src/omnisharp/protocol.ts +++ b/src/omnisharp/protocol.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; - import * as path from 'path'; export module Requests { @@ -398,6 +396,7 @@ export interface SignatureHelpItem { Label: string; Documentation: string; Parameters: SignatureHelpParameter[]; + StructuredDocumentation: DocumentationComment; } export interface SignatureHelpParameter { @@ -461,7 +460,9 @@ export namespace V2 { export const RunCodeAction = '/v2/runcodeaction'; export const GetTestStartInfo = '/v2/getteststartinfo'; export const RunTest = '/v2/runtest'; + export const RunAllTestsInClass = "/v2/runtestsinclass"; export const DebugTestGetStartInfo = '/v2/debugtest/getstartinfo'; + export const DebugTestsInClassGetStartInfo = '/v2/debugtestsinclass/getstartinfo'; export const DebugTestLaunch = '/v2/debugtest/launch'; export const DebugTestStop = '/v2/debugtest/stop'; } @@ -545,6 +546,12 @@ export namespace V2 { TargetFrameworkVersion: string; } + export interface DebugTestClassGetStartInfoRequest extends Request { + MethodNames: string[]; + TestFrameworkName: string; + TargetFrameworkVersion: string; + } + export interface DebugTestGetStartInfoResponse { FileName: string; Arguments: string; @@ -583,6 +590,12 @@ export namespace V2 { TargetFrameworkVersion: string; } + export interface RunTestsInClassRequest extends Request { + MethodNames: string[]; + TestFrameworkName: string; + TargetFrameworkVersion: string; + } + export module TestOutcomes { export const None = 'none'; export const Passed = 'passed'; diff --git a/src/omnisharp/requestQueue.ts b/src/omnisharp/requestQueue.ts index 644afba7f..c4c50d4dd 100644 --- a/src/omnisharp/requestQueue.ts +++ b/src/omnisharp/requestQueue.ts @@ -3,8 +3,9 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Logger } from '../logger'; import * as prioritization from './prioritization'; +import { OmnisharpServerProcessRequestComplete, OmnisharpServerProcessRequestStart, OmnisharpServerDequeueRequest, OmnisharpServerEnqueueRequest } from './loggingEvents'; +import { EventStream } from '../EventStream'; export interface Request { command: string; @@ -26,7 +27,7 @@ class RequestQueue { public constructor( private _name: string, private _maxSize: number, - private _logger: Logger, + private eventStream: EventStream, private _makeRequest: (request: Request) => number) { } @@ -34,7 +35,7 @@ class RequestQueue { * Enqueue a new request. */ public enqueue(request: Request) { - this._logger.appendLine(`Enqueue ${this._name} request for ${request.command}.`); + this.eventStream.post(new OmnisharpServerEnqueueRequest(this._name, request.command)); this._pending.push(request); } @@ -46,7 +47,7 @@ class RequestQueue { if (request) { this._waiting.delete(id); - this._logger.appendLine(`Dequeue ${this._name} request for ${request.command} (${id}).`); + this.eventStream.post(new OmnisharpServerDequeueRequest(this._name, request.command, id)); } return request; @@ -86,8 +87,7 @@ class RequestQueue { return; } - this._logger.appendLine(`Processing ${this._name} queue`); - this._logger.increaseIndent(); + this.eventStream.post(new OmnisharpServerProcessRequestStart(this._name)); const slots = this._maxSize - this._waiting.size; @@ -102,8 +102,7 @@ class RequestQueue { break; } } - - this._logger.decreaseIndent(); + this.eventStream.post(new OmnisharpServerProcessRequestComplete()); } } @@ -114,13 +113,13 @@ export class RequestQueueCollection { private _deferredQueue: RequestQueue; public constructor( - logger: Logger, + eventStream: EventStream, concurrency: number, makeRequest: (request: Request) => number ) { - this._priorityQueue = new RequestQueue('Priority', 1, logger, makeRequest); - this._normalQueue = new RequestQueue('Normal', concurrency, logger, makeRequest); - this._deferredQueue = new RequestQueue('Deferred', Math.max(Math.floor(concurrency / 4), 2), logger, makeRequest); + this._priorityQueue = new RequestQueue('Priority', 1, eventStream, makeRequest); + this._normalQueue = new RequestQueue('Normal', concurrency, eventStream, makeRequest); + this._deferredQueue = new RequestQueue('Deferred', Math.max(Math.floor(concurrency / 4), 2), eventStream, makeRequest); } private getQueue(command: string) { @@ -135,11 +134,10 @@ export class RequestQueueCollection { } } - public isEmpty() - { + public isEmpty() { return !this._deferredQueue.hasPending() - && !this._normalQueue.hasPending() - && !this._priorityQueue.hasPending(); + && !this._normalQueue.hasPending() + && !this._priorityQueue.hasPending(); } public enqueue(request: Request) { diff --git a/src/omnisharp/server.ts b/src/omnisharp/server.ts index bd3b9c8a9..510bf5904 100644 --- a/src/omnisharp/server.ts +++ b/src/omnisharp/server.ts @@ -3,22 +3,31 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { EventEmitter } from 'events'; -import { ChildProcess, exec } from 'child_process'; -import { ReadLine, createInterface } from 'readline'; -import { launchOmniSharp } from './launcher'; -import { Options } from './options'; -import { Logger } from '../logger'; -import { DelayTracker } from './delayTracker'; -import { LaunchTarget, findLaunchTargets } from './launcher'; -import { Request, RequestQueueCollection } from './requestQueue'; -import TelemetryReporter from 'vscode-extension-telemetry'; -import * as os from 'os'; import * as path from 'path'; import * as protocol from './protocol'; import * as utils from '../common'; -import * as vscode from 'vscode'; +import * as serverUtils from '../omnisharp/utils'; +import { vscode, CancellationToken } from '../vscodeAdapter'; + +import { ChildProcess, exec } from 'child_process'; +import { LaunchTarget, findLaunchTargets } from './launcher'; +import { ReadLine, createInterface } from 'readline'; +import { Request, RequestQueueCollection } from './requestQueue'; +import { DelayTracker } from './delayTracker'; +import { EventEmitter } from 'events'; +import { OmnisharpManager, LaunchInfo } from './OmnisharpManager'; +import { Options } from './options'; +import { PlatformInformation } from '../platform'; +import { launchOmniSharp } from './launcher'; import { setTimeout } from 'timers'; +import { OmnisharpDownloader } from './OmnisharpDownloader'; +import * as ObservableEvents from './loggingEvents'; +import { EventStream } from '../EventStream'; +import { NetworkSettingsProvider } from '../NetworkSettings'; +import { Subject } from 'rxjs/Subject'; +import 'rxjs/add/operator/debounceTime'; +import CompositeDisposable from '../CompositeDisposable'; +import Disposable from '../Disposable'; enum ServerState { Starting, @@ -58,17 +67,16 @@ module Events { } const TelemetryReportingDelay = 2 * 60 * 1000; // two minutes +const serverUrl = "https://roslynomnisharp.blob.core.windows.net"; +const installPath = ".omnisharp/experimental"; +const latestVersionFileServerPath = 'releases/versioninfo.txt'; export class OmniSharpServer { private static _nextId = 1; - - private _debugMode: boolean = false; - private _readLine: ReadLine; - private _disposables: vscode.Disposable[] = []; + private _disposables: CompositeDisposable; - private _reporter: TelemetryReporter; private _delayTrackers: { [requestName: string]: DelayTracker }; private _telemetryIntervalId: NodeJS.Timer = undefined; @@ -76,34 +84,35 @@ export class OmniSharpServer { private _state: ServerState = ServerState.Stopped; private _launchTarget: LaunchTarget; private _requestQueue: RequestQueueCollection; - private _channel: vscode.OutputChannel; - private _logger: Logger; - private _serverProcess: ChildProcess; private _options: Options; - constructor(reporter: TelemetryReporter) { - this._reporter = reporter; + private _omnisharpManager: OmnisharpManager; + private eventStream: EventStream; + private updateProjectDebouncer = new Subject(); + private firstUpdateProject: boolean; + private vscode: vscode; - this._channel = vscode.window.createOutputChannel('OmniSharp Log'); - this._logger = new Logger(message => this._channel.append(message)); + constructor(vscode: vscode, networkSettingsProvider: NetworkSettingsProvider, eventStream: EventStream, packageJSON: any, platformInfo: PlatformInformation) { + this.eventStream = eventStream; + this.vscode = vscode; + this._requestQueue = new RequestQueueCollection(this.eventStream, 8, request => this._makeRequest(request)); + let downloader = new OmnisharpDownloader(networkSettingsProvider, this.eventStream, packageJSON, platformInfo); + this._omnisharpManager = new OmnisharpManager(downloader, platformInfo); + this.updateProjectDebouncer.debounceTime(1500).subscribe((event) => { this.updateProjectInfo(); }); + this.firstUpdateProject = true; - const logger = this._debugMode - ? this._logger - : new Logger(message => { }); - - this._requestQueue = new RequestQueueCollection(logger, 8, request => this._makeRequest(request)); } public isRunning(): boolean { return this._state === ServerState.Started; } - public async waitForEmptyEventQueue() : Promise { + public async waitForEmptyEventQueue(): Promise { while (!this._requestQueue.isEmpty()) { let p = new Promise((resolve) => setTimeout(resolve, 100)); await p; - } + } } private _getState(): ServerState { @@ -137,7 +146,7 @@ export class OmniSharpServer { const measures = tracker.getMeasures(); tracker.clearMeasures(); - this._reporter.sendTelemetryEvent(eventName, null, measures); + this.eventStream.post(new ObservableEvents.OmnisharpDelayTrackerEventMeasures(eventName, measures)); } } } @@ -148,12 +157,7 @@ export class OmniSharpServer { : undefined; } - public getChannel(): vscode.OutputChannel { - return this._channel; - } - // --- eventing - public onStdout(listener: (e: string) => any, thisArg?: any) { return this._addListener(Events.StdOut, listener, thisArg); } @@ -226,10 +230,10 @@ export class OmniSharpServer { return this._addListener(Events.Started, listener); } - private _addListener(event: string, listener: (e: any) => any, thisArg?: any): vscode.Disposable { + private _addListener(event: string, listener: (e: any) => any, thisArg?: any): Disposable { listener = thisArg ? listener.bind(thisArg) : listener; this._eventBus.addListener(event, listener); - return new vscode.Disposable(() => this._eventBus.removeListener(event, listener)); + return new Disposable(() => this._eventBus.removeListener(event, listener)); } protected _fireEvent(event: string, args: any): void { @@ -238,14 +242,63 @@ export class OmniSharpServer { // --- start, stop, and connect - private _start(launchTarget: LaunchTarget): Promise { + private async _start(launchTarget: LaunchTarget): Promise { + + let disposables = new CompositeDisposable(); + + disposables.add(this.onServerError(err => + this.eventStream.post(new ObservableEvents.OmnisharpServerOnServerError(err)) + )); + + disposables.add(this.onError((message: protocol.ErrorMessage) => + this.eventStream.post(new ObservableEvents.OmnisharpServerOnError(message)) + )); + + disposables.add(this.onMsBuildProjectDiagnostics((message: protocol.MSBuildProjectDiagnostics) => + this.eventStream.post(new ObservableEvents.OmnisharpServerMsBuildProjectDiagnostics(message)) + )); + + disposables.add(this.onUnresolvedDependencies((message: protocol.UnresolvedDependenciesMessage) => + this.eventStream.post(new ObservableEvents.OmnisharpServerUnresolvedDependencies(message)) + )); + + disposables.add(this.onStderr((message: string) => + this.eventStream.post(new ObservableEvents.OmnisharpServerOnStdErr(message)) + )); + + disposables.add(this.onMultipleLaunchTargets((targets: LaunchTarget[]) => + this.eventStream.post(new ObservableEvents.OmnisharpOnMultipleLaunchTargets(targets)) + )); + + disposables.add(this.onBeforeServerInstall(() => + this.eventStream.post(new ObservableEvents.OmnisharpOnBeforeServerInstall()) + )); + + disposables.add(this.onBeforeServerStart(() => { + this.eventStream.post(new ObservableEvents.OmnisharpOnBeforeServerStart()); + })); + + disposables.add(this.onServerStop(() => + this.eventStream.post(new ObservableEvents.OmnisharpServerOnStop()) + )); + + disposables.add(this.onServerStart(() => { + this.eventStream.post(new ObservableEvents.OmnisharpServerOnStart()); + })); + + disposables.add(this.onProjectAdded(this.debounceUpdateProjectWithLeadingTrue)); + disposables.add(this.onProjectChange(this.debounceUpdateProjectWithLeadingTrue)); + disposables.add(this.onProjectRemoved(this.debounceUpdateProjectWithLeadingTrue)); + + this._disposables = disposables; + this._setState(ServerState.Starting); this._launchTarget = launchTarget; const solutionPath = launchTarget.target; const cwd = path.dirname(solutionPath); this._options = Options.Read(); - + let args = [ '-s', solutionPath, '--hostPID', process.pid.toString(), @@ -259,50 +312,59 @@ export class OmniSharpServer { args.push('--debug'); } - this._logger.appendLine(`Starting OmniSharp server at ${new Date().toLocaleString()}`); - this._logger.increaseIndent(); - this._logger.appendLine(`Target: ${solutionPath}`); - this._logger.decreaseIndent(); - this._logger.appendLine(); + let launchInfo: LaunchInfo; + try { + let extensionPath = utils.getExtensionPath(); + launchInfo = await this._omnisharpManager.GetOmniSharpLaunchInfo(this._options.path, serverUrl, latestVersionFileServerPath, installPath, extensionPath); + } + catch (error) { + this.eventStream.post(new ObservableEvents.OmnisharpFailure(`Error occured in loading omnisharp from omnisharp.path\nCould not start the server due to ${error.toString()}`, error)); + return; + } + this.eventStream.post(new ObservableEvents.OmnisharpInitialisation(new Date(), solutionPath)); this._fireEvent(Events.BeforeServerStart, solutionPath); - return launchOmniSharp(cwd, args).then(value => { - if (value.usingMono) { - this._logger.appendLine(`OmniSharp server started wth Mono`); - } - else { - this._logger.appendLine(`OmniSharp server started`); - } - - this._logger.increaseIndent(); - this._logger.appendLine(`Path: ${value.command}`); - this._logger.appendLine(`PID: ${value.process.pid}`); - this._logger.decreaseIndent(); - this._logger.appendLine(); + try { + let launchResult = await launchOmniSharp(cwd, args, launchInfo); + this.eventStream.post(new ObservableEvents.OmnisharpLaunch(launchResult.monoVersion, launchResult.command, launchResult.process.pid)); - this._serverProcess = value.process; + this._serverProcess = launchResult.process; this._delayTrackers = {}; this._setState(ServerState.Started); this._fireEvent(Events.ServerStart, solutionPath); - return this._doConnect(); - }).then(() => { - // Start telemetry reporting + await this._doConnect(); + this._telemetryIntervalId = setInterval(() => this._reportTelemetry(), TelemetryReportingDelay); - }).then(() => { this._requestQueue.drain(); - }).catch(err => { + } + catch (err) { this._fireEvent(Events.ServerError, err); return this.stop(); - }); + } } - public stop(): Promise { + private debounceUpdateProjectWithLeadingTrue = () => { + // Call the updateProjectInfo directly if it is the first time, otherwise debounce the request + // This needs to be done so that we have a project information for the first incoming request - while (this._disposables.length) { - this._disposables.pop().dispose(); + if (this.firstUpdateProject) { + this.updateProjectInfo(); } + else { + this.updateProjectDebouncer.next(new ObservableEvents.ProjectModified()); + } + } + + private updateProjectInfo = async () => { + this.firstUpdateProject = false; + let info = await serverUtils.requestWorkspaceInformation(this); + //once we get the info, push the event into the event stream + this.eventStream.post(new ObservableEvents.WorkspaceInformationUpdated(info)); + } + + public async stop(): Promise { let cleanupPromise: Promise; @@ -344,10 +406,16 @@ export class OmniSharpServer { }); } + let disposables = this._disposables; + this._disposables = null; + return cleanupPromise.then(() => { this._serverProcess = null; this._setState(ServerState.Stopped); this._fireEvent(Events.ServerStop, this); + if (disposables) { + disposables.dispose(); + } }); } @@ -359,13 +427,13 @@ export class OmniSharpServer { } public autoStart(preferredPath: string): Thenable { - return findLaunchTargets().then(launchTargets => { + return findLaunchTargets().then(async launchTargets => { // If there aren't any potential launch targets, we create file watcher and try to // start the server again once a *.sln, *.csproj, project.json, CSX or Cake file is created. if (launchTargets.length === 0) { return new Promise((resolve, reject) => { // 1st watch for files - let watcher = vscode.workspace.createFileSystemWatcher('{**/*.sln,**/*.csproj,**/project.json,**/*.csx,**/*.cake}', + let watcher = this.vscode.workspace.createFileSystemWatcher('{**/*.sln,**/*.csproj,**/project.json,**/*.csx,**/*.cake}', /*ignoreCreateEvents*/ false, /*ignoreChangeEvents*/ true, /*ignoreDeleteEvents*/ true); @@ -403,7 +471,7 @@ export class OmniSharpServer { // --- requests et al - public makeRequest(command: string, data?: any, token?: vscode.CancellationToken): Promise { + public async makeRequest(command: string, data?: any, token?: CancellationToken): Promise { if (this._getState() !== ServerState.Started) { return Promise.reject('server has been stopped or not started'); @@ -440,7 +508,7 @@ export class OmniSharpServer { }); } - private _doConnect(): Promise { + private async _doConnect(): Promise { this._serverProcess.stderr.on('data', (data: any) => { this._fireEvent('stderr', String(data)); @@ -453,7 +521,7 @@ export class OmniSharpServer { }); const promise = new Promise((resolve, reject) => { - let listener: vscode.Disposable; + let listener: Disposable; // Convert the timeout from the seconds to milliseconds, which is required by setTimeout(). const timeoutDuration = this._options.projectLoadTimeout * 1000; @@ -482,7 +550,7 @@ export class OmniSharpServer { this._readLine.addListener('line', lineReceived); - this._disposables.push(new vscode.Disposable(() => { + this._disposables.add(new Disposable(() => { this._readLine.removeListener('line', lineReceived); })); @@ -493,7 +561,7 @@ export class OmniSharpServer { line = line.trim(); if (line[0] !== '{') { - this._logger.appendLine(line); + this.eventStream.post(new ObservableEvents.OmnisharpServerMessage(line)); return; } @@ -519,7 +587,7 @@ export class OmniSharpServer { this._handleEventPacket(packet); break; default: - console.warn(`Unknown packet type: ${packet.Type}`); + this.eventStream.post(new ObservableEvents.OmnisharpServerMessage(`Unknown packet type: ${packet.Type}`)); break; } } @@ -528,13 +596,11 @@ export class OmniSharpServer { const request = this._requestQueue.dequeue(packet.Command, packet.Request_seq); if (!request) { - this._logger.appendLine(`Received response for ${packet.Command} but could not find request.`); + this.eventStream.post(new ObservableEvents.OmnisharpServerMessage(`Received response for ${packet.Command} but could not find request.`)); return; } - if (this._debugMode) { - this._logger.appendLine(`handleResponse: ${packet.Command} (${packet.Request_seq})`); - } + this.eventStream.post(new ObservableEvents.OmnisharpServerVerboseMessage(`handleResponse: ${packet.Command} (${packet.Request_seq})`)); if (packet.Success) { request.onSuccess(packet.Body); @@ -549,7 +615,7 @@ export class OmniSharpServer { private _handleEventPacket(packet: protocol.WireProtocol.EventPacket): void { if (packet.Event === 'log') { const entry = <{ LogLevel: string; Name: string; Message: string; }>packet.Body; - this._logOutput(entry.LogLevel, entry.Name, entry.Message); + this.eventStream.post(new ObservableEvents.OmnisharpEventPacketReceived(entry.LogLevel, entry.Name, entry.Message)); } else { // fwd all other events @@ -567,48 +633,8 @@ export class OmniSharpServer { Arguments: request.data }; - if (this._debugMode) { - this._logger.append(`makeRequest: ${request.command} (${id})`); - if (request.data) { - this._logger.append(`, data=${JSON.stringify(request.data)}`); - } - this._logger.appendLine(); - } - + this.eventStream.post(new ObservableEvents.OmnisharpRequestMessage(request, id)); this._serverProcess.stdin.write(JSON.stringify(requestPacket) + '\n'); - return id; } - - private static getLogLevelPrefix(logLevel: string) { - switch (logLevel) { - case "TRACE": return "trce"; - case "DEBUG": return "dbug"; - case "INFORMATION": return "info"; - case "WARNING": return "warn"; - case "ERROR": return "fail"; - case "CRITICAL": return "crit"; - default: throw new Error(`Unknown log level value: ${logLevel}`); - } - } - - private _isFilterableOutput(logLevel: string, name: string, message: string) { - // filter messages like: /codecheck: 200 339ms - const timing200Pattern = /^\/[\/\w]+: 200 \d+ms/; - - return logLevel === "INFORMATION" - && name === "OmniSharp.Middleware.LoggingMiddleware" - && timing200Pattern.test(message); - } - - private _logOutput(logLevel: string, name: string, message: string) { - if (this._debugMode || !this._isFilterableOutput(logLevel, name, message)) { - let output = `[${OmniSharpServer.getLogLevelPrefix(logLevel)}]: ${name}${os.EOL}${message}`; - - const newLinePlusPadding = os.EOL + " "; - output = output.replace(os.EOL, newLinePlusPadding); - - this._logger.appendLine(output); - } - } } diff --git a/src/omnisharp/typeConvertion.ts b/src/omnisharp/typeConvertion.ts index 532d026a0..546e6db05 100644 --- a/src/omnisharp/typeConvertion.ts +++ b/src/omnisharp/typeConvertion.ts @@ -2,7 +2,6 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; import * as protocol from './protocol'; import * as vscode from 'vscode'; diff --git a/src/omnisharp/utils.ts b/src/omnisharp/utils.ts index 6ae0391d0..a9e437a49 100644 --- a/src/omnisharp/utils.ts +++ b/src/omnisharp/utils.ts @@ -3,108 +3,114 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; - import { OmniSharpServer } from './server'; import * as protocol from './protocol'; import * as vscode from 'vscode'; -export function autoComplete(server: OmniSharpServer, request: protocol.AutoCompleteRequest) { +export async function autoComplete(server: OmniSharpServer, request: protocol.AutoCompleteRequest) { return server.makeRequest(protocol.Requests.AutoComplete, request); } -export function codeCheck(server: OmniSharpServer, request: protocol.Request, token: vscode.CancellationToken) { +export async function codeCheck(server: OmniSharpServer, request: protocol.Request, token: vscode.CancellationToken) { return server.makeRequest(protocol.Requests.CodeCheck, request, token); } -export function currentFileMembersAsTree(server: OmniSharpServer, request: protocol.Request, token: vscode.CancellationToken) { +export async function currentFileMembersAsTree(server: OmniSharpServer, request: protocol.Request, token: vscode.CancellationToken) { return server.makeRequest(protocol.Requests.CurrentFileMembersAsTree, request, token); } -export function filesChanged(server: OmniSharpServer, requests: protocol.Request[]) { +export async function filesChanged(server: OmniSharpServer, requests: protocol.Request[]) { return server.makeRequest(protocol.Requests.FilesChanged, requests); } -export function findImplementations(server: OmniSharpServer, request: protocol.FindImplementationsRequest, token: vscode.CancellationToken) { +export async function findImplementations(server: OmniSharpServer, request: protocol.FindImplementationsRequest, token: vscode.CancellationToken) { return server.makeRequest(protocol.Requests.FindImplementations, request); } -export function findSymbols(server: OmniSharpServer, request: protocol.FindSymbolsRequest, token: vscode.CancellationToken) { +export async function findSymbols(server: OmniSharpServer, request: protocol.FindSymbolsRequest, token: vscode.CancellationToken) { return server.makeRequest(protocol.Requests.FindSymbols, request, token); } -export function findUsages(server: OmniSharpServer, request: protocol.FindUsagesRequest, token: vscode.CancellationToken) { +export async function findUsages(server: OmniSharpServer, request: protocol.FindUsagesRequest, token: vscode.CancellationToken) { return server.makeRequest(protocol.Requests.FindUsages, request, token); } -export function formatAfterKeystroke(server: OmniSharpServer, request: protocol.FormatAfterKeystrokeRequest, token: vscode.CancellationToken) { +export async function formatAfterKeystroke(server: OmniSharpServer, request: protocol.FormatAfterKeystrokeRequest, token: vscode.CancellationToken) { return server.makeRequest(protocol.Requests.FormatAfterKeystroke, request, token); } -export function formatRange(server: OmniSharpServer, request: protocol.FormatRangeRequest, token: vscode.CancellationToken) { +export async function formatRange(server: OmniSharpServer, request: protocol.FormatRangeRequest, token: vscode.CancellationToken) { return server.makeRequest(protocol.Requests.FormatRange, request, token); } -export function getCodeActions(server: OmniSharpServer, request: protocol.V2.GetCodeActionsRequest, token: vscode.CancellationToken) { +export async function getCodeActions(server: OmniSharpServer, request: protocol.V2.GetCodeActionsRequest, token: vscode.CancellationToken) { return server.makeRequest(protocol.V2.Requests.GetCodeActions, request, token); } -export function goToDefinition(server: OmniSharpServer, request: protocol.GoToDefinitionRequest, token: vscode.CancellationToken) { +export async function goToDefinition(server: OmniSharpServer, request: protocol.GoToDefinitionRequest, token: vscode.CancellationToken) { return server.makeRequest(protocol.Requests.GoToDefinition, request); } -export function rename(server: OmniSharpServer, request: protocol.RenameRequest, token: vscode.CancellationToken) { +export async function rename(server: OmniSharpServer, request: protocol.RenameRequest, token: vscode.CancellationToken) { return server.makeRequest(protocol.Requests.Rename, request, token); } -export function requestProjectInformation(server: OmniSharpServer, request: protocol.Request) { +export async function requestProjectInformation(server: OmniSharpServer, request: protocol.Request) { return server.makeRequest(protocol.Requests.Project, request); } -export function requestWorkspaceInformation(server: OmniSharpServer) { +export async function requestWorkspaceInformation(server: OmniSharpServer) { return server.makeRequest(protocol.Requests.Projects); } -export function runCodeAction(server: OmniSharpServer, request: protocol.V2.RunCodeActionRequest) { +export async function runCodeAction(server: OmniSharpServer, request: protocol.V2.RunCodeActionRequest) { return server.makeRequest(protocol.V2.Requests.RunCodeAction, request); } -export function signatureHelp(server: OmniSharpServer, request: protocol.Request, token: vscode.CancellationToken) { +export async function signatureHelp(server: OmniSharpServer, request: protocol.Request, token: vscode.CancellationToken) { return server.makeRequest(protocol.Requests.SignatureHelp, request, token); } -export function typeLookup(server: OmniSharpServer, request: protocol.TypeLookupRequest, token: vscode.CancellationToken) { +export async function typeLookup(server: OmniSharpServer, request: protocol.TypeLookupRequest, token: vscode.CancellationToken) { return server.makeRequest(protocol.Requests.TypeLookup, request, token); } -export function updateBuffer(server: OmniSharpServer, request: protocol.UpdateBufferRequest) { +export async function updateBuffer(server: OmniSharpServer, request: protocol.UpdateBufferRequest) { return server.makeRequest(protocol.Requests.UpdateBuffer, request); } -export function getMetadata(server: OmniSharpServer, request: protocol.MetadataRequest) { +export async function getMetadata(server: OmniSharpServer, request: protocol.MetadataRequest) { return server.makeRequest(protocol.Requests.Metadata, request); } -export function getTestStartInfo(server: OmniSharpServer, request: protocol.V2.GetTestStartInfoRequest) { +export async function getTestStartInfo(server: OmniSharpServer, request: protocol.V2.GetTestStartInfoRequest) { return server.makeRequest(protocol.V2.Requests.GetTestStartInfo, request); } -export function runTest(server: OmniSharpServer, request: protocol.V2.RunTestRequest) { +export async function runTest(server: OmniSharpServer, request: protocol.V2.RunTestRequest) { return server.makeRequest(protocol.V2.Requests.RunTest, request); } -export function debugTestGetStartInfo(server: OmniSharpServer, request: protocol.V2.DebugTestGetStartInfoRequest) { +export async function runTestsInClass(server: OmniSharpServer, request: protocol.V2.RunTestsInClassRequest) { + return server.makeRequest(protocol.V2.Requests.RunAllTestsInClass, request); +} + +export async function debugTestGetStartInfo(server: OmniSharpServer, request: protocol.V2.DebugTestGetStartInfoRequest) { return server.makeRequest(protocol.V2.Requests.DebugTestGetStartInfo, request); } -export function debugTestLaunch(server: OmniSharpServer, request: protocol.V2.DebugTestLaunchRequest) { +export async function debugTestClassGetStartInfo(server: OmniSharpServer, request: protocol.V2.DebugTestClassGetStartInfoRequest) { + return server.makeRequest(protocol.V2.Requests.DebugTestsInClassGetStartInfo, request); +} + +export async function debugTestLaunch(server: OmniSharpServer, request: protocol.V2.DebugTestLaunchRequest) { return server.makeRequest(protocol.V2.Requests.DebugTestLaunch, request); } -export function debugTestStop(server: OmniSharpServer, request: protocol.V2.DebugTestStopRequest) { +export async function debugTestStop(server: OmniSharpServer, request: protocol.V2.DebugTestStopRequest) { return server.makeRequest(protocol.V2.Requests.DebugTestStop, request); } -export function isNetCoreProject(project: protocol.MSBuildProject) { +export async function isNetCoreProject(project: protocol.MSBuildProject) { return project.TargetFrameworks.find(tf => tf.ShortName.startsWith('netcoreapp') || tf.ShortName.startsWith('netstandard')) !== undefined; } \ No newline at end of file diff --git a/src/packageManager/FileDownloader.ts b/src/packageManager/FileDownloader.ts new file mode 100644 index 000000000..0541f8e46 --- /dev/null +++ b/src/packageManager/FileDownloader.ts @@ -0,0 +1,111 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as https from 'https'; +import * as util from '../common'; +import * as fs from 'fs'; +import { EventStream } from "../EventStream"; +import { DownloadSuccess, DownloadStart, DownloadFallBack, DownloadFailure, DownloadProgress, DownloadSizeObtained } from "../omnisharp/loggingEvents"; +import { NestedError } from "../NestedError"; +import { parse as parseUrl } from 'url'; +import { getProxyAgent } from './proxy'; +import { NetworkSettingsProvider } from '../NetworkSettings'; + +export async function DownloadFile(destinationFileDescriptor: number, description: string, eventStream: EventStream, networkSettingsProvider: NetworkSettingsProvider, url: string, fallbackUrl?: string){ + eventStream.post(new DownloadStart(description)); + + try { + await downloadFile(destinationFileDescriptor, description, url, eventStream, networkSettingsProvider); + eventStream.post(new DownloadSuccess(` Done!`)); + } + catch (primaryUrlError) { + // If the package has a fallback Url, and downloading from the primary Url failed, try again from + // the fallback. This is used for debugger packages as some users have had issues downloading from + // the CDN link + if (fallbackUrl) { + eventStream.post(new DownloadFallBack(fallbackUrl)); + try { + await downloadFile(destinationFileDescriptor, description, fallbackUrl, eventStream, networkSettingsProvider); + eventStream.post(new DownloadSuccess(' Done!')); + } + catch (fallbackUrlError) { + throw primaryUrlError; + } + } + else { + throw primaryUrlError; + } + } +} + +async function downloadFile(fd: number, description: string, urlString: string, eventStream: EventStream, networkSettingsProvider: NetworkSettingsProvider): Promise { + const url = parseUrl(urlString); + const networkSettings = networkSettingsProvider(); + const proxy = networkSettings.proxy; + const strictSSL = networkSettings.strictSSL; + const options: https.RequestOptions = { + host: url.hostname, + path: url.path, + agent: getProxyAgent(url, proxy, strictSSL), + port: url.port, + rejectUnauthorized: util.isBoolean(strictSSL) ? strictSSL : true + }; + + return new Promise((resolve, reject) => { + if (fd == 0) { + reject(new NestedError("Temporary package file unavailable")); + } + + let request = https.request(options, response => { + if (response.statusCode === 301 || response.statusCode === 302) { + // Redirect - download from new location + return resolve(downloadFile(fd, description, response.headers.location, eventStream, networkSettingsProvider)); + } + + else if (response.statusCode != 200) { + // Download failed - print error message + eventStream.post(new DownloadFailure(`failed (error code '${response.statusCode}')`)); + return reject(new NestedError(response.statusCode.toString())); + } + + // Downloading - hook up events + let packageSize = parseInt(response.headers['content-length'], 10); + let downloadedBytes = 0; + let downloadPercentage = 0; + let tmpFile = fs.createWriteStream(null, { fd }); + + eventStream.post(new DownloadSizeObtained(packageSize)); + + response.on('data', data => { + downloadedBytes += data.length; + + // Update status bar item with percentage + let newPercentage = Math.ceil(100 * (downloadedBytes / packageSize)); + if (newPercentage !== downloadPercentage) { + downloadPercentage = newPercentage; + eventStream.post(new DownloadProgress(downloadPercentage, description)); + } + }); + + response.on('end', () => { + resolve(); + }); + + response.on('error', err => { + reject(new NestedError(`Reponse error: ${err.message || 'NONE'}`, err)); + }); + + // Begin piping data from the response to the package file + response.pipe(tmpFile, { end: false }); + }); + + request.on('error', err => { + reject(new NestedError(`Request error: ${err.message || 'NONE'}`, err)); + }); + + // Execute the request + request.end(); + }); +} \ No newline at end of file diff --git a/src/packageManager/Package.ts b/src/packageManager/Package.ts new file mode 100644 index 000000000..f941d5578 --- /dev/null +++ b/src/packageManager/Package.ts @@ -0,0 +1,17 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +export interface Package { + description: string; + url: string; + fallbackUrl?: string; + installPath?: string; + platforms: string[]; + architectures: string[]; + binaries: string[]; + platformId?: string; + // Path to use to test if the package has already been installed + installTestPath?: string; +} diff --git a/src/packageManager/PackageError.ts b/src/packageManager/PackageError.ts new file mode 100644 index 000000000..69423f0e9 --- /dev/null +++ b/src/packageManager/PackageError.ts @@ -0,0 +1,16 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { NestedError } from '../NestedError'; +import { Package } from './Package'; + +export class PackageError extends NestedError { + // Do not put PII (personally identifiable information) in the 'message' field as it will be logged to telemetry + constructor(public message: string, + public pkg: Package = null, + public innerError: any = null) { + super(message, innerError); + } +} \ No newline at end of file diff --git a/src/packageManager/PackageFilePathResolver.ts b/src/packageManager/PackageFilePathResolver.ts new file mode 100644 index 000000000..7c1fac687 --- /dev/null +++ b/src/packageManager/PackageFilePathResolver.ts @@ -0,0 +1,39 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as path from 'path'; +import * as util from '../common'; +import { Package } from './Package'; + +export function ResolveFilePaths(pkg: Package) { + pkg.installTestPath = ResolvePackageTestPath(pkg); + pkg.installPath = ResolveBaseInstallPath(pkg); + pkg.binaries = ResolvePackageBinaries(pkg); +} + +export function ResolvePackageTestPath(pkg: Package): string { + if (pkg.installTestPath) { + return path.resolve(util.getExtensionPath(), pkg.installTestPath); + } + + return null; +} + +function ResolvePackageBinaries(pkg: Package) { + if (pkg.binaries) { + return pkg.binaries.map(value => path.resolve(ResolveBaseInstallPath(pkg), value)); + } + + return null; +} + +function ResolveBaseInstallPath(pkg: Package): string { + let basePath = util.getExtensionPath(); + if (pkg.installPath) { + basePath = path.resolve(basePath, pkg.installPath); + } + + return basePath; +} diff --git a/src/packageManager/PackageFilterer.ts b/src/packageManager/PackageFilterer.ts new file mode 100644 index 000000000..36ead88ac --- /dev/null +++ b/src/packageManager/PackageFilterer.ts @@ -0,0 +1,49 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Package } from "./Package"; +import { PlatformInformation } from "../platform"; +import * as util from '../common'; +import { ResolvePackageTestPath } from "./PackageFilePathResolver"; +import { PackageError } from "./PackageError"; + +const { filterAsync } = require('node-filter-async'); + +export async function filterPackages(packages: Package[], platformInfo: PlatformInformation) { + let platformPackages = filterPlatformPackages(packages, platformInfo); + return filterAlreadyInstalledPackages(platformPackages); +} + +function filterPlatformPackages(packages: Package[], platformInfo: PlatformInformation) { + if (packages) { + return packages.filter(pkg => { + if (pkg.architectures && pkg.architectures.indexOf(platformInfo.architecture) === -1) { + return false; + } + + if (pkg.platforms && pkg.platforms.indexOf(platformInfo.platform) === -1) { + return false; + } + + return true; + }); + } + else { + throw new PackageError("Package manifest does not exist."); + } +} + +async function filterAlreadyInstalledPackages(packages: Package[]): Promise { + return filterAsync(packages, async (pkg: Package) => { + //If the file is present at the install test path then filter it + let testPath = ResolvePackageTestPath(pkg); + if (!testPath) { + //if there is no testPath specified then we will not filter it + return true; + } + + return !(await util.fileExists(testPath)); + }); +} \ No newline at end of file diff --git a/src/packageManager/PackageManager.ts b/src/packageManager/PackageManager.ts new file mode 100644 index 000000000..64b229b9f --- /dev/null +++ b/src/packageManager/PackageManager.ts @@ -0,0 +1,46 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { PlatformInformation } from "../platform"; +import { Package } from './Package'; +import { PackageError } from './PackageError'; +import { NestedError } from "../NestedError"; +import { DownloadFile } from './FileDownloader'; +import { InstallZip } from './ZipInstaller'; +import { EventStream } from '../EventStream'; +import { NetworkSettingsProvider } from "../NetworkSettings"; +import { filterPackages } from "./PackageFilterer"; +import { CreateTmpFile, TmpAsset } from "../CreateTmpAsset"; + +// Package manager needs a list of packages to be filtered based on platformInfo then download and install them +// Note that the packages that this component will install needs absolute paths for the installPath, intsallTestPath and the binaries +export async function DownloadAndInstallPackages(packages: Package[], provider: NetworkSettingsProvider, platformInfo: PlatformInformation, eventStream: EventStream) { + let filteredPackages = await filterPackages(packages, platformInfo); + if (filteredPackages) { + let tmpFile: TmpAsset; + for (let pkg of filteredPackages) { + try { + tmpFile = await CreateTmpFile(); + await DownloadFile(tmpFile.fd, pkg.description, eventStream, provider, pkg.url, pkg.fallbackUrl); + await InstallZip(tmpFile.fd, pkg.description, pkg.installPath, pkg.binaries, eventStream); + } + catch (error) { + if (error instanceof NestedError) { + throw new PackageError(error.message, pkg, error.err); + } + else { + throw error; + } + } + finally { + //clean the temporary file + if (tmpFile) { + tmpFile.dispose(); + } + } + } + } +} + diff --git a/src/packageManager/ZipInstaller.ts b/src/packageManager/ZipInstaller.ts new file mode 100644 index 000000000..3907254be --- /dev/null +++ b/src/packageManager/ZipInstaller.ts @@ -0,0 +1,76 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as fs from 'fs'; +import * as mkdirp from 'mkdirp'; +import * as path from 'path'; +import * as yauzl from 'yauzl'; +import { EventStream } from "../EventStream"; +import { InstallationStart } from "../omnisharp/loggingEvents"; +import { NestedError } from '../NestedError'; + +export async function InstallZip(sourceFileDescriptor: number, description: string, destinationInstallPath: string, binaries: string[], eventStream: EventStream): Promise { + eventStream.post(new InstallationStart(description)); + + return new Promise((resolve, reject) => { + if (sourceFileDescriptor == 0) { + return reject(new NestedError('Downloaded file unavailable')); + } + + yauzl.fromFd(sourceFileDescriptor, { lazyEntries: true }, (err, zipFile) => { + if (err) { + return reject(new NestedError('Immediate zip file error', err)); + } + + zipFile.readEntry(); + + zipFile.on('entry', (entry: yauzl.Entry) => { + let absoluteEntryPath = path.resolve(destinationInstallPath, entry.fileName); + + if (entry.fileName.endsWith('/')) { + // Directory - create it + mkdirp(absoluteEntryPath, { mode: 0o775 }, err => { + if (err) { + return reject(new NestedError('Error creating directory for zip directory entry:' + err.code || '', err)); + } + + zipFile.readEntry(); + }); + } + else { + // File - extract it + zipFile.openReadStream(entry, (err, readStream) => { + if (err) { + return reject(new NestedError('Error reading zip stream', err)); + } + + mkdirp(path.dirname(absoluteEntryPath), { mode: 0o775 }, err => { + if (err) { + return reject(new NestedError('Error creating directory for zip file entry', err)); + } + + // Make sure executable files have correct permissions when extracted + let fileMode = binaries && binaries.indexOf(absoluteEntryPath) !== -1 + ? 0o755 + : 0o664; + + readStream.pipe(fs.createWriteStream(absoluteEntryPath, { mode: fileMode })); + readStream.on('end', () => zipFile.readEntry()); + }); + }); + } + }); + + zipFile.on('end', () => { + resolve(); + }); + + zipFile.on('error', err => { + reject(new NestedError('Zip File Error:' + err.code || '', err)); + }); + }); + }); +} + diff --git a/src/proxy.ts b/src/packageManager/proxy.ts similarity index 96% rename from src/proxy.ts rename to src/packageManager/proxy.ts index babc2669a..c572da761 100644 --- a/src/proxy.ts +++ b/src/packageManager/proxy.ts @@ -3,10 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -'use strict'; - import { Url, parse as parseUrl } from 'url'; -import { isBoolean } from './common'; +import { isBoolean } from '../common'; import HttpProxyAgent = require('http-proxy-agent'); import HttpsProxyAgent = require('https-proxy-agent'); diff --git a/src/packages.ts b/src/packages.ts deleted file mode 100644 index 2e3592d35..000000000 --- a/src/packages.ts +++ /dev/null @@ -1,356 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as fs from 'fs'; -import * as https from 'https'; -import * as mkdirp from 'mkdirp'; -import * as path from 'path'; -import * as tmp from 'tmp'; -import { parse as parseUrl } from 'url'; -import * as yauzl from 'yauzl'; -import * as util from './common'; -import { Logger } from './logger'; -import { PlatformInformation } from './platform'; -import { getProxyAgent } from './proxy'; - -export interface Package { - description: string; - url: string; - fallbackUrl?: string; - installPath?: string; - platforms: string[]; - architectures: string[]; - binaries: string[]; - tmpFile: tmp.SynchrounousResult; - - // Path to use to test if the package has already been installed - installTestPath?: string; -} - -export interface Status { - setMessage: (text: string) => void; - setDetail: (text: string) => void; -} - -export class PackageError extends Error { - // Do not put PII (personally identifiable information) in the 'message' field as it will be logged to telemetry - constructor(public message: string, - public pkg: Package = null, - public innerError: any = null) { - super(message); - } -} - -export class PackageManager { - private allPackages: Package[]; - - public constructor( - private platformInfo: PlatformInformation, - private packageJSON: any) { - - // Ensure our temp files get cleaned up in case of error. - tmp.setGracefulCleanup(); - } - - public DownloadPackages(logger: Logger, status: Status, proxy: string, strictSSL: boolean): Promise { - return this.GetPackages() - .then(packages => { - return util.buildPromiseChain(packages, pkg => maybeDownloadPackage(pkg, logger, status, proxy, strictSSL)); - }); - } - - public InstallPackages(logger: Logger, status: Status): Promise { - return this.GetPackages() - .then(packages => { - return util.buildPromiseChain(packages, pkg => installPackage(pkg, logger, status)); - }); - } - - private GetAllPackages(): Promise { - return new Promise((resolve, reject) => { - if (this.allPackages) { - resolve(this.allPackages); - } - else if (this.packageJSON.runtimeDependencies) { - this.allPackages = this.packageJSON.runtimeDependencies; - - // Convert relative binary paths to absolute - for (let pkg of this.allPackages) { - if (pkg.binaries) { - pkg.binaries = pkg.binaries.map(value => path.resolve(getBaseInstallPath(pkg), value)); - } - } - - resolve(this.allPackages); - } - else { - reject(new PackageError("Package manifest does not exist.")); - } - }); - } - - private GetPackages(): Promise { - return this.GetAllPackages() - .then(list => { - return list.filter(pkg => { - if (pkg.architectures && pkg.architectures.indexOf(this.platformInfo.architecture) === -1) { - return false; - } - - if (pkg.platforms && pkg.platforms.indexOf(this.platformInfo.platform) === -1) { - return false; - } - - return true; - }); - }); - } -} - -function getBaseInstallPath(pkg: Package): string { - let basePath = util.getExtensionPath(); - if (pkg.installPath) { - basePath = path.join(basePath, pkg.installPath); - } - - return basePath; -} - -function getNoopStatus(): Status { - return { - setMessage: text => { }, - setDetail: text => { } - }; -} - -function maybeDownloadPackage(pkg: Package, logger: Logger, status: Status, proxy: string, strictSSL: boolean): Promise { - return doesPackageTestPathExist(pkg).then((exists: boolean) => { - if (!exists) { - return downloadPackage(pkg, logger, status, proxy, strictSSL); - } else { - logger.appendLine(`Skipping package '${pkg.description}' (already downloaded).`); - } - }); -} - -function downloadPackage(pkg: Package, logger: Logger, status: Status, proxy: string, strictSSL: boolean): Promise { - status = status || getNoopStatus(); - - logger.append(`Downloading package '${pkg.description}' `); - - status.setMessage("$(cloud-download) Downloading packages"); - status.setDetail(`Downloading package '${pkg.description}'...`); - - return new Promise((resolve, reject) => { - tmp.file({ prefix: 'package-' }, (err, path, fd, cleanupCallback) => { - if (err) { - return reject(new PackageError('Error from tmp.file', pkg, err)); - } - - resolve({ name: path, fd: fd, removeCallback: cleanupCallback }); - }); - }).then(tmpResult => { - pkg.tmpFile = tmpResult; - - let result = downloadFile(pkg.url, pkg, logger, status, proxy, strictSSL) - .then(() => logger.appendLine(' Done!')); - - // If the package has a fallback Url, and downloading from the primary Url failed, try again from - // the fallback. This is used for debugger packages as some users have had issues downloading from - // the CDN link. - if (pkg.fallbackUrl) { - result = result.catch((primaryUrlError) => { - logger.append(`\tRetrying from '${pkg.fallbackUrl}' `); - return downloadFile(pkg.fallbackUrl, pkg, logger, status, proxy, strictSSL) - .then(() => logger.appendLine(' Done!')) - .catch(() => primaryUrlError); - }); - } - - return result; - }); -} - -function downloadFile(urlString: string, pkg: Package, logger: Logger, status: Status, proxy: string, strictSSL: boolean): Promise { - const url = parseUrl(urlString); - - const options: https.RequestOptions = { - host: url.host, - path: url.path, - agent: getProxyAgent(url, proxy, strictSSL), - rejectUnauthorized: util.isBoolean(strictSSL) ? strictSSL : true - }; - - return new Promise((resolve, reject) => { - if (!pkg.tmpFile || pkg.tmpFile.fd == 0) { - return reject(new PackageError("Temporary package file unavailable", pkg)); - } - - let request = https.request(options, response => { - if (response.statusCode === 301 || response.statusCode === 302) { - // Redirect - download from new location - return resolve(downloadFile(response.headers.location, pkg, logger, status, proxy, strictSSL)); - } - - if (response.statusCode != 200) { - // Download failed - print error message - logger.appendLine(`failed (error code '${response.statusCode}')`); - return reject(new PackageError(response.statusCode.toString(), pkg)); - } - - // Downloading - hook up events - let packageSize = parseInt(response.headers['content-length'], 10); - let downloadedBytes = 0; - let downloadPercentage = 0; - let dots = 0; - let tmpFile = fs.createWriteStream(null, { fd: pkg.tmpFile.fd }); - - logger.append(`(${Math.ceil(packageSize / 1024)} KB) `); - - response.on('data', data => { - downloadedBytes += data.length; - - // Update status bar item with percentage - let newPercentage = Math.ceil(100 * (downloadedBytes / packageSize)); - if (newPercentage !== downloadPercentage) { - status.setDetail(`Downloading package '${pkg.description}'... ${downloadPercentage}%`); - downloadPercentage = newPercentage; - } - - // Update dots after package name in output console - let newDots = Math.ceil(downloadPercentage / 5); - if (newDots > dots) { - logger.append('.'.repeat(newDots - dots)); - dots = newDots; - } - }); - - response.on('end', () => { - resolve(); - }); - - response.on('error', err => { - reject(new PackageError(`Reponse error: ${err.message || 'NONE'}`, pkg, err)); - }); - - // Begin piping data from the response to the package file - response.pipe(tmpFile, { end: false }); - }); - - request.on('error', err => { - reject(new PackageError(`Request error: ${err.message || 'NONE'}`, pkg, err)); - }); - - // Execute the request - request.end(); - }); -} - -function installPackage(pkg: Package, logger: Logger, status?: Status): Promise { - - if (!pkg.tmpFile) { - // Download of this package was skipped, so there is nothing to install - return Promise.resolve(); - } - - status = status || getNoopStatus(); - - logger.appendLine(`Installing package '${pkg.description}'`); - - status.setMessage("$(desktop-download) Installing packages..."); - status.setDetail(`Installing package '${pkg.description}'`); - - return new Promise((resolve, baseReject) => { - const reject = (err) => { - // If anything goes wrong with unzip, make sure we delete the test path (if there is one) - // so we will retry again later - const testPath = getPackageTestPath(pkg); - if (testPath) { - fs.unlink(testPath, unlinkErr => { - baseReject(err); - }); - } else { - baseReject(err); - } - }; - - if (pkg.tmpFile.fd == 0) { - return reject(new PackageError('Downloaded file unavailable', pkg)); - } - - yauzl.fromFd(pkg.tmpFile.fd, { lazyEntries: true }, (err, zipFile) => { - if (err) { - return reject(new PackageError('Immediate zip file error', pkg, err)); - } - - zipFile.readEntry(); - - zipFile.on('entry', (entry: yauzl.Entry) => { - let absoluteEntryPath = path.resolve(getBaseInstallPath(pkg), entry.fileName); - - if (entry.fileName.endsWith('/')) { - // Directory - create it - mkdirp(absoluteEntryPath, { mode: 0o775 }, err => { - if (err) { - return reject(new PackageError('Error creating directory for zip directory entry:' + err.code || '', pkg, err)); - } - - zipFile.readEntry(); - }); - } - else { - // File - extract it - zipFile.openReadStream(entry, (err, readStream) => { - if (err) { - return reject(new PackageError('Error reading zip stream', pkg, err)); - } - - mkdirp(path.dirname(absoluteEntryPath), { mode: 0o775 }, err => { - if (err) { - return reject(new PackageError('Error creating directory for zip file entry', pkg, err)); - } - - // Make sure executable files have correct permissions when extracted - let fileMode = pkg.binaries && pkg.binaries.indexOf(absoluteEntryPath) !== -1 - ? 0o755 - : 0o664; - - readStream.pipe(fs.createWriteStream(absoluteEntryPath, { mode: fileMode })); - readStream.on('end', () => zipFile.readEntry()); - }); - }); - } - }); - - zipFile.on('end', () => { - resolve(); - }); - - zipFile.on('error', err => { - reject(new PackageError('Zip File Error:' + err.code || '', pkg, err)); - }); - }); - }).then(() => { - // Clean up temp file - pkg.tmpFile.removeCallback(); - }); -} - -function doesPackageTestPathExist(pkg: Package) : Promise { - const testPath = getPackageTestPath(pkg); - if (testPath) { - return util.fileExists(testPath); - } else { - return Promise.resolve(false); - } -} - -function getPackageTestPath(pkg: Package) : string { - if (pkg.installTestPath) { - return path.join(util.getExtensionPath(), pkg.installTestPath); - } else { - return null; - } -} \ No newline at end of file diff --git a/src/platform.ts b/src/platform.ts index eab4935be..e05f549a6 100644 --- a/src/platform.ts +++ b/src/platform.ts @@ -22,12 +22,12 @@ export class LinuxDistribution { public version: string, public idLike?: string[]) { } - public static GetCurrent(): Promise { + public static async GetCurrent(): Promise { // Try /etc/os-release and fallback to /usr/lib/os-release per the synopsis // at https://www.freedesktop.org/software/systemd/man/os-release.html. return LinuxDistribution.FromFilePath('/etc/os-release') - .catch(() => LinuxDistribution.FromFilePath('/usr/lib/os-release')) - .catch(() => Promise.resolve(new LinuxDistribution(unknown, unknown))); + .catch(async () => LinuxDistribution.FromFilePath('/usr/lib/os-release')) + .catch(async () => Promise.resolve(new LinuxDistribution(unknown, unknown))); } public toString(): string { @@ -62,7 +62,7 @@ export class LinuxDistribution { } } - private static FromFilePath(filePath: string): Promise { + private static async FromFilePath(filePath: string): Promise { return new Promise((resolve, reject) => { fs.readFile(filePath, 'utf8', (error, data) => { if (error) { @@ -156,7 +156,7 @@ export class PlatformInformation { return result; } - public static GetCurrent(): Promise { + public static async GetCurrent(): Promise { let platform = os.platform(); let architecturePromise: Promise; let distributionPromise: Promise; @@ -181,13 +181,12 @@ export class PlatformInformation { throw new Error(`Unsupported platform: ${platform}`); } - return Promise.all([architecturePromise, distributionPromise]) - .then(([arch, distro]) => { - return new PlatformInformation(platform, arch, distro); - }); + const platformData: [string, LinuxDistribution] = await Promise.all([architecturePromise, distributionPromise]); + + return new PlatformInformation(platform, platformData[0], platformData[1]); } - private static GetWindowsArchitecture(): Promise { + private static async GetWindowsArchitecture(): Promise { return new Promise((resolve, reject) => { if (process.env.PROCESSOR_ARCHITECTURE === 'x86' && process.env.PROCESSOR_ARCHITEW6432 === undefined) { resolve('x86'); @@ -198,7 +197,7 @@ export class PlatformInformation { }); } - private static GetUnixArchitecture(): Promise { + private static async GetUnixArchitecture(): Promise { return util.execChildProcess('uname -m') .then(architecture => { if (architecture) { diff --git a/src/statusBarItemAdapter.ts b/src/statusBarItemAdapter.ts new file mode 100644 index 000000000..f91d56054 --- /dev/null +++ b/src/statusBarItemAdapter.ts @@ -0,0 +1,65 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as vscodeAdapter from './vscodeAdapter'; +import * as vscode from 'vscode'; + +export class StatusBarItemAdapter implements vscodeAdapter.StatusBarItem { + + get alignment(): vscodeAdapter.StatusBarAlignment{ + return this.statusBarItem.alignment; + } + + get priority(): number{ + return this.statusBarItem.priority; + } + + get text(): string{ + return this.statusBarItem.text; + } + + set text(value: string) { + this.statusBarItem.text = value; + } + + get tooltip(): string{ + return this.statusBarItem.tooltip; + } + + set tooltip(value: string){ + this.statusBarItem.tooltip = value; + } + + get color(): string{ + return this.statusBarItem.color as string; + } + + set color(value: string) { + this.statusBarItem.color = value; + } + + get command(): string{ + return this.statusBarItem.command; + } + + set command(value: string) { + this.statusBarItem.command = value; + } + + show(): void { + this.statusBarItem.show(); + } + + hide(): void { + this.statusBarItem.hide(); + } + + dispose(): void { + this.statusBarItem.dispose(); + } + + constructor(private statusBarItem: vscode.StatusBarItem) { + } +} \ No newline at end of file diff --git a/src/textEditorAdapter.ts b/src/textEditorAdapter.ts new file mode 100644 index 000000000..c08b196c5 --- /dev/null +++ b/src/textEditorAdapter.ts @@ -0,0 +1,17 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as vscodeAdapter from './vscodeAdapter'; +import * as vscode from 'vscode'; + +export class TextEditorAdapter implements vscodeAdapter.TextEditor { + + get document(): any { + return this.textEditor.document; + } + + constructor(private textEditor: vscode.TextEditor) { + } +} \ No newline at end of file diff --git a/src/tools/GenerateOptionsSchema.ts b/src/tools/GenerateOptionsSchema.ts index a14dedf99..c87eee505 100644 --- a/src/tools/GenerateOptionsSchema.ts +++ b/src/tools/GenerateOptionsSchema.ts @@ -85,9 +85,20 @@ function ReplaceReferences(definitions: any, objects: any) { return objects; } +function mergeReferences(baseDefinitions: any, additionalDefinitions: any) : void { + for (let key in additionalDefinitions) { + if (baseDefinitions[key]) { + throw `Error: '${key}' defined in multiple schema files.`; + } + baseDefinitions[key] = additionalDefinitions[key]; + } +} + export function GenerateOptionsSchema() { let packageJSON: any = JSON.parse(fs.readFileSync('package.json').toString()); let schemaJSON: any = JSON.parse(fs.readFileSync('src/tools/OptionsSchema.json').toString()); + let symbolSettingsJSON: any = JSON.parse(fs.readFileSync('src/tools/VSSymbolSettings.json').toString()); + mergeReferences(schemaJSON.definitions, symbolSettingsJSON.definitions); schemaJSON.definitions = ReplaceReferences(schemaJSON.definitions, schemaJSON.definitions); @@ -100,9 +111,37 @@ export function GenerateOptionsSchema() { packageJSON.contributes.debuggers[1].configurationAttributes.launch = schemaJSON.definitions.LaunchOptions; packageJSON.contributes.debuggers[1].configurationAttributes.attach = schemaJSON.definitions.AttachOptions; + // Make a copy of the options for unit test debugging + let unitTestDebuggingOptions = JSON.parse(JSON.stringify(schemaJSON.definitions.AttachOptions.properties)); + // Remove the options we don't want + delete unitTestDebuggingOptions.processName; + delete unitTestDebuggingOptions.processId; + delete unitTestDebuggingOptions.pipeTransport; + // Add the additional options we do want + unitTestDebuggingOptions["type"] = { + "type": "string", + "enum": [ + "coreclr", + "clr" + ], + "description": "Type type of code to debug. Can be either 'coreclr' for .NET Core debugging, or 'clr' for Desktop .NET Framework. 'clr' only works on Windows as the Desktop framework is Windows-only.", + "default": "coreclr" + }; + unitTestDebuggingOptions["debugServer"] = { + "type": "number", + "description": "For debug extension development only: if a port is specified VS Code tries to connect to a debug adapter running in server mode", + "default": 4711 + }; + packageJSON.contributes.configuration.properties["csharp.unitTestDebuggingOptions"].properties = unitTestDebuggingOptions; + let content = JSON.stringify(packageJSON, null, 2); if (os.platform() === 'win32') { content = content.replace(/\n/gm, "\r\n"); } + + // We use '\u200b' (unicode zero-length space character) to break VS Code's URL detection regex for URLs that are examples. This process will + // convert that from the readable espace sequence, to just an invisible character. Convert it back to the visible espace sequence. + content = content.replace(/\u200b/gm, "\\u200b"); + fs.writeFileSync('package.json', content); } diff --git a/src/tools/OptionsSchema.json b/src/tools/OptionsSchema.json index cb8c9fb69..53367ba42 100644 --- a/src/tools/OptionsSchema.json +++ b/src/tools/OptionsSchema.json @@ -1,446 +1,484 @@ { - "_comment": "See README.md for information about this file", - "$schema": "http://json-schema.org/draft-04/schema#", - "title": "VS Code launch/attach options", - "description": "A json schema for the VS Code attach and launch options", - "type": "object", - "definitions": { - "PipeConfigurations": { - "type": "object", - "description": "Platform-specific pipe launch configuration options", - "default": { - "pipeCwd": "${workspaceFolder}", - "pipeProgram": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'", - "pipeArgs": [] + "_comment": "See README.md for information about this file", + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "VS Code launch/attach options", + "description": "A json schema for the VS Code attach and launch options", + "type": "object", + "definitions": { + "PipeConfigurations": { + "type": "object", + "description": "Platform-specific pipe launch configuration options", + "default": { + "pipeCwd": "${workspaceFolder}", + "pipeProgram": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'", + "pipeArgs": [] + }, + "properties": { + "pipeCwd": { + "type": "string", + "description": "The fully qualified path to the working directory for the pipe program.", + "default": "${workspaceFolder}" + }, + "pipeProgram": { + "type": "string", + "description": "The fully qualified pipe command to execute.", + "default": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'" + }, + "pipeArgs": { + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "items": { + "type": "string" + }, + "default": [] }, - "properties": { - "pipeCwd": { - "type": "string", - "description": "The fully qualified path to the working directory for the pipe program.", - "default": "${workspaceFolder}" - }, - "pipeProgram": { - "type": "string", - "description": "The fully qualified pipe command to execute.", - "default": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'" - }, - "pipeArgs": { - "anyOf": [ - { - "type": "array", - "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", - "items": { - "type": "string" - }, - "default": [] - }, - { - "type": "string", - "description": "Stringified version of command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", - "default": "" - } - ] - }, - "quoteArgs": { - "type": "boolean", - "description": "Should arguments that contain characters that need to be quoted (example: spaces) be quoted? Defaults to 'true'. If set to false, the debugger command will no longer be automatically quoted.", - "default": true - }, - "pipeEnv": { - "type": "object", - "additionalProperties": { - "type": "string" - }, - "description": "Environment variables passed to the pipe program.", - "default": {} - } + { + "type": "string", + "description": "Stringified version of command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "default": "" } + ] }, - "PipeTransport": { - "type": "object", - "required": ["debuggerPath"], - "description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the .NET Core debugger backend executable (vsdbg).", - "default": { - "pipeCwd": "${workspaceFolder}", - "pipeProgram": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'", - "pipeArgs": [], - "debuggerPath" : "enter the path for the debugger on the target machine, for example ~/vsdbg/vsdbg" + "quoteArgs": { + "type": "boolean", + "description": "Should arguments that contain characters that need to be quoted (example: spaces) be quoted? Defaults to 'true'. If set to false, the debugger command will no longer be automatically quoted.", + "default": true + }, + "pipeEnv": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Environment variables passed to the pipe program.", + "default": {} + } + } + }, + "PipeTransport": { + "type": "object", + "required": [ "debuggerPath" ], + "description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the .NET Core debugger backend executable (vsdbg).", + "default": { + "pipeCwd": "${workspaceFolder}", + "pipeProgram": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'", + "pipeArgs": [], + "debuggerPath": "enter the path for the debugger on the target machine, for example ~/vsdbg/vsdbg" + }, + "properties": { + "pipeCwd": { + "type": "string", + "description": "The fully qualified path to the working directory for the pipe program.", + "default": "${workspaceFolder}" + }, + "pipeProgram": { + "type": "string", + "description": "The fully qualified pipe command to execute.", + "default": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'" + }, + "pipeArgs": { + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "items": { + "type": "string" + }, + "default": [] }, - "properties": { - "pipeCwd": { - "type": "string", - "description": "The fully qualified path to the working directory for the pipe program.", - "default": "${workspaceFolder}" - }, - "pipeProgram": { - "type": "string", - "description": "The fully qualified pipe command to execute.", - "default": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'" - }, - "pipeArgs": { - "anyOf": [ - { - "type": "array", - "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", - "items": { - "type": "string" - }, - "default": [] - }, - { - "type": "string", - "description": "Stringified version of command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", - "default": "" - } - ] - }, - "debuggerPath" : { - "type" : "string", - "description" : "The full path to the debugger on the target machine.", - "default" : "~/vsdbg/vsdbg" - }, - "pipeEnv": { - "type": "object", - "additionalProperties": { - "type": "string" - }, - "description": "Environment variables passed to the pipe program.", - "default": {} - }, - "quoteArgs": { - "type": "boolean", - "description": "Should arguments that contain characters that need to be quoted (example: spaces) be quoted? Defaults to 'true'. If set to false, the debugger command will no longer be automatically quoted.", - "default": true - }, - "windows": { - "$ref": "#/definitions/PipeConfigurations", - "description": "Windows-specific pipe launch configuration options", - "default": { - "pipeCwd": "${workspaceFolder}", - "pipeProgram": "enter the fully qualified path for the pipe program name, for example 'c:\\tools\\plink.exe'", - "pipeArgs": [] - } - }, - "osx": { - "$ref": "#/definitions/PipeConfigurations", - "description": "OSX-specific pipe launch configuration options", - "default": { - "pipeCwd": "${workspaceFolder}", - "pipeProgram": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'", - "pipeArgs": [] - } - }, - "linux": { - "$ref": "#/definitions/PipeConfigurations", - "description": "Linux-specific pipe launch configuration options", - "default": { - "pipeCwd": "${workspaceFolder}", - "pipeProgram": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'", - "pipeArgs": [] - } - } + { + "type": "string", + "description": "Stringified version of command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "default": "" } + ] }, - "Logging": { - "type": "object", - "required": [], - "default": {}, - "description": "Optional flags to determine what types of messages should be logged to the output window.", - "properties": { - "exceptions": { - "type": "boolean", - "description": "Optional flag to determine whether exception messages should be logged to the output window.", - "default": true - }, - "moduleLoad": { - "type": "boolean", - "description": "Optional flag to determine whether module load events should be logged to the output window.", - "default": true - }, - "programOutput": { - "type": "boolean", - "description": "Optional flag to determine whether program output should be logged to the output window when not using an external console.", - "default": true - }, - "engineLogging": { - "type": "boolean", - "description": "Optional flag to determine whether diagnostic engine logs should be logged to the output window.", - "default": false - }, - "browserStdOut": { - "type": "boolean", - "description": "Optional flag to determine if stdout text from the launching the web browser should be logged to the output window.", - "default": true - } - } + "debuggerPath": { + "type": "string", + "description": "The full path to the debugger on the target machine.", + "default": "~/vsdbg/vsdbg" + }, + "pipeEnv": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Environment variables passed to the pipe program.", + "default": {} + }, + "quoteArgs": { + "type": "boolean", + "description": "Should arguments that contain characters that need to be quoted (example: spaces) be quoted? Defaults to 'true'. If set to false, the debugger command will no longer be automatically quoted.", + "default": true + }, + "windows": { + "$ref": "#/definitions/PipeConfigurations", + "description": "Windows-specific pipe launch configuration options", + "default": { + "pipeCwd": "${workspaceFolder}", + "pipeProgram": "enter the fully qualified path for the pipe program name, for example 'c:\\tools\\plink.exe'", + "pipeArgs": [] + } + }, + "osx": { + "$ref": "#/definitions/PipeConfigurations", + "description": "OSX-specific pipe launch configuration options", + "default": { + "pipeCwd": "${workspaceFolder}", + "pipeProgram": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'", + "pipeArgs": [] + } + }, + "linux": { + "$ref": "#/definitions/PipeConfigurations", + "description": "Linux-specific pipe launch configuration options", + "default": { + "pipeCwd": "${workspaceFolder}", + "pipeProgram": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'", + "pipeArgs": [] + } + } + } + }, + "Logging": { + "type": "object", + "required": [], + "default": {}, + "description": "Optional flags to determine what types of messages should be logged to the output window.", + "properties": { + "exceptions": { + "type": "boolean", + "description": "Optional flag to determine whether exception messages should be logged to the output window.", + "default": true + }, + "moduleLoad": { + "type": "boolean", + "description": "Optional flag to determine whether module load events should be logged to the output window.", + "default": true }, - "LaunchBrowserPlatformOptions": { - "type": "object", - "properties": { - "command": { - "type": "string", - "description": "The command to execute for launching the web browser", - "default": "open" - }, - "args": { - "type": "string", - "description": "The arguments to pass to the command to open the browser. Use ${auto-detect-url} to automatically use the address the server is listening to", - "default": "${auto-detect-url}" - } + "programOutput": { + "type": "boolean", + "description": "Optional flag to determine whether program output should be logged to the output window when not using an external console.", + "default": true + }, + "engineLogging": { + "type": "boolean", + "description": "Optional flag to determine whether diagnostic engine logs should be logged to the output window.", + "default": false + }, + "browserStdOut": { + "type": "boolean", + "description": "Optional flag to determine if stdout text from the launching the web browser should be logged to the output window.", + "default": true + } + } + }, + "LaunchBrowserPlatformOptions": { + "type": "object", + "properties": { + "command": { + "type": "string", + "description": "The command to execute for launching the web browser", + "default": "open" + }, + "args": { + "type": "string", + "description": "The arguments to pass to the command to open the browser. Use ${auto-detect-url} to automatically use the address the server is listening to", + "default": "${auto-detect-url}" + } + } + }, + "LaunchBrowser": { + "type": "object", + "description": "Describes options to launch a web browser as part of launch", + "default": { + "enabled": true, + "args": "${auto-detect-url}", + "windows": { + "command": "cmd.exe", + "args": "/C start ${auto-detect-url}" + }, + "osx": { + "command": "open" + }, + "linux": { + "command": "xdg-open" + } + }, + "properties": { + "enabled": { + "type": "boolean", + "description": "Whether web browser launch is enabled", + "default": true + }, + "args": { + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the program.", + "items": { + "type": "string" + }, + "default": [] + }, + { + "type": "string", + "description": "Stringified version of command line arguments passed to the program.", + "default": "" } + ] + }, + "osx": { + "$ref": "#/definitions/LaunchBrowserPlatformOptions", + "description": "OSX-specific web launch configuration options", + "default": { + "command": "open" + } + }, + "linux": { + "$ref": "#/definitions/LaunchBrowserPlatformOptions", + "description": "Linux-specific web launch configuration options", + "default": { + "command": "xdg-open" + } + }, + "windows": { + "$ref": "#/definitions/LaunchBrowserPlatformOptions", + "description": "Windows-specific web launch configuration options", + "default": { + "command": "cmd.exe", + "args": "/C start ${auto-detect-url}" + } + } + } + }, + "LaunchOptions": { + "type": "object", + "required": [ + "program" + ], + "properties": { + "program": { + "type": "string", + "description": "Path to the application dll or .NET Core host executable to launch.\nThis property normally takes the form: '${workspaceFolder}/bin/Debug/(target-framework)/(project-name.dll)'\nExample: '${workspaceFolder}/bin/Debug/netcoreapp1.1/MyProject.dll'\n\nWhere:\n(target-framework) is the framework that the debugged project is being built for. This is normally found in the project file as the 'TargetFramework' property.\n(project-name.dll) is the name of debugged project's build output dll. This is normally the same as the project file name but with a '.dll' extension.", + "default": "${workspaceFolder}/bin/Debug//.dll" }, - "LaunchBrowser": { - "type": "object", - "description": "Describes options to launch a web browser as part of launch", - "default": { - "enabled": true, - "args": "${auto-detect-url}", - "windows": { - "command": "cmd.exe", - "args": "/C start ${auto-detect-url}" - }, - "osx": { - "command": "open" - }, - "linux": { - "command": "xdg-open" - } + "cwd": { + "type": "string", + "description": "Path to the working directory of the program being debugged. Default is the current workspace.", + "default": "${workspaceFolder}" + }, + "args": { + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the program.", + "items": { + "type": "string" + }, + "default": [] }, - "properties": { - "enabled": { - "type": "boolean", - "description": "Whether web browser launch is enabled", - "default": true - }, - "args": { - "anyOf": [ - { - "type": "array", - "description": "Command line arguments passed to the program.", - "items": { - "type": "string" - }, - "default": [] - }, - { - "type": "string", - "description": "Stringified version of command line arguments passed to the program.", - "default": "" - } - ] - }, - "osx": { - "$ref": "#/definitions/LaunchBrowserPlatformOptions", - "description": "OSX-specific web launch configuration options", - "default": { - "command": "open" - } - }, - "linux": { - "$ref": "#/definitions/LaunchBrowserPlatformOptions", - "description": "Linux-specific web launch configuration options", - "default": { - "command": "xdg-open" - } - }, - "windows": { - "$ref": "#/definitions/LaunchBrowserPlatformOptions", - "description": "Windows-specific web launch configuration options", - "default": { - "command": "cmd.exe", - "args": "/C start ${auto-detect-url}" - } - } + { + "type": "string", + "description": "Stringified version of command line arguments passed to the program.", + "default": "" } + ] + }, + "stopAtEntry": { + "type": "boolean", + "description": "If true, the debugger should stop at the entry point of the target.", + "default": false }, - "LaunchOptions": { - "type": "object", - "required": [ - "program" - ], - "properties": { - "program": { - "type": "string", - "description": "Path to the application dll or .NET Core host executable to launch.\nThis property normally takes the form: '${workspaceFolder}/bin/Debug/(target-framework)/(project-name.dll)'\nExample: '${workspaceFolder}/bin/Debug/netcoreapp1.1/MyProject.dll'\n\nWhere:\n(target-framework) is the framework that the debugged project is being built for. This is normally found in the project file as the 'TargetFramework' property.\n(project-name.dll) is the name of debugged project's build output dll. This is normally the same as the project file name but with a '.dll' extension.", - "default": "${workspaceFolder}/bin/Debug//.dll" - }, - "cwd": { - "type": "string", - "description": "Path to the working directory of the program being debugged. Default is the current workspace.", - "default": "${workspaceFolder}" - }, - "args": { - "anyOf": [ - { - "type": "array", - "description": "Command line arguments passed to the program.", - "items": { - "type": "string" - }, - "default": [] - }, - { - "type": "string", - "description": "Stringified version of command line arguments passed to the program.", - "default": "" - } - ] - }, - "stopAtEntry": { - "type": "boolean", - "description": "If true, the debugger should stop at the entry point of the target.", - "default": false - }, - "launchBrowser": { - "$ref": "#/definitions/LaunchBrowser", - "description": "Describes options to launch a web browser as part of launch", - "default": { - "enabled": true, - "args": "${auto-detect-url}", - "windows": { - "command": "cmd.exe", - "args": "/C start ${auto-detect-url}" - }, - "osx": { - "command": "open" - }, - "linux": { - "command": "xdg-open" - } - } - }, - "env": { - "type": "object", - "additionalProperties": { - "type": "string" - }, - "description": "Environment variables passed to the program.", - "default": {} - }, - "console": { - "type": "string", - "enum": [ "internalConsole", "integratedTerminal", "externalTerminal" ], - "enumDescriptions": [ - "Output to the VS Code Debug Console. This doesn't support reading console input (ex:Console.ReadLine)", - "VS Code's integrated terminal", - "External terminal that can be configured via user settings" - ], - "description": "Where to launch the debug target.", - "default": "internalConsole" - }, - "externalConsole": { - "type": "boolean", - "description": "Attribute 'externalConsole' is deprecated, use 'console' instead.", - "default": false - }, - "sourceFileMap": { - "type": "object", - "description": "Optional source file mappings passed to the debug engine. Example: '{ \"C:\\foo\":\"/home/user/foo\" }'", - "additionalProperties": { - "type": "string" - }, - "default": { - "": "" - } - }, - "justMyCode": { - "type": "boolean", - "description": "Optional flag to only show user code.", - "default": true - }, - "symbolPath": { - "type": "array", - "description": "Array of directories to use to search for .pdb files. These directories will be searched in addition to the default locations -- next to the module and the path where the pdb was originally dropped to. Example: '[ \"/Volumes/symbols\" ]", - "items": { - "type": "string" - }, - "default": [] - }, - "requireExactSource": { - "type": "boolean", - "description": "Optional flag to require current source code to match the pdb.", - "default": true - }, - "enableStepFiltering": { - "type": "boolean", - "description": "Optional flag to enable stepping over Properties and Operators.", - "default": true - }, - "logging": { - "$ref": "#/definitions/Logging", - "description": "Optional flags to determine what types of messages should be logged to the output window." - }, - "pipeTransport": { - "$ref": "#/definitions/PipeTransport", - "description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the .NET Core debugger backend executable (vsdbg)." - } + "launchBrowser": { + "$ref": "#/definitions/LaunchBrowser", + "description": "Describes options to launch a web browser as part of launch", + "default": { + "enabled": true, + "args": "${auto-detect-url}", + "windows": { + "command": "cmd.exe", + "args": "/C start ${auto-detect-url}" + }, + "osx": { + "command": "open" + }, + "linux": { + "command": "xdg-open" } + } + }, + "env": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Environment variables passed to the program.", + "default": {} + }, + "console": { + "type": "string", + "enum": [ "internalConsole", "integratedTerminal", "externalTerminal" ], + "enumDescriptions": [ + "Output to the VS Code Debug Console. This doesn't support reading console input (ex:Console.ReadLine)", + "VS Code's integrated terminal", + "External terminal that can be configured via user settings" + ], + "description": "Where to launch the debug target.", + "default": "internalConsole" + }, + "externalConsole": { + "type": "boolean", + "description": "Attribute 'externalConsole' is deprecated, use 'console' instead.", + "default": false + }, + "sourceFileMap": { + "type": "object", + "description": "Optional source file mappings passed to the debug engine. Example: '{ \"C:\\foo\":\"/home/user/foo\" }'", + "additionalProperties": { + "type": "string" + }, + "default": { + "": "" + } + }, + "justMyCode": { + "type": "boolean", + "description": "Optional flag to only show user code.", + "default": true + }, + "requireExactSource": { + "type": "boolean", + "description": "Optional flag to require current source code to match the pdb.", + "default": true + }, + "enableStepFiltering": { + "type": "boolean", + "description": "Optional flag to enable stepping over Properties and Operators.", + "default": true + }, + "logging": { + "$ref": "#/definitions/Logging", + "description": "Optional flags to determine what types of messages should be logged to the output window." + }, + "pipeTransport": { + "$ref": "#/definitions/PipeTransport", + "description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the .NET Core debugger backend executable (vsdbg)." + }, + "suppressJITOptimizations": { + "type": "boolean", + "description": "If true, when an optimized module (.dll compiled in the Release configuration) loads in the target process, the debugger will ask the Just-In-Time compiler to generate code with optimizations disabled. For more information: https://aka.ms/VSCode-CS-LaunchJson#suppress-jit-optimizations", + "default": false }, - "AttachOptions": { - "type": "object", - "required": [], - "properties": { - "processName": { - "type": "string", - "description": "", - "default": "The process name to attach to. If this is used, 'processId' should not be used." - }, - "processId": { - "anyOf": [ - { - "type": "string", - "description": "The process id to attach to. Use \"${command:pickProcesss}\" to get a list of running processes to attach to. If 'processId' used, 'processName' should not be used.", - "default": "${command:pickProcess}" - }, - { - "type": "integer", - "description": "The process id to attach to. Use \"${command:pickProcesss}\" to get a list of running processes to attach to. If 'processId' used, 'processName' should not be used.", - "default": 0 - } - ] - }, - "sourceFileMap": { - "type": "object", - "description": "Optional source file mappings passed to the debug engine. Example: '{ \"C:\\foo\":\"/home/user/foo\" }'", - "additionalProperties": { - "type": "string" - }, - "default": { - "": "" - } - }, - "justMyCode": { - "type": "boolean", - "description": "Optional flag to only show user code.", - "default": true - }, - "symbolPath": { - "type": "array", - "description": "Array of directories to use to search for .pdb files. These directories will be searched in addition to the default locations -- next to the module and the path where the pdb was originally dropped to. Example: '[ \"/Volumes/symbols\" ]", - "items": { - "type": "string" - }, - "default": [] - }, - "requireExactSource": { - "type": "boolean", - "description": "Optional flag to require current source code to match the pdb.", - "default": true - }, - "enableStepFiltering": { - "type": "boolean", - "description": "Optional flag to enable stepping over Properties and Operators.", - "default": true - }, - "logging": { - "$ref": "#/definitions/Logging", - "description": "Optional flags to determine what types of messages should be logged to the output window." - }, - "pipeTransport": { - "$ref": "#/definitions/PipeTransport", - "description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the .NET Core debugger backend executable (vsdbg)." - } + "symbolOptions": { + "$ref": "#/definitions/VSSymbolOptions", + "description": "Options to control how symbols (.pdb files) are found and loaded.", + "default": { + "searchPaths": [], + "searchMicrosoftSymbolServer": false + } + }, + "sourceLinkOptions": { + "$ref": "#/definitions/SourceLinkOptions", + "description": "Options to control how Source Link connects to web servers. For more information: https://aka.ms/VSCode-CS-LaunchJson#source-link-options", + "default": { + "*": { "enabled": true } + } + } + } + }, + "AttachOptions": { + "type": "object", + "required": [], + "properties": { + "processName": { + "type": "string", + "description": "", + "default": "The process name to attach to. If this is used, 'processId' should not be used." + }, + "processId": { + "anyOf": [ + { + "type": "string", + "description": "The process id to attach to. Use \"${command:pickProcesss}\" to get a list of running processes to attach to. If 'processId' used, 'processName' should not be used.", + "default": "${command:pickProcess}" + }, + { + "type": "integer", + "description": "The process id to attach to. Use \"${command:pickProcesss}\" to get a list of running processes to attach to. If 'processId' used, 'processName' should not be used.", + "default": 0 } + ] + }, + "sourceFileMap": { + "type": "object", + "description": "Optional source file mappings passed to the debug engine. Example: '{ \"C:\\foo\":\"/home/user/foo\" }'", + "additionalProperties": { + "type": "string" + }, + "default": { + "": "" + } + }, + "justMyCode": { + "type": "boolean", + "description": "Optional flag to only show user code.", + "default": true + }, + "requireExactSource": { + "type": "boolean", + "description": "Optional flag to require current source code to match the pdb.", + "default": true + }, + "enableStepFiltering": { + "type": "boolean", + "description": "Optional flag to enable stepping over Properties and Operators.", + "default": true + }, + "logging": { + "$ref": "#/definitions/Logging", + "description": "Optional flags to determine what types of messages should be logged to the output window." + }, + "pipeTransport": { + "$ref": "#/definitions/PipeTransport", + "description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the .NET Core debugger backend executable (vsdbg)." + }, + "suppressJITOptimizations": { + "type": "boolean", + "description": "If true, when an optimized module (.dll compiled in the Release configuration) loads in the target process, the debugger will ask the Just-In-Time compiler to generate code with optimizations disabled. For more information: https://aka.ms/VSCode-CS-LaunchJson#suppress-jit-optimizations", + "default": false + }, + "symbolOptions": { + "$ref": "#/definitions/VSSymbolOptions", + "description": "Options to control how symbols (.pdb files) are found and loaded.", + "default": { + "searchPaths": [], + "searchMicrosoftSymbolServer": false + } + }, + "sourceLinkOptions": { + "$ref": "#/definitions/SourceLinkOptions", + "description": "Options to control how Source Link connects to web servers. For more information: https://aka.ms/VSCode-CS-LaunchJson#source-link-options", + "default": { + "*": { "enabled": true } + } + } + } + }, + "SourceLinkOptions": { + "type": "object", + "description": "Options to control how Source Link connects to web servers. For more information: https://aka.ms/VSCode-CS-LaunchJson#source-link-options", + "additionalItems": { + "type": "object", + "properties": { + "enabled": { + "title": "boolean", + "description": "Is Source Link enabled for this URL? If unspecified, this option defaults to 'true'.", + "default": "true" + } } + } } + } } diff --git a/src/tools/UpdatePackageDependencies.ts b/src/tools/UpdatePackageDependencies.ts index 105b0d391..55ea679e2 100644 --- a/src/tools/UpdatePackageDependencies.ts +++ b/src/tools/UpdatePackageDependencies.ts @@ -5,8 +5,8 @@ import * as fs from 'fs'; import * as os from 'os'; +import { Package } from '../packageManager/Package'; -import { Package } from '../packages'; interface PackageJSONFile { @@ -36,7 +36,7 @@ export function updatePackageDependencies() { let packageJSON: PackageJSONFile = JSON.parse(fs.readFileSync('package.json').toString()); // map from lowercase filename to Package - const mapFileNameToDependency = {}; + const mapFileNameToDependency: { [key: string]: Package } = {}; // First build the map packageJSON.runtimeDependencies.forEach(dependency => { @@ -77,6 +77,11 @@ export function updatePackageDependencies() { if (os.platform() === 'win32') { content = content.replace(/\n/gm, "\r\n"); } + + // We use '\u200b' (unicode zero-length space character) to break VS Code's URL detection regex for URLs that are examples. This process will + // convert that from the readable espace sequence, to just an invisible character. Convert it back to the visible espace sequence. + content = content.replace(/\u200b/gm, "\\u200b"); + fs.writeFileSync('package.json', content); } diff --git a/src/tools/VSSymbolSettings.json b/src/tools/VSSymbolSettings.json new file mode 100644 index 000000000..b78a4ba45 --- /dev/null +++ b/src/tools/VSSymbolSettings.json @@ -0,0 +1,75 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + + "definitions": { + "VSSymbolOptions": { + "type": "object", + "properties": { + "searchPaths": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Array of symbol server URLs (example: http\u200b://MyExampleSymbolServer) or directories (example: /build/symbols) to search for .pdb files. These directories will be searched in addition to the default locations -- next to the module and the path where the pdb was originally dropped to.", + "default": [] + }, + "searchMicrosoftSymbolServer": { + "type": "boolean", + "description": "If 'true' the Microsoft Symbol server (https\u200b://msdl.microsoft.com\u200b/download/symbols) is added to the symbols search path. If unspecified, this option defaults to 'false'.", + "default": false + }, + "cachePath": { + "type": "string", + "description": "Directory where symbols downloaded from symbol servers should be cached. If unspecified, on Windows the debugger will default to %TEMP%\\SymbolCache, and on Linux and macOS the debugger will default to ~/.vsdbg/SymbolCache.", + "default": "~/.vsdbg/SymbolCache" + }, + "moduleFilter": { + "$ref": "#/definitions/VSSymbolOptionsModuleFilter", + "description": "Provides options to control which modules (.dll files) the debugger will attempt to load symbols (.pdb files) for.", + "default": { + "mode": "loadAllButExcluded", + "excludedModules": [ + ] + } + } + } + }, + "VSSymbolOptionsModuleFilter": { + "type": "object", + "required": [ "mode" ], + "properties": { + "mode": { + "type": "string", + "enum": [ "loadAllButExcluded", "loadOnlyIncluded" ], + "enumDescriptions": [ + "Load symbols for all modules unless the module is in the 'excludedModules' array.", + "Do not attempt to load symbols for ANY module unless it is in the 'includedModules' array, or it is included through the 'includeSymbolsNextToModules' setting." + ], + "description": "Controls which of the two basic operating modes the module filter operates in.", + "default": "loadAllButExcluded" + }, + "excludedModules": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Array of modules that the debugger should NOT load symbols for. Wildcards (example: MyCompany.*.dll) are supported.\n\nThis property is ignored unless 'mode' is set to 'loadAllButExcluded'.", + "default": [ "MyExampleModule.dll" ] + }, + "includedModules": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Array of modules that the debugger should load symbols for. Wildcards (example: MyCompany.*.dll) are supported.\n\nThis property is ignored unless 'mode' is set to 'loadOnlyIncluded'.", + "default": [ "MyExampleModule.dll" ] + }, + "includeSymbolsNextToModules": { + "type": "boolean", + "description": "If true, for any module NOT in the 'includedModules' array, the debugger will still check next to the module itself and the launching executable, but it will not check paths on the symbol search list. This option defaults to 'true'.\n\nThis property is ignored unless 'mode' is set to 'loadOnlyIncluded'.", + "default": true + } + } + } + } +} \ No newline at end of file diff --git a/src/vscodeAdapter.ts b/src/vscodeAdapter.ts new file mode 100644 index 000000000..f368be213 --- /dev/null +++ b/src/vscodeAdapter.ts @@ -0,0 +1,909 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +export interface OutputChannel { + + /** + * The human-readable name of this output channel. + */ + readonly name: string; + + /** + * Append the given value to the channel. + * + * @param value A string, falsy values will not be printed. + */ + append(value: string): void; + + /** + * Append the given value and a line feed character + * to the channel. + * + * @param value A string, falsy values will be printed. + */ + appendLine(value: string): void; + + /** + * Removes all output from the channel. + */ + clear(): void; + + /** + * Reveal this channel in the UI. + * + * @param preserveFocus When `true` the channel will not take focus. + */ + show(preserveFocus?: boolean): void; + + /** + * Hide this channel from the UI. + */ + hide(): void; + + /** + * Dispose and free associated resources. + */ + dispose(): void; +} + +export enum ViewColumn { + /** + * A *symbolic* editor column representing the currently + * active column. This value can be used when opening editors, but the + * *resolved* [viewColumn](#TextEditor.viewColumn)-value of editors will always + * be `One`, `Two`, `Three`, or `undefined` but never `Active`. + */ + Active = -1, + /** + * The left most editor column. + */ + One = 1, + /** + * The center editor column. + */ + Two = 2, + /** + * The right most editor column. + */ + Three = 3 +} + +export interface WorkspaceConfiguration { + + /** + * Return a value from this configuration. + * + * @param section Configuration name, supports _dotted_ names. + * @return The value `section` denotes or `undefined`. + */ + get(section: string): T | undefined; + + /** + * Return a value from this configuration. + * + * @param section Configuration name, supports _dotted_ names. + * @param defaultValue A value should be returned when no value could be found, is `undefined`. + * @return The value `section` denotes or the default. + */ + get(section: string, defaultValue: T): T; + + /** + * Check if this configuration has a certain value. + * + * @param section Configuration name, supports _dotted_ names. + * @return `true` if the section doesn't resolve to `undefined`. + */ + has(section: string): boolean; + + /** + * Retrieve all information about a configuration setting. A configuration value + * often consists of a *default* value, a global or installation-wide value, + * a workspace-specific value and a folder-specific value. + * + * The *effective* value (returned by [`get`](#WorkspaceConfiguration.get)) + * is computed like this: `defaultValue` overwritten by `globalValue`, + * `globalValue` overwritten by `workspaceValue`. `workspaceValue` overwritten by `workspaceFolderValue`. + * Refer to [Settings Inheritence](https://code.visualstudio.com/docs/getstarted/settings) + * for more information. + * + * *Note:* The configuration name must denote a leaf in the configuration tree + * (`editor.fontSize` vs `editor`) otherwise no result is returned. + * + * @param section Configuration name, supports _dotted_ names. + * @return Information about a configuration setting or `undefined`. + */ + inspect(section: string): { key: string; defaultValue?: T; globalValue?: T; workspaceValue?: T, workspaceFolderValue?: T } | undefined; + + /** + * Update a configuration value. The updated configuration values are persisted. + * + * A value can be changed in + * + * - [Global configuration](#ConfigurationTarget.Global): Changes the value for all instances of the editor. + * - [Workspace configuration](#ConfigurationTarget.Workspace): Changes the value for current workspace, if available. + * - [Workspace folder configuration](#ConfigurationTarget.WorkspaceFolder): Changes the value for the + * [Workspace folder](#workspace.workspaceFolders) to which the current [configuration](#WorkspaceConfiguration) is scoped to. + * + * *Note 1:* Setting a global value in the presence of a more specific workspace value + * has no observable effect in that workspace, but in others. Setting a workspace value + * in the presence of a more specific folder value has no observable effect for the resources + * under respective [folder](#workspace.workspaceFolders), but in others. Refer to + * [Settings Inheritence](https://code.visualstudio.com/docs/getstarted/settings) for more information. + * + * *Note 2:* To remove a configuration value use `undefined`, like so: `config.update('somekey', undefined)` + * + * Will throw error when + * - Writing a configuration which is not registered. + * - Writing a configuration to workspace or folder target when no workspace is opened + * - Writing a configuration to folder target when there is no folder settings + * - Writing to folder target without passing a resource when getting the configuration (`workspace.getConfiguration(section, resource)`) + * - Writing a window configuration to folder target + * + * @param section Configuration name, supports _dotted_ names. + * @param value The new value. + * @param configurationTarget The [configuration target](#ConfigurationTarget) or a boolean value. + * - If `true` configuration target is `ConfigurationTarget.Global`. + * - If `false` configuration target is `ConfigurationTarget.Workspace`. + * - If `undefined` or `null` configuration target is + * `ConfigurationTarget.WorkspaceFolder` when configuration is resource specific + * `ConfigurationTarget.Workspace` otherwise. + */ + update(section: string, value: any, configurationTarget?: ConfigurationTarget | boolean): Thenable; + + /** + * Readable dictionary that backs this configuration. + */ + readonly [key: string]: any; +} + +/** + * The configuration target + */ +export enum ConfigurationTarget { + /** + * Global configuration + */ + Global = 1, + + /** + * Workspace configuration + */ + Workspace = 2, + + /** + * Workspace folder configuration + */ + WorkspaceFolder = 3 +} + +/** + * Represents the alignment of status bar items. + */ +export enum StatusBarAlignment { + + /** + * Aligned to the left side. + */ + Left = 1, + + /** + * Aligned to the right side. + */ + Right = 2 +} + + +export interface StatusBarItem { + + /** + * The alignment of this item. + */ + readonly alignment: StatusBarAlignment; + + /** + * The priority of this item. Higher value means the item should + * be shown more to the left. + */ + readonly priority: number; + + /** + * The text to show for the entry. You can embed icons in the text by leveraging the syntax: + * + * `My text $(icon-name) contains icons like $(icon'name) this one.` + * + * Where the icon-name is taken from the [octicon](https://octicons.github.com) icon set, e.g. + * `light-bulb`, `thumbsup`, `zap` etc. + */ + text: string; + + /** + * The tooltip text when you hover over this entry. + */ + tooltip: string | undefined; + + /** + * The foreground color for this entry. + */ + color: string | undefined; + + /** + * The identifier of a command to run on click. The command must be + * [known](#commands.getCommands). + */ + command: string | undefined; + + /** + * Shows the entry in the status bar. + */ + show(): void; + + /** + * Hide the entry in the status bar. + */ + hide(): void; + + /** + * Dispose and free associated resources. Call + * [hide](#StatusBarItem.hide). + */ + dispose(): void; +} + +export interface Event { + + /** + * A function that represents an event to which you subscribe by calling it with + * a listener function as argument. + * + * @param listener The listener function will be called when the event happens. + * @param thisArgs The `this`-argument which will be used when calling the event listener. + * @param disposables An array to which a [disposable](#Disposable) will be added. + * @return A disposable which unsubscribes the event listener. + */ + (listener: (e: T) => any, thisArgs?: any, disposables?: Disposable[]): Disposable; +} + +export interface Disposable { + /** + * Dispose this object. + */ + dispose(): any; +} + + +export interface CancellationToken { + + /** + * Is `true` when the token has been cancelled, `false` otherwise. + */ + isCancellationRequested: boolean; + + /** + * An [event](#Event) which fires upon cancellation. + */ + onCancellationRequested: Event; +} + + +export interface DocumentFilter { + + /** + * A language id, like `typescript`. + */ + language?: string; + + /** + * A Uri [scheme](#Uri.scheme), like `file` or `untitled`. + */ + scheme?: string; + + /** + * A [glob pattern](#GlobPattern) that is matched on the absolute path of the document. Use a [relative pattern](#RelativePattern) + * to filter documents to a [workspace folder](#WorkspaceFolder). + */ + pattern?: GlobPattern; +} + +export type GlobPattern = string; + +export type DocumentSelector = string | DocumentFilter | (string | DocumentFilter)[]; + +export interface MessageOptions { + + /** + * Indicates that this message should be modal. + */ + modal?: boolean; +} + +export interface TextEditor { + + /** + * The document associated with this text editor. The document will be the same for the entire lifetime of this text editor. + */ + document: TextDocument; +} + +/** + * A universal resource identifier representing either a file on disk + * or another resource, like untitled resources. + */ +export interface Uri { + + /** + * Create an URI from a file system path. The [scheme](#Uri.scheme) + * will be `file`. + * + * @param path A file system or UNC path. + * @return A new Uri instance. + */ + + /** + * Create an URI from a string. Will throw if the given value is not + * valid. + * + * @param value The string value of an Uri. + * @return A new Uri instance. + */ + /** + * Scheme is the `http` part of `http://www.msft.com/some/path?query#fragment`. + * The part before the first colon. + */ + readonly scheme: string; + + /** + * Authority is the `www.msft.com` part of `http://www.msft.com/some/path?query#fragment`. + * The part between the first double slashes and the next slash. + */ + readonly authority: string; + + /** + * Path is the `/some/path` part of `http://www.msft.com/some/path?query#fragment`. + */ + readonly path: string; + + /** + * Query is the `query` part of `http://www.msft.com/some/path?query#fragment`. + */ + readonly query: string; + + /** + * Fragment is the `fragment` part of `http://www.msft.com/some/path?query#fragment`. + */ + readonly fragment: string; + + /** + * The string representing the corresponding file system path of this Uri. + * + * Will handle UNC paths and normalize windows drive letters to lower-case. Also + * uses the platform specific path separator. Will *not* validate the path for + * invalid characters and semantics. Will *not* look at the scheme of this Uri. + */ + readonly fsPath: string; + + /** + * Derive a new Uri from this Uri. + * + * ```ts + * let file = Uri.parse('before:some/file/path'); + * let other = file.with({ scheme: 'after' }); + * assert.ok(other.toString() === 'after:some/file/path'); + * ``` + * + * @param change An object that describes a change to this Uri. To unset components use `null` or + * the empty string. + * @return A new Uri that reflects the given change. Will return `this` Uri if the change + * is not changing anything. + */ + with(change: { scheme?: string; authority?: string; path?: string; query?: string; fragment?: string }): Uri; + + /** + * Returns a string representation of this Uri. The representation and normalization + * of a URI depends on the scheme. The resulting string can be safely used with + * [Uri.parse](#Uri.parse). + * + * @param skipEncoding Do not percentage-encode the result, defaults to `false`. Note that + * the `#` and `?` characters occuring in the path will always be encoded. + * @returns A string representation of this Uri. + */ + toString(skipEncoding?: boolean): string; + + /** + * Returns a JSON representation of this Uri. + * + * @return An object. + */ + toJSON(): any; +} + +export interface MessageItem { + + /** + * A short title like 'Retry', 'Open Log' etc. + */ + title: string; + + /** + * Indicates that this item replaces the default + * 'Close' action. + */ + isCloseAffordance?: boolean; +} + +/** + * Represents a text document, such as a source file. Text documents have + * [lines](#TextLine) and knowledge about an underlying resource like a file. + */ +export interface TextDocument { + + /** + * The associated URI for this document. Most documents have the __file__-scheme, indicating that they + * represent files on disk. However, some documents may have other schemes indicating that they are not + * available on disk. + */ + readonly uri: Uri; + + /** + * The file system path of the associated resource. Shorthand + * notation for [TextDocument.uri.fsPath](#TextDocument.uri). Independent of the uri scheme. + */ + readonly fileName: string; + + /** + * Is this document representing an untitled file. + */ + readonly isUntitled: boolean; + + /** + * The identifier of the language associated with this document. + */ + readonly languageId: string; + + /** + * The version number of this document (it will strictly increase after each + * change, including undo/redo). + */ + readonly version: number; + + /** + * `true` if there are unpersisted changes. + */ + readonly isDirty: boolean; + + /** + * `true` if the document have been closed. A closed document isn't synchronized anymore + * and won't be re-used when the same resource is opened again. + */ + readonly isClosed: boolean; + + /** + * Save the underlying file. + * + * @return A promise that will resolve to true when the file + * has been saved. If the file was not dirty or the save failed, + * will return false. + */ + save(): Thenable; + + /** + * The [end of line](#EndOfLine) sequence that is predominately + * used in this document. + */ + readonly eol: EndOfLine; + + /** + * The number of lines in this document. + */ + readonly lineCount: number; + + /** + * Returns a text line denoted by the line number. Note + * that the returned object is *not* live and changes to the + * document are not reflected. + * + * @param line A line number in [0, lineCount). + * @return A [line](#TextLine). + */ + lineAt(line: number): TextLine; + + /** + * Returns a text line denoted by the position. Note + * that the returned object is *not* live and changes to the + * document are not reflected. + * + * The position will be [adjusted](#TextDocument.validatePosition). + * + * @see [TextDocument.lineAt](#TextDocument.lineAt) + * @param position A position. + * @return A [line](#TextLine). + */ + lineAt(position: Position): TextLine; + + /** + * Converts the position to a zero-based offset. + * + * The position will be [adjusted](#TextDocument.validatePosition). + * + * @param position A position. + * @return A valid zero-based offset. + */ + offsetAt(position: Position): number; + + /** + * Converts a zero-based offset to a position. + * + * @param offset A zero-based offset. + * @return A valid [position](#Position). + */ + positionAt(offset: number): Position; + + /** + * Get the text of this document. A substring can be retrieved by providing + * a range. The range will be [adjusted](#TextDocument.validateRange). + * + * @param range Include only the text included by the range. + * @return The text inside the provided range or the entire text. + */ + getText(range?: Range): string; + + /** + * Get a word-range at the given position. By default words are defined by + * common separators, like space, -, _, etc. In addition, per languge custom + * [word definitions](#LanguageConfiguration.wordPattern) can be defined. It + * is also possible to provide a custom regular expression. + * + * * *Note 1:* A custom regular expression must not match the empty string and + * if it does, it will be ignored. + * * *Note 2:* A custom regular expression will fail to match multiline strings + * and in the name of speed regular expressions should not match words with + * spaces. Use [`TextLine.text`](#TextLine.text) for more complex, non-wordy, scenarios. + * + * The position will be [adjusted](#TextDocument.validatePosition). + * + * @param position A position. + * @param regex Optional regular expression that describes what a word is. + * @return A range spanning a word, or `undefined`. + */ + getWordRangeAtPosition(position: Position, regex?: RegExp): Range | undefined; + + /** + * Ensure a range is completely contained in this document. + * + * @param range A range. + * @return The given range or a new, adjusted range. + */ + validateRange(range: Range): Range; + + /** + * Ensure a position is contained in the range of this document. + * + * @param position A position. + * @return The given position or a new, adjusted position. + */ + validatePosition(position: Position): Position; +} + +/** + * Represents an end of line character sequence in a [document](#TextDocument). + */ +export enum EndOfLine { + /** + * The line feed `\n` character. + */ + LF = 1, + /** + * The carriage return line feed `\r\n` sequence. + */ + CRLF = 2 +} + +/** + * Represents a line and character position, such as + * the position of the cursor. + * + * Position objects are __immutable__. Use the [with](#Position.with) or + * [translate](#Position.translate) methods to derive new positions + * from an existing position. + */ +export interface Position { + + /** + * The zero-based line value. + */ + readonly line: number; + + /** + * The zero-based character value. + */ + readonly character: number; + + /** + * @param line A zero-based line value. + * @param character A zero-based character value. + */ + + /** + * Check if `other` is before this position. + * + * @param other A position. + * @return `true` if position is on a smaller line + * or on the same line on a smaller character. + */ + isBefore(other: Position): boolean; + + /** + * Check if `other` is before or equal to this position. + * + * @param other A position. + * @return `true` if position is on a smaller line + * or on the same line on a smaller or equal character. + */ + isBeforeOrEqual(other: Position): boolean; + + /** + * Check if `other` is after this position. + * + * @param other A position. + * @return `true` if position is on a greater line + * or on the same line on a greater character. + */ + isAfter(other: Position): boolean; + + /** + * Check if `other` is after or equal to this position. + * + * @param other A position. + * @return `true` if position is on a greater line + * or on the same line on a greater or equal character. + */ + isAfterOrEqual(other: Position): boolean; + + /** + * Check if `other` equals this position. + * + * @param other A position. + * @return `true` if the line and character of the given position are equal to + * the line and character of this position. + */ + isEqual(other: Position): boolean; + + /** + * Compare this to `other`. + * + * @param other A position. + * @return A number smaller than zero if this position is before the given position, + * a number greater than zero if this position is after the given position, or zero when + * this and the given position are equal. + */ + compareTo(other: Position): number; + + /** + * Create a new position relative to this position. + * + * @param lineDelta Delta value for the line value, default is `0`. + * @param characterDelta Delta value for the character value, default is `0`. + * @return A position which line and character is the sum of the current line and + * character and the corresponding deltas. + */ + translate(lineDelta?: number, characterDelta?: number): Position; + + /** + * Derived a new position relative to this position. + * + * @param change An object that describes a delta to this position. + * @return A position that reflects the given delta. Will return `this` position if the change + * is not changing anything. + */ + translate(change: { lineDelta?: number; characterDelta?: number; }): Position; + + /** + * Create a new position derived from this position. + * + * @param line Value that should be used as line value, default is the [existing value](#Position.line) + * @param character Value that should be used as character value, default is the [existing value](#Position.character) + * @return A position where line and character are replaced by the given values. + */ + with(line?: number, character?: number): Position; + + /** + * Derived a new position from this position. + * + * @param change An object that describes a change to this position. + * @return A position that reflects the given change. Will return `this` position if the change + * is not changing anything. + */ + with(change: { line?: number; character?: number; }): Position; +} + +export interface Range { + + /** + * The start position. It is before or equal to [end](#Range.end). + */ + readonly start: Position; + + /** + * The end position. It is after or equal to [start](#Range.start). + */ + readonly end: Position; + + /** + * `true` if `start` and `end` are equal. + */ + isEmpty: boolean; + + /** + * `true` if `start.line` and `end.line` are equal. + */ + isSingleLine: boolean; + + /** + * Check if a position or a range is contained in this range. + * + * @param positionOrRange A position or a range. + * @return `true` if the position or range is inside or equal + * to this range. + */ + contains(positionOrRange: Position | Range): boolean; + + /** + * Check if `other` equals this range. + * + * @param other A range. + * @return `true` when start and end are [equal](#Position.isEqual) to + * start and end of this range. + */ + isEqual(other: Range): boolean; + + /** + * Intersect `range` with this range and returns a new range or `undefined` + * if the ranges have no overlap. + * + * @param range A range. + * @return A range of the greater start and smaller end positions. Will + * return undefined when there is no overlap. + */ + intersection(range: Range): Range | undefined; + + /** + * Compute the union of `other` with this range. + * + * @param other A range. + * @return A range of smaller start position and the greater end position. + */ + union(other: Range): Range; + + /** + * Derived a new range from this range. + * + * @param start A position that should be used as start. The default value is the [current start](#Range.start). + * @param end A position that should be used as end. The default value is the [current end](#Range.end). + * @return A range derived from this range with the given start and end position. + * If start and end are not different `this` range will be returned. + */ + with(start?: Position, end?: Position): Range; + + /** + * Derived a new range from this range. + * + * @param change An object that describes a change to this range. + * @return A range that reflects the given change. Will return `this` range if the change + * is not changing anything. + */ + with(change: { start?: Position, end?: Position }): Range; +} + +/** + * Represents a line of text, such as a line of source code. + * + * TextLine objects are __immutable__. When a [document](#TextDocument) changes, + * previously retrieved lines will not represent the latest state. + */ +export interface TextLine { + + /** + * The zero-based line number. + */ + readonly lineNumber: number; + + /** + * The text of this line without the line separator characters. + */ + readonly text: string; + + /** + * The range this line covers without the line separator characters. + */ + readonly range: Range; + + /** + * The range this line covers with the line separator characters. + */ + readonly rangeIncludingLineBreak: Range; + + /** + * The offset of the first character which is not a whitespace character as defined + * by `/\s/`. **Note** that if a line is all whitespaces the length of the line is returned. + */ + readonly firstNonWhitespaceCharacterIndex: number; + + /** + * Whether this line is whitespace only, shorthand + * for [TextLine.firstNonWhitespaceCharacterIndex](#TextLine.firstNonWhitespaceCharacterIndex) === [TextLine.text.length](#TextLine.text). + */ + readonly isEmptyOrWhitespace: boolean; +} + +export interface FileSystemWatcher extends Disposable { + + /** + * true if this file system watcher has been created such that + * it ignores creation file system events. + */ + ignoreCreateEvents: boolean; + + /** + * true if this file system watcher has been created such that + * it ignores change file system events. + */ + ignoreChangeEvents: boolean; + + /** + * true if this file system watcher has been created such that + * it ignores delete file system events. + */ + ignoreDeleteEvents: boolean; + + /** + * An event which fires on file/folder creation. + */ + onDidCreate: Event; + + /** + * An event which fires on file/folder change. + */ + onDidChange: Event; + + /** + * An event which fires on file/folder deletion. + */ + onDidDelete: Event; +} + +/** + * 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 recommend the use of native promises which are available in this editor. + */ +interface Thenable { + /** + * 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(onfulfilled?: (value: T) => TResult | Thenable, onrejected?: (reason: any) => TResult | Thenable): Thenable; + then(onfulfilled?: (value: T) => TResult | Thenable, onrejected?: (reason: any) => void): Thenable; +} + +export interface vscode { + commands: { + executeCommand: (command: string, ...rest: any[]) => Thenable; + }; + languages: { + match: (selector: DocumentSelector, document: TextDocument) => number; + }; + window: { + activeTextEditor: TextEditor | undefined; + showInformationMessage: (message: string, ...items: string[]) => Thenable; + showWarningMessage: (message: string, ...items: T[]) => Thenable; + }; + workspace: { + getConfiguration: (section?: string, resource?: Uri) => WorkspaceConfiguration; + asRelativePath: (pathOrUri: string | Uri, includeWorkspaceFolder?: boolean) => string; + createFileSystemWatcher(globPattern: GlobPattern, ignoreCreateEvents?: boolean, ignoreChangeEvents?: boolean, ignoreDeleteEvents?: boolean): FileSystemWatcher; + }; +} \ No newline at end of file diff --git a/tasks/backcompatTasks.ts b/tasks/backcompatTasks.ts new file mode 100644 index 000000000..fc1bc22c4 --- /dev/null +++ b/tasks/backcompatTasks.ts @@ -0,0 +1,10 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import * as gulp from 'gulp'; + +gulp.task('package:offline', ['vsix:offline:package']); diff --git a/tasks/commandLineArguments.ts b/tasks/commandLineArguments.ts new file mode 100644 index 000000000..deca32e59 --- /dev/null +++ b/tasks/commandLineArguments.ts @@ -0,0 +1,31 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import * as minimist from 'minimist'; +import * as path from 'path'; + +let argv = minimist(process.argv.slice(2), { + boolean: ['retainVsix'] +}); + +export const commandLineOptions ={ + retainVsix: !!argv['retainVsix'], + outputFolder: makePathAbsolute(argv['o']), + codeExtensionPath: makePathAbsolute(argv['codeExtensionPath']) +}; + +function makePathAbsolute(originalPath: string) { + if (!originalPath || originalPath == '') { + return undefined; + } + + if (path.isAbsolute(originalPath)) { + return originalPath; + } + + return path.resolve(originalPath); +} diff --git a/tasks/coverageTasks.ts b/tasks/coverageTasks.ts new file mode 100644 index 000000000..22f485586 --- /dev/null +++ b/tasks/coverageTasks.ts @@ -0,0 +1,80 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import * as gulp from 'gulp'; +import * as path from 'path'; +import * as del from 'del'; +import spawnNode from './spawnNode'; +import { coverageRootPath, nycOutputPath, nycPath, codeExtensionSourcesPath, integrationTestCoverageRootPath, integrationTestNycOutputPath, istanbulCombinePath, codecovPath, unitTestCoverageRootPath } from './projectPaths'; + +gulp.task("cov:instrument", async () => { + del(coverageRootPath); + del(nycOutputPath); + + return spawnNode([ + nycPath, + 'instrument', + '--require', + 'source-map-support/register', + '.', + '.' + ], { + cwd: codeExtensionSourcesPath + }); +}); + +gulp.task("cov:merge", async () => { + return spawnNode([ + istanbulCombinePath, + '-d', + integrationTestCoverageRootPath, + '-r', + 'lcovonly', + `${integrationTestNycOutputPath}/*.json` + ], { + cwd: codeExtensionSourcesPath + }); +}); + +gulp.task("cov:merge-html", async () => { + return spawnNode([ + istanbulCombinePath, + '-d', + integrationTestCoverageRootPath, + '-r', + 'html', + `${integrationTestNycOutputPath}/*.json` + ], { + cwd: codeExtensionSourcesPath + }); +}); + +gulp.task("cov:report", ["cov:report:integration", "cov:report:unit"]); + +gulp.task("cov:report:integration", ["cov:merge"], async () => { + return spawnNode([ + codecovPath, + '-f', + path.join(integrationTestCoverageRootPath, 'lcov.info'), + '-F', + 'integration' + ], { + cwd: codeExtensionSourcesPath + }); +}); + +gulp.task("cov:report:unit", async () => { + return spawnNode([ + codecovPath, + '-f', + path.join(unitTestCoverageRootPath, 'lcov.info'), + '-F', + 'unit' + ], { + cwd: codeExtensionSourcesPath + }); +}); diff --git a/tasks/offlinePackagingTasks.ts b/tasks/offlinePackagingTasks.ts new file mode 100644 index 000000000..e05ffeaf4 --- /dev/null +++ b/tasks/offlinePackagingTasks.ts @@ -0,0 +1,122 @@ + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import * as debugUtil from '../src/coreclr-debug/util'; +import * as del from 'del'; +import * as fs from 'fs'; +import * as gulp from 'gulp'; +import * as path from 'path'; +import * as util from '../src/common'; +import spawnNode from '../tasks/spawnNode'; +import { codeExtensionPath, offlineVscodeignorePath, vscodeignorePath, vscePath, packedVsixOutputRoot } from '../tasks/projectPaths'; +import { commandLineOptions } from '../tasks/commandLineArguments'; +import { CsharpLoggerObserver } from '../src/observers/CsharpLoggerObserver'; +import { EventStream } from '../src/EventStream'; +import { getPackageJSON } from '../tasks/packageJson'; +import { Logger } from '../src/logger'; +import { PlatformInformation } from '../src/platform'; +import { DownloadAndInstallPackages } from '../src/packageManager/PackageManager'; +import NetworkSettings from '../src/NetworkSettings'; +import { GetRunTimeDependenciesPackages } from '../src/CSharpExtDownloader'; + +gulp.task('vsix:offline:package', async () => { + del.sync(vscodeignorePath); + + fs.copyFileSync(offlineVscodeignorePath, vscodeignorePath); + + try { + await doPackageOffline(); + } + finally { + del(vscodeignorePath); + } +}); + +async function doPackageOffline() { + util.setExtensionPath(codeExtensionPath); + + if (commandLineOptions.retainVsix) { + //if user doesnot want to clean up the existing vsix packages + cleanSync(false); + } + else { + cleanSync(true); + } + + const packageJSON = getPackageJSON(); + const name = packageJSON.name; + const version = packageJSON.version; + const packageName = name + '.' + version; + + const packages = [ + new PlatformInformation('win32', 'x86_64'), + new PlatformInformation('darwin', 'x86_64'), + new PlatformInformation('linux', 'x86_64') + ]; + + for (let platformInfo of packages) { + await doOfflinePackage(platformInfo, packageName, packageJSON, packedVsixOutputRoot); + } +} + +function cleanSync(deleteVsix: boolean) { + del.sync('install.*'); + del.sync('.omnisharp*'); + del.sync('.debugger'); + + if (deleteVsix) { + del.sync('*.vsix'); + } +} + +async function doOfflinePackage(platformInfo: PlatformInformation, packageName: string, packageJSON: any, outputFolder: string) { + if (process.platform === 'win32') { + throw new Error('Do not build offline packages on windows. Runtime executables will not be marked executable in *nix packages.'); + } + + cleanSync(false); + + const packageFileName = `${packageName}-${platformInfo.platform}-${platformInfo.architecture}.vsix`; + + await install(platformInfo, packageJSON); + await doPackageSync(packageFileName, outputFolder); +} + +// Install Tasks +async function install(platformInfo: PlatformInformation, packageJSON: any) { + let eventStream = new EventStream(); + const logger = new Logger(message => process.stdout.write(message)); + let stdoutObserver = new CsharpLoggerObserver(logger); + eventStream.subscribe(stdoutObserver.post); + const debuggerUtil = new debugUtil.CoreClrDebugUtil(path.resolve('.')); + let runTimeDependencies = GetRunTimeDependenciesPackages(packageJSON); + let provider = () => new NetworkSettings(undefined, undefined); + await DownloadAndInstallPackages(runTimeDependencies, provider, platformInfo, eventStream); + await debugUtil.CoreClrDebugUtil.writeEmptyFile(debuggerUtil.installCompleteFilePath()); +} + +/// Packaging (VSIX) Tasks +async function doPackageSync(packageName: string, outputFolder: string) { + + let vsceArgs = []; + vsceArgs.push(vscePath); + vsceArgs.push('package'); // package command + + if (packageName !== undefined) { + vsceArgs.push('-o'); + if (outputFolder) { + //if we have specified an output folder then put the files in that output folder + vsceArgs.push(path.join(outputFolder, packageName)); + } + else { + vsceArgs.push(packageName); + } + } + + return spawnNode(vsceArgs); +} \ No newline at end of file diff --git a/tasks/onlinePackagingTasks.ts b/tasks/onlinePackagingTasks.ts new file mode 100644 index 000000000..ee8fe6794 --- /dev/null +++ b/tasks/onlinePackagingTasks.ts @@ -0,0 +1,37 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import * as del from 'del'; +import * as fs from 'fs'; +import * as gulp from 'gulp'; +import * as unzip from 'unzip2'; +import { onlineVscodeignorePath, unpackedVsixPath, vscePath, vscodeignorePath } from './projectPaths'; +import { getPackageJSON } from './packageJson'; +import spawnNode from './spawnNode'; + +gulp.task('vsix:release:unpackage', () => { + const packageJSON = getPackageJSON(); + const name = packageJSON.name; + const version = packageJSON.version; + const packageName = `${name}-${version}.vsix`; + + del.sync(unpackedVsixPath); + fs.createReadStream(packageName).pipe(unzip.Extract({ path: unpackedVsixPath })); +}); + +gulp.task('vsix:release:package', async (onError) => { + del.sync(vscodeignorePath); + + fs.copyFileSync(onlineVscodeignorePath, vscodeignorePath); + + try { + await spawnNode([vscePath, 'package']); + } + finally { + await del(vscodeignorePath); + } +}); \ No newline at end of file diff --git a/tasks/packageJson.ts b/tasks/packageJson.ts new file mode 100644 index 000000000..dc46968cd --- /dev/null +++ b/tasks/packageJson.ts @@ -0,0 +1,12 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import * as fs from 'fs'; + +export function getPackageJSON() { + return JSON.parse(fs.readFileSync('package.json').toString()); +} diff --git a/tasks/projectPaths.ts b/tasks/projectPaths.ts new file mode 100644 index 000000000..16c16891a --- /dev/null +++ b/tasks/projectPaths.ts @@ -0,0 +1,47 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import * as path from 'path'; +import { commandLineOptions } from './commandLineArguments'; + +export const rootPath = path.resolve(__dirname, '..'); + +export const vscodeignorePath = path.join(rootPath, '.vscodeignore'); +export const offlineVscodeignorePath = path.join(rootPath, 'offline.vscodeignore'); +export const onlineVscodeignorePath = path.join(rootPath, 'release.vscodeignore'); + +export const nodeModulesPath = path.join(rootPath, 'node_modules'); +export const vscePath = path.join(nodeModulesPath, 'vsce', 'out', 'vsce'); +export const nycPath = path.join(nodeModulesPath, 'nyc', 'bin', 'nyc.js'); +export const mochaPath = path.join(nodeModulesPath, 'mocha', 'bin', 'mocha'); +export const istanbulCombinePath = path.join(nodeModulesPath, 'istanbul-combine', 'cli.js'); +export const codecovPath = path.join(nodeModulesPath, 'codecov', 'bin', 'codecov'); +export const vscodeTestHostPath = path.join(nodeModulesPath, 'vscode', 'bin', 'test'); + +export const packageJsonPath = path.join(rootPath, "package.json"); + +export const packedVsixOutputRoot = commandLineOptions.outputFolder || rootPath; +export const unpackedVsixPath = path.join(rootPath, "vsix"); +export const unpackedExtensionPath = path.join(unpackedVsixPath, "extension"); + +export const codeExtensionPath = commandLineOptions.codeExtensionPath || rootPath; +export const codeExtensionSourcesPath = path.join(codeExtensionPath, "out"); + +export const testRootPath = path.join(rootPath, "out", "test"); +export const testAssetsRootPath = path.join(rootPath, "test", "integrationTests", "testAssets"); + +export const coverageRootPath = path.join(rootPath, 'coverage'); +export const unitTestCoverageRootPath = path.join(coverageRootPath, 'unit'); +export const integrationTestCoverageRootPath = path.join(coverageRootPath, 'integration'); + +export const nycOutputPath = path.join(rootPath, '.nyc_output'); +export const integrationTestNycOutputPath = path.join(nycOutputPath, 'integration'); + +export const nodePath = path.join(process.env.NVM_BIN + ? `${process.env.NVM_BIN}${path.sep}` + : '', 'node'); + diff --git a/tasks/spawnNode.ts b/tasks/spawnNode.ts new file mode 100644 index 000000000..7df6a2d50 --- /dev/null +++ b/tasks/spawnNode.ts @@ -0,0 +1,37 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import { SpawnOptions, spawn } from "child_process"; +import { join, Result } from "async-child-process"; +import { nodePath, rootPath } from "./projectPaths"; + +export default async function spawnNode(args?: string[], options?: SpawnOptions): Promise { + if (!options) { + options = { + env: {} + }; + } + + let optionsWithFullEnvironment = { + cwd: rootPath, + stdio: 'inherit', + ...options, + env: { + ...process.env, + ...options.env + } + }; + + console.log(`starting ${nodePath} ${args.join(' ')}`); + + let spawned = spawn(nodePath, args, optionsWithFullEnvironment); + + // spawned.stderr.pipe(process.stdout); + // spawned.stdout.pipe(process.stdout); + + return join(spawned); +} \ No newline at end of file diff --git a/tasks/testTasks.ts b/tasks/testTasks.ts new file mode 100644 index 000000000..d9d9d9977 --- /dev/null +++ b/tasks/testTasks.ts @@ -0,0 +1,71 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import * as gulp from 'gulp'; +import * as path from 'path'; +import { codeExtensionPath, nycPath, rootPath, testAssetsRootPath, testRootPath, unitTestCoverageRootPath, mochaPath, vscodeTestHostPath } from './projectPaths'; +import spawnNode from './spawnNode'; + +const gulpSequence = require('gulp-sequence'); + +gulp.task("test", gulpSequence( + "test:feature", + "test:unit", + "test:integration")); + +gulp.task("test:feature", async () => { + let env = { + ...process.env, + OSVC_SUITE: "featureTests", + CODE_TESTS_PATH: path.join(testRootPath, "featureTests") + }; + + return spawnNode([vscodeTestHostPath], { + env + }); +}); + +gulp.task("test:unit", async () => { + return spawnNode([ + nycPath, + '-r', + 'lcovonly', + '--report-dir', + unitTestCoverageRootPath, + mochaPath, + '--ui', + 'tdd', + '--', + 'test/unitTests/**/*.test.ts' + ]); +}); + +gulp.task( + "test:integration", gulpSequence( + "test:integration:singleCsproj", + "test:integration:slnWithCsproj" + )); + +gulp.task("test:integration:singleCsproj", async () => { + return runIntegrationTest("singleCsproj"); +}); + +gulp.task("test:integration:slnWithCsproj", async () => { + return runIntegrationTest("slnWithCsproj"); +}); + +async function runIntegrationTest(testAssetName: string) { + let env = { + OSVC_SUITE: testAssetName, + CODE_TESTS_PATH: path.join(testRootPath, "integrationTests"), + CODE_EXTENSIONS_PATH: codeExtensionPath, + CODE_TESTS_WORKSPACE: path.join(testAssetsRootPath, testAssetName), + CODE_WORKSPACE_ROOT: rootPath, + }; + + return spawnNode([vscodeTestHostPath], { env, cwd: rootPath }); +} \ No newline at end of file diff --git a/test-plan.md b/test-plan.md new file mode 100644 index 000000000..1831055b4 --- /dev/null +++ b/test-plan.md @@ -0,0 +1,120 @@ +# Validating C# Extension for VS Code + +#### Opening projects +When you open a directory in VS Code, the C# extension should look for a .csproj or .sln file in that directory and use "OmniSharp" to load it. +If you look in "Output > Omnisharp Log" a bunch of information should be printed about what copy of MSBuild was used and what projects were load + +Project types to test: +* Standalone csproj +* Directory containing .sln file that references csprojs--projects should be loaded +* .NET Core/.NET Standard csproj +* (Windows) Desktop .NET projects +* Unity projects + +The easist way to verify that a project was successfully loaded is to open a .cs file within it and verify that the references codelens indicator appears. + +#### Specific projects to test opening (on all OSes): +* `dotnet new console` in a directory +* A more complex dotnet solution, eg. [1] +* A console app solution created in Visual Studio + +#### Unity +* Follow the directions at https://code.visualstudio.com/docs/other/unity to configure VS Code with unity +* Try editing a project like https://github.com/staceyhaffner/SuperSpaceShooter + +#### Intellisense +* The completion list in a file contains symbols defined in references and in the file +* If you write a documentation comment on a symbol, the completion list displays it + +#### Signature Help +* Signature Help shows up in a method call after typing `(` +* Signature help shows documentation for methods and for parameters +* Parameter documentation is only shown for the currently active parameter + +#### Quick Info +* Hovering over an identifier shows info and documentation + +#### Formatting +* The "Format Document" command works +* Pressing enter inside a method body automatically indents the new line + +#### Go To Definition +* F12 from callsites to definition +* Ctrl-Click +* Can go to metadata for symbols defined in metadata + +#### Go To Implementation +* Ctrl-F12 on virtual member shows implementations + +#### Find All References +* Shift-F12 on a symbol shows a reference list + +### Reference highlighting +* Clicking on a symbol name should highlight other references to it in the same file + +#### Colorization +* Appropriate colorization of keywords, literals, identifiers + +#### Error squiggles +* Introducing an error should show a squiggle in the editor and an error message in the "problems" window +* Messages in the "problems" window should appear only once per unique error (see https://github.com/OmniSharp/omnisharp-vscode/issues/1830) + +#### Quick Fixes +* Add using should be availble (does not currently suppport adding references) +* Generate variable/generate method should show up for missing members +* Remove unncessary usings should show up +* (this is not an exhaustive list) + +#### Refactorings +* `Use expression body for methods` should be available +* `Rename file to match type` should correctly rename the file. The renamed file should be open after the refactoring +* (this is not an exhaustive list) + +#### Code Lens - References +* References codelens appears on symbols and shows correct Find All References results + +#### Code Lens - Unit Tests +* In unit tests projects, the "run test" and "debug test" codelens appears on test methods + * Clicking runs or debugs the test and prints results to the console + * Breakpoints in a unit test are hit if you "debug test" +* "Run All Tests" and "Debug All Tests" code lens buttons will appear on test classes + * Click Run All or Debug All should run/debug all the tests in the class and print a summary + * If you set breakpoints within multiple tests, you should hit each breakpoint as the tests are run + +#### Symbol Finder +* Ctrl-T can find symbols by name when you type them + * Symbols have appropriate glyphs + +#### Rename +* Rename can rename symbols + +#### File Watching +* In a project that uses globbing (.NET Core), use the VS Code file explorer to add a new file next to the csproj. Intellisense/sighelp/etc should be available in the new file +* Add a new file and reference a type in it from a different file. Deleting from disk the file containing the referenced type should produce error messages + +#### Omnisharp Options + + #### omnisharp.useMono (for Linux) + For using this option, mono version greater than or equal to 5.2.0 must be installed. If that is not so, setting this option to true, should give an error. + * If the option is not set, the OmniSharp path displayed in the "OmniSharp Log" should end with "run" + * If the option is set, the OmniSharp path as mentioned above should end with "OmniSharp.exe" + + #### omnisharp.path + Setting this path to any of the values as listed below, should start the OmniSharp server and display the correct OmniSharp path in the `OmniSharp Log`(View --> Output--> OmniSharp Log). + * undefined - OmniSharp server must start using the copy of omnisharp shipped with the extension, that is, the OmniSharp path must be the extension path, followed by .omnisharp followed by the platform-specific executable. + * Some absolute path - OmniSharp server must start using the local copy of OmniSharp pointed to by the path and the same must be displayed as the Omnisharp path. Example:C:\omnisharp-roslyn\artifacts\publish\OmniSharp.Stdio\win7-x64\OmniSharp.exe. + * "" - The specified version must be downloaded and installed (The status of download/install can be seen in the `C#` log). If the installation is successful, the server must start and the OmniSharp path must include the .omnisharp/experimental folder followed by the version name and the executable. Eg: If the version is `1.29.2-beta.60`, the path displayed on Windows should be `.omnisharp/experimental/1.29.2-beta.60/OmniSharp.exe`. + * "latest" - The file containing the information about the latest CI build (https://roslynomnisharp.blob.core.windows.net/releases/versioninfo.txt), must be downloaded and accordingly the latest CI build from the "master" branch of omnisharp-roslyn should be downloaded and installed. If the installation is successful, the server must start and the OmniSharp path must include the .omnisharp/experimental folder followed by the version name and the executable. Eg: If the latest version is `1.29.2-beta.62`, the path displayed on Windows should be `.omnisharp/experimental/1.29.2-beta.62/OmniSharp.exe`. + * All the above configurations should work, with and without setting the useMono option on Linux + * The above behavior should be exhibited when a new vscode window is opened, as well as if the setting is modified and a "Restart OmniSharp"(Ctrl+Shift+P --> OmniSharp: Restart OmniSharp) is performed. + +[1] For example, +``` +mkdir project +mkdir test +dotnet new console -o project +dotnet new xunit -o test +dotnet add test\test.csproj reference project\project.csproj +dotnet new solution -n solution +dotnet sln solution.sln add test\test.csproj project\project.csproj +``` diff --git a/test/artifactTests/vsix.test.ts b/test/artifactTests/vsix.test.ts new file mode 100644 index 000000000..506af2e2e --- /dev/null +++ b/test/artifactTests/vsix.test.ts @@ -0,0 +1,39 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as chai from 'chai'; +import * as fs from 'async-file'; +import * as glob from 'glob-promise'; +import * as path from 'path'; + +let vsixFiles = glob.sync(path.join(process.cwd(), '**', '*.vsix')); + +suite("Omnisharp-Vscode VSIX", async () => { + suiteSetup(async () => { + chai.should(); + + }); + + test("At least one vsix file should be produced", () => { + vsixFiles.length.should.be.greaterThan(0, "the build should produce at least one vsix file"); + }); + + vsixFiles.forEach(element => { + const sizeInMB = 5; + const maximumVsixSizeInBytes = sizeInMB * 1024 * 1024; + + suite(`Given ${element}`, () => { + test(`Then its size is less than ${sizeInMB}MB`, async () => { + const stats = await fs.stat(element); + stats.size.should.be.lessThan(maximumVsixSizeInBytes); + }); + + test(`Then it should not be empty`, async () => { + const stats = await fs.stat(element); + stats.size.should.be.greaterThan(0); + }); + }); + }); +}); diff --git a/test/coverageWritingTestRunner.ts b/test/coverageWritingTestRunner.ts new file mode 100644 index 000000000..0b7bf65b2 --- /dev/null +++ b/test/coverageWritingTestRunner.ts @@ -0,0 +1,97 @@ +/*--------------------------------------------------------- + * Copyright (C) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------*/ + + import shelljs = require("async-shelljs"); +import path = require('path'); +const fs = require('async-file'); + +declare var __coverage__: any; + +export default class CoverageWritingTestRunner { + constructor(private baseRunner: any) { + } + + public configure(mochaOpts: any) { + this.baseRunner.configure(mochaOpts); + } + + public run(testRoot: string, clb: any) { + let promiseResolve: any; + let clbArgsLocal: { error: any, failures?: number }; + + new Promise<{ error: any, failures?: number }>(function (resolve, reject) { + promiseResolve = (error: any, failures?: number) => resolve({ error, failures }); + }) + .then(async clbArgs => { + clbArgsLocal = clbArgs; + return this.writeCoverage(); + }) + .then(() => clb(clbArgsLocal.error, clbArgsLocal.failures), + () => clb(clbArgsLocal.error, clbArgsLocal.failures)); + + this.baseRunner.run(testRoot, promiseResolve); + } + + private async writeCoverage(): Promise { + if (typeof __coverage__ !== 'undefined') { + let nycFolderPath = path.join(process.env.CODE_WORKSPACE_ROOT, ".nyc_output", "integration"); + + let rawCoverageJsonPath: string; + let remappedCoverageJsonPath: string; + let outFolderPath: string; + let remapIstanbulPath: string; + let nodePath: string; + + try { + if (!(await fs.exists(nycFolderPath))) { + await fs.mkdirp(nycFolderPath); + + rawCoverageJsonPath = path.join(nycFolderPath, `${process.env.OSVC_SUITE}.json.raw`); + remappedCoverageJsonPath = path.join(nycFolderPath, `${process.env.OSVC_SUITE}.json`); + outFolderPath = path.join(process.env.CODE_WORKSPACE_ROOT, "out"); + remapIstanbulPath = path.join(process.env.CODE_WORKSPACE_ROOT, "node_modules", "remap-istanbul", "bin", "remap-istanbul.js"); + nodePath = ""; + if (process.env.NVM_BIN) { + nodePath = `${process.env.NVM_BIN}${path.sep}`; + } + + await fs.writeTextFile(rawCoverageJsonPath, JSON.stringify(__coverage__)); + + await shelljs.asyncExec(`${nodePath}node ${remapIstanbulPath} -i ${rawCoverageJsonPath} -o ${remappedCoverageJsonPath}`, { + cwd: outFolderPath + }); + + let remappedResult = JSON.parse(await fs.readTextFile(remappedCoverageJsonPath)); + + let finalResult = <{[details: string] : { path: string }}>{}; + + for (let key in remappedResult) { + if (remappedResult[key].path) { + let realPath = key.replace("../", "./"); + + finalResult[realPath] = remappedResult[key]; + finalResult[realPath].path = realPath; + } + else { + finalResult[key] = remappedResult[key]; + } + } + + await fs.writeTextFile(remappedCoverageJsonPath, JSON.stringify(finalResult)); + + console.log(`done remapping ${finalResult}`); + } + } + catch (e) { + console.log(`Coverage remapping failure: ${JSON.stringify(e)}`); + console.log(`* rawCoverageJsonPath: ${rawCoverageJsonPath}`); + console.log(`* remappedCoverageJsonPath: ${remappedCoverageJsonPath}`); + console.log(`* outFolderPath: ${outFolderPath}`); + console.log(`* remapIstanbulPath: ${remapIstanbulPath}`); + console.log(`* nodePath: ${nodePath}`); + console.log(e); + } + } + } + } diff --git a/test/featureTests/OmnisharpDownloader.test.ts b/test/featureTests/OmnisharpDownloader.test.ts new file mode 100644 index 000000000..0441d26c9 --- /dev/null +++ b/test/featureTests/OmnisharpDownloader.test.ts @@ -0,0 +1,51 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as path from 'path'; +import * as tmp from 'tmp'; +import * as util from '../../src/common'; +import { rimraf } from 'async-file'; +import { PlatformInformation } from '../../src/platform'; +import { EventStream } from '../../src/EventStream'; +import { GetTestOmnisharpDownloader } from './testAssets/testAssets'; + +const chai = require("chai"); +chai.use(require("chai-as-promised")); +let expect = chai.expect; + +suite("DownloadAndInstallExperimentalVersion : Gets the version packages, downloads and installs them", () => { + let tmpDir: tmp.SynchrounousResult = null; + const version = "1.2.3"; + const platformInfo = new PlatformInformation("win32", "x86"); + const eventStream = new EventStream(); + const downloader = GetTestOmnisharpDownloader(eventStream, platformInfo); + const serverUrl = "https://roslynomnisharp.blob.core.windows.net"; + const installPath = ".omnisharp/experimental/"; + + setup(() => { + tmpDir = tmp.dirSync(); + util.setExtensionPath(tmpDir.name); + }); + + test('Throws error if request is made for a version that doesnot exist on the server', () => { + expect(downloader.DownloadAndInstallOmnisharp("1.00000001.0000", serverUrl, installPath)).to.be.rejectedWith(Error); + }); + + test('Packages are downloaded from the specified server url and installed at the specified path', async () => { + /* Download a test package that conatins a install_check_1.2.3.txt file and check whether the + file appears at the expected path */ + await downloader.DownloadAndInstallOmnisharp(version, serverUrl, installPath); + let exists = await util.fileExists(path.resolve(tmpDir.name, installPath, version, `install_check_1.2.3.txt`)); + exists.should.equal(true); + }); + + teardown(async () => { + if (tmpDir) { + await rimraf(tmpDir.name); + } + + tmpDir = null; + }); +}); diff --git a/test/featureTests/OmnisharpManager.test.ts b/test/featureTests/OmnisharpManager.test.ts new file mode 100644 index 000000000..edbe7ae75 --- /dev/null +++ b/test/featureTests/OmnisharpManager.test.ts @@ -0,0 +1,123 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as path from 'path'; +import * as util from '../../src/common'; +import { expect, should } from "chai"; +import { PlatformInformation } from "../../src/platform"; +import { rimraf } from 'async-file'; +import { OmnisharpManager } from '../../src/omnisharp/OmnisharpManager'; +import { EventStream } from '../../src/EventStream'; +import { GetTestOmnisharpDownloader } from './testAssets/testAssets'; + +const chai = require("chai"); +chai.use(require("chai-as-promised")); + +const tmp = require('tmp'); + +suite('GetExperimentalOmnisharpPath : Returns Omnisharp experiment path depending on the path and useMono option', () => { + const platformInfo = new PlatformInformation("win32", "x86"); + const serverUrl = "https://roslynomnisharp.blob.core.windows.net"; + const installPath = ".omnisharp/experimental"; + const versionFilepathInServer = "releases/testVersionInfo.txt"; + const eventStream = new EventStream(); + const manager = GetTestOmnisharpManager(eventStream, platformInfo); + let extensionPath: string; + let tmpDir: any; + let tmpFile: any; + + suiteSetup(() => should()); + + setup(() => { + tmpDir = tmp.dirSync(); + extensionPath = tmpDir.name; + util.setExtensionPath(tmpDir.name); + }); + + test('Throws error if the path is neither an absolute path nor a valid semver, nor the string "latest"', async () => { + expect(manager.GetOmniSharpLaunchInfo("Some incorrect path", serverUrl, versionFilepathInServer, installPath, extensionPath)).to.be.rejectedWith(Error); + }); + + test('Throws error when the specified path is null', async () => { + expect(manager.GetOmniSharpLaunchInfo(null, serverUrl, versionFilepathInServer, installPath, extensionPath)).to.be.rejectedWith(Error); + }); + + test('Throws error when the specified path is empty', async () => { + expect(manager.GetOmniSharpLaunchInfo("", serverUrl, versionFilepathInServer, installPath, extensionPath)).to.be.rejectedWith(Error); + }); + + test('Throws error when the specified path is an invalid semver', async () => { + expect(manager.GetOmniSharpLaunchInfo("a.b.c", serverUrl, versionFilepathInServer, installPath, extensionPath)).to.be.rejectedWith(Error); + }); + + test('Returns default paths if no path is specified', async () => { + let launchInfo = await manager.GetOmniSharpLaunchInfo(undefined, serverUrl, versionFilepathInServer, installPath, extensionPath); + launchInfo.LaunchPath.should.equal(path.resolve(extensionPath, '.omnisharp/OmniSharp.exe')); + expect(launchInfo.MonoLaunchPath).to.be.undefined; + }); + + test('Returns default paths if no path is specified - Linux ', async () => { + let manager = GetTestOmnisharpManager(eventStream, new PlatformInformation("linux", "x64")); + let launchInfo = await manager.GetOmniSharpLaunchInfo(undefined, serverUrl, versionFilepathInServer, installPath, extensionPath); + launchInfo.LaunchPath.should.equal(path.resolve(extensionPath, '.omnisharp/run')); + launchInfo.MonoLaunchPath.should.equal(path.resolve(extensionPath, '.omnisharp/omnisharp/OmniSharp.exe')); + }); + + test('Returns the same path if absolute path to an existing file is passed', async () => { + tmpFile = tmp.fileSync(); + let launchInfo = await manager.GetOmniSharpLaunchInfo(tmpFile.name, serverUrl, versionFilepathInServer, installPath, extensionPath); + launchInfo.LaunchPath.should.equal(tmpFile.name); + }); + + test('Installs the latest version and returns the launch path based on the version and platform', async () => { + let launchInfo = await manager.GetOmniSharpLaunchInfo("latest", serverUrl, versionFilepathInServer, installPath, extensionPath); + launchInfo.LaunchPath.should.equal(path.resolve(extensionPath, `.omnisharp/experimental/1.2.3/OmniSharp.exe`)); + expect(launchInfo.MonoLaunchPath).to.be.undefined; + }); + + test('Installs the test version and returns the launch path based on the version and platform', async () => { + let launchInfo = await manager.GetOmniSharpLaunchInfo("1.2.3", serverUrl, versionFilepathInServer, installPath, extensionPath); + launchInfo.LaunchPath.should.equal(path.resolve(extensionPath, `.omnisharp/experimental/1.2.3/OmniSharp.exe`)); + expect(launchInfo.MonoLaunchPath).to.be.undefined; + }); + + test('Downloads package from given url and installs them at the specified path', async () => { + await manager.GetOmniSharpLaunchInfo("1.2.3", serverUrl, versionFilepathInServer, installPath, extensionPath); + let exists = await util.fileExists(path.resolve(extensionPath, `.omnisharp/experimental/1.2.3/install_check_1.2.3.txt`)); + exists.should.equal(true); + }); + + test('Downloads package and returns launch path based on platform - on Linux ', async () => { + let manager = GetTestOmnisharpManager(eventStream, new PlatformInformation("linux", "x64")); + let launchInfo = await manager.GetOmniSharpLaunchInfo("1.2.3", serverUrl, versionFilepathInServer, installPath, extensionPath); + launchInfo.LaunchPath.should.equal(path.resolve(extensionPath, '.omnisharp/experimental/1.2.3/run')); + launchInfo.MonoLaunchPath.should.equal(path.resolve(extensionPath, '.omnisharp/experimental/1.2.3/omnisharp/OmniSharp.exe')); + }); + + test('Downloads package and returns launch path based on install path ', async () => { + let manager = GetTestOmnisharpManager(eventStream, platformInfo); + let launchInfo = await manager.GetOmniSharpLaunchInfo("1.2.3", serverUrl, versionFilepathInServer, "installHere", extensionPath); + launchInfo.LaunchPath.should.equal(path.resolve(extensionPath, 'installHere/1.2.3/OmniSharp.exe')); + expect(launchInfo.MonoLaunchPath).to.be.undefined; + }); + + teardown(async () => { + if (tmpDir) { + await rimraf(tmpDir.name); + } + + if (tmpFile) { + tmpFile.removeCallback(); + } + + tmpFile = null; + tmpDir = null; + }); +}); + +function GetTestOmnisharpManager(eventStream: EventStream, platformInfo: PlatformInformation) { + let downloader = GetTestOmnisharpDownloader(eventStream, platformInfo); + return new OmnisharpManager(downloader, platformInfo); +} diff --git a/test/featureTests/OmnisharpPackageCreator.test.ts b/test/featureTests/OmnisharpPackageCreator.test.ts new file mode 100644 index 000000000..f4b5c1ea1 --- /dev/null +++ b/test/featureTests/OmnisharpPackageCreator.test.ts @@ -0,0 +1,198 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { assert, should, expect } from "chai"; +import { SetBinaryAndGetPackage, GetPackagesFromVersion } from "../../src/omnisharp/OmnisharpPackageCreator"; +import { testPackageJSON } from "./testAssets/testAssets"; +import { Package } from "../../src/packageManager/Package"; + +suite("GetOmnisharpPackage : Output package depends on the input package and other input parameters like serverUrl", () => { + + let serverUrl: string; + let version: string; + let installPath: string; + let inputPackages: Package[]; + + suiteSetup(() => { + serverUrl = "http://serverUrl"; + version = "0.0.0"; + installPath = "testPath"; + let packageJSON = testPackageJSON; + inputPackages = (packageJSON.runtimeDependencies); + should(); + }); + + test('Throws exception if version is empty', () => { + let testPackage = inputPackages.find(element => (element.platformId && element.platformId == "os-architecture")); + let fn = function () { SetBinaryAndGetPackage(testPackage, serverUrl, "", installPath); }; + expect(fn).to.throw('Invalid version'); + }); + + test('Throws exception if version is null', () => { + let testPackage = inputPackages.find(element => (element.platformId && element.platformId == "os-architecture")); + let fn = function () { SetBinaryAndGetPackage(testPackage, serverUrl, null, installPath);}; + expect(fn).to.throw('Invalid version'); + }); + + test('Architectures, binaries and platforms do not change and fallback url is empty', () => { + let testPackage = inputPackages.find(element => (element.platformId && element.platformId == "os-architecture")); + let resultPackage = SetBinaryAndGetPackage(testPackage, serverUrl, version, installPath); + + resultPackage.architectures.should.equal(testPackage.architectures); + assert.equal(resultPackage.binaries, testPackage.binaries); + resultPackage.platforms.should.equal(testPackage.platforms); + expect(resultPackage.fallbackUrl).to.be.empty; + }); + + test('Version information is appended to the description', () => { + let testPackage = inputPackages.find(element => (element.platformId && element.platformId == "os-architecture")); + let resultPackage = SetBinaryAndGetPackage(testPackage, serverUrl, "1.2.3", installPath); + + resultPackage.description.should.equal(`${testPackage.description}, Version = 1.2.3`); + }); + + test('Download url is calculated using server url and version', () => { + let testPackage = inputPackages.find(element => (element.platformId && element.platformId == "os-architecture")); + let resultPackage = SetBinaryAndGetPackage(testPackage, "http://someurl", "1.1.1", installPath); + resultPackage.url.should.equal("http://someurl/releases/1.1.1/omnisharp-os-architecture.zip"); + }); + + test('Install path is calculated using the specified path and version', () => { + let testPackage = inputPackages.find(element => (element.platformId && element.platformId == "os-architecture")); + let resultPackage = SetBinaryAndGetPackage(testPackage, serverUrl, "1.2.3", "experimentPath"); + resultPackage.installPath.should.equal("experimentPath/1.2.3"); + }); + + test('Install test path is calculated using specified path, version and ends with Omnisharp.exe - Windows(x86)', () => { + let testPackage = inputPackages.find(element => (element.platformId && element.platformId == "win-x86")); + let resultPackage = SetBinaryAndGetPackage(testPackage, serverUrl, "1.2.3", "experimentPath"); + resultPackage.installTestPath.should.equal("./experimentPath/1.2.3/OmniSharp.exe"); + }); + + test('Install test path is calculated using specified path, version and ends with Omnisharp.exe - Windows(x64)', () => { + let testPackage = inputPackages.find(element => (element.platformId && element.platformId == "win-x64")); + let resultPackage = SetBinaryAndGetPackage(testPackage, serverUrl, "1.2.3", "experimentPath"); + resultPackage.installTestPath.should.equal("./experimentPath/1.2.3/OmniSharp.exe"); + }); + + test('Install test path is calculated using specified path, version and ends with mono.osx - OSX', () => { + let testPackage = inputPackages.find(element => (element.platformId && element.platformId == "osx")); + let resultPackage = SetBinaryAndGetPackage(testPackage, serverUrl, "1.2.3", "experimentPath"); + resultPackage.installTestPath.should.equal("./experimentPath/1.2.3/mono.osx"); + }); + + test('Install test path is calculated using specified path, version and ends with mono.linux-x86 - Linux(x86)', () => { + let testPackage = inputPackages.find(element => (element.platformId && element.platformId == "linux-x86")); + let resultPackage = SetBinaryAndGetPackage(testPackage, serverUrl, "1.2.3", "experimentPath"); + resultPackage.installTestPath.should.equal("./experimentPath/1.2.3/mono.linux-x86"); + }); + + test('Install test path is calculated using specified path, version and ends with mono.linux-x86_64 - Linux(x64)', () => { + let testPackage = inputPackages.find(element => (element.platformId && element.platformId == "linux-x64")); + let resultPackage = SetBinaryAndGetPackage(testPackage, serverUrl, "1.2.3", "experimentPath"); + resultPackage.installTestPath.should.equal("./experimentPath/1.2.3/mono.linux-x86_64"); + }); +}); + +suite('GetPackagesFromVersion : Gets the experimental omnisharp packages from a set of input packages', () => { + + const serverUrl = "http://serverUrl"; + const installPath = "testPath"; + let inputPackages : any; + + suiteSetup(() => { + inputPackages = (testPackageJSON.runtimeDependencies); + should(); + }); + + test('Throws exception if the version is null', () => { + let version: string = null; + let fn = function () { GetPackagesFromVersion(version, inputPackages, serverUrl, installPath); }; + expect(fn).to.throw('Invalid version'); + }); + + test('Throws exception if the version is empty', () => { + let version = ""; + let fn = function () { GetPackagesFromVersion(version, inputPackages, serverUrl, installPath); }; + expect(fn).to.throw('Invalid version'); + }); + + test('Returns experiment packages with install test path depending on install path and version', () => { + let inputPackages = [ + { + "description": "OmniSharp for Windows (.NET 4.6 / x64)", + "url": "https://download.visualstudio.microsoft.com/download/pr/100505821/c570a9e20dbf7172f79850babd058872/omnisharp-win-x64-1.28.0.zip", + "fallbackUrl": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x64-1.28.0.zip", + "installPath": ".omnisharp", + "platforms": [ + "win32" + ], + "architectures": [ + "x86_64" + ], + "installTestPath": "./.omnisharp/OmniSharp.exe", + "platformId": "win-x64" + }, + { + "description": "OmniSharp for OSX", + "url": "https://download.visualstudio.microsoft.com/download/pr/100505818/6b99c6a86da3221919158ca0f36a3e45/omnisharp-osx-1.28.0.zip", + "fallbackUrl": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-osx-1.28.0.zip", + "installPath": ".omnisharp", + "platforms": [ + "darwin" + ], + "binaries": [ + "./mono.osx", + "./run" + ], + "installTestPath": "./.omnisharp/mono.osx", + "platformId": "osx" + }, + ]; + + let outPackages = GetPackagesFromVersion("1.1.1", inputPackages, serverUrl, "experimentPath"); + outPackages.length.should.equal(2); + outPackages[0].installTestPath.should.equal("./experimentPath/1.1.1/OmniSharp.exe"); + outPackages[1].installTestPath.should.equal("./experimentPath/1.1.1/mono.osx"); + }); + + test('Returns only omnisharp packages with experimentalIds', () => { + let version = "0.0.0"; + let inputPackages = [ + { + "description": "OmniSharp for Windows (.NET 4.6 / x64)", + "url": "https://download.visualstudio.microsoft.com/download/pr/100505821/c570a9e20dbf7172f79850babd058872/omnisharp-win-x64-1.28.0.zip", + "fallbackUrl": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x64-1.28.0.zip", + "installPath": ".omnisharp", + "platforms": [ + "win32" + ], + "architectures": [ + "x86_64" + ], + "installTestPath": "./.omnisharp/OmniSharp.exe", + "platformId": "win-x64" + }, + { + "description": "Some other package - no experimental id", + "url": "https://download.visualstudio.microsoft.com/download/pr/100505818/6b99c6a86da3221919158ca0f36a3e45/omnisharp-osx-1.28.0.zip", + "fallbackUrl": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-osx-1.28.0.zip", + "installPath": ".omnisharp", + "platforms": [ + "darwin" + ], + "binaries": [ + "./mono.osx", + "./run" + ], + "installTestPath": "./.omnisharp/mono.osx", + }, + ]; + + let outPackages = GetPackagesFromVersion(version, inputPackages, serverUrl, installPath); + outPackages.length.should.equal(1); + outPackages[0].platformId.should.equal("win-x64"); + }); +}); \ No newline at end of file diff --git a/test/unitTests/assets.test.ts b/test/featureTests/assets.test.ts similarity index 100% rename from test/unitTests/assets.test.ts rename to test/featureTests/assets.test.ts diff --git a/test/unitTests/index.ts b/test/featureTests/index.ts similarity index 88% rename from test/unitTests/index.ts rename to test/featureTests/index.ts index ce7193f1a..5eec1b9ba 100644 --- a/test/unitTests/index.ts +++ b/test/featureTests/index.ts @@ -15,13 +15,15 @@ // to report the results back to the caller. When the tests are finished, return // a possible error to the callback or null if none. -let testRunner = require('vscode/lib/testrunner'); +import coverageWritingTestRunner from "../coverageWritingTestRunner"; + +let testRunner = new coverageWritingTestRunner(require('vscode/lib/testrunner')); // You can directly control Mocha options by uncommenting the following lines // See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info testRunner.configure({ - timeout: 10000, + timeout: 100000, ui: 'tdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.) useColors: true // colored output from test results }); diff --git a/test/unitTests/processPicker.test.ts b/test/featureTests/processPicker.test.ts similarity index 99% rename from test/unitTests/processPicker.test.ts rename to test/featureTests/processPicker.test.ts index f8189d0fa..3130fdda5 100644 --- a/test/unitTests/processPicker.test.ts +++ b/test/featureTests/processPicker.test.ts @@ -222,7 +222,7 @@ function GetOSSpecificJSON() { return { pipeCwd: "${workspaceFolder}", pipeProgram: "pipeProgram", - pipeArgs: [], + pipeArgs: [], windows: { pipeProgram: "Windows pipeProgram", pipeArgs: "windows" diff --git a/test/featureTests/testAssets/testAssets.ts b/test/featureTests/testAssets/testAssets.ts new file mode 100644 index 000000000..72c3921b8 --- /dev/null +++ b/test/featureTests/testAssets/testAssets.ts @@ -0,0 +1,142 @@ + +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { EventStream } from "../../../src/EventStream"; +import { PlatformInformation } from "../../../src/platform"; +import { OmnisharpDownloader } from "../../../src/omnisharp/OmnisharpDownloader"; +import { getFakeVsCode, getNullWorkspaceConfiguration } from "../../unitTests/testAssets/Fakes"; +import { Uri } from "../../../src/vscodeAdapter"; +import NetworkSettings from "../../../src/NetworkSettings"; + + +export function GetTestOmnisharpDownloader(sink: EventStream, platformInfo: PlatformInformation): OmnisharpDownloader { + let vscode = getFakeVsCode(); + vscode.workspace.getConfiguration = (section?: string, resource?: Uri) => { + return { + ...getNullWorkspaceConfiguration(), + }; + }; + + return new OmnisharpDownloader(() => new NetworkSettings(undefined, undefined), sink, testPackageJSON, platformInfo); +} + +//Since we need only the runtime dependencies of packageJSON for the downloader create a testPackageJSON +//with just that +export let testPackageJSON = { + "runtimeDependencies": [ + { + "description": "OmniSharp for Windows (.NET 4.6 / x86)", + "url": "https://download.visualstudio.microsoft.com/download/pr/100505823/5804b7d3b5eeb7e4ae812a7cff03bd52/omnisharp-win-x86-1.28.0.zip", + "fallbackUrl": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x86-1.28.0.zip", + "installPath": ".omnisharp", + "platforms": [ + "win32" + ], + "architectures": [ + "x86" + ], + "installTestPath": "./.omnisharp/OmniSharp.exe", + "platformId": "win-x86" + }, + { + "description": "OmniSharp for Windows (.NET 4.6 / x64)", + "url": "https://download.visualstudio.microsoft.com/download/pr/100505821/c570a9e20dbf7172f79850babd058872/omnisharp-win-x64-1.28.0.zip", + "fallbackUrl": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x64-1.28.0.zip", + "installPath": ".omnisharp", + "platforms": [ + "win32" + ], + "architectures": [ + "x86_64" + ], + "installTestPath": "./.omnisharp/OmniSharp.exe", + "platformId": "win-x64" + }, + { + "description": "OmniSharp for OSX", + "url": "https://download.visualstudio.microsoft.com/download/pr/100505818/6b99c6a86da3221919158ca0f36a3e45/omnisharp-osx-1.28.0.zip", + "fallbackUrl": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-osx-1.28.0.zip", + "installPath": ".omnisharp", + "platforms": [ + "darwin" + ], + "binaries": [ + "./mono.osx", + "./run" + ], + "installTestPath": "./.omnisharp/mono.osx", + "platformId": "osx" + }, + { + "description": "OmniSharp for Linux (x86)", + "url": "https://download.visualstudio.microsoft.com/download/pr/100505817/b710ec9c2bedc0cfdb57da82da166c47/omnisharp-linux-x86-1.28.0.zip", + "fallbackUrl": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-linux-x86-1.28.0.zip", + "installPath": ".omnisharp", + "platforms": [ + "linux" + ], + "architectures": [ + "x86", + "i686" + ], + "binaries": [ + "./mono.linux-x86", + "./run" + ], + "installTestPath": "./.omnisharp/mono.linux-x86", + "platformId": "linux-x86" + }, + { + "description": "OmniSharp for Linux (x64)", + "url": "https://download.visualstudio.microsoft.com/download/pr/100505485/3f8a10409240decebb8a3189429f3fdf/omnisharp-linux-x64-1.28.0.zip", + "fallbackUrl": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-linux-x64-1.28.0.zip", + "installPath": ".omnisharp", + "platforms": [ + "linux" + ], + "architectures": [ + "x86_64" + ], + "binaries": [ + "./mono.linux-x86_64", + "./run" + ], + "installTestPath": "./.omnisharp/mono.linux-x86_64", + "platformId": "linux-x64" + }, + { + "description": "OmniSharp for Test OS(architecture)", + "url": "https://download.visualstudio.microsoft.com/download/pr/100505485/3f8a10409240decebb8a3189429f3fdf/omnisharp-os-architecture-version.zip", + "fallbackUrl": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-os-architecture-version.zip", + "installPath": ".omnisharp", + "platforms": [ + "platform1" + ], + "architectures": [ + "architecture" + ], + "binaries": [ + "./binary1", + "./binary2" + ], + "installTestPath": "./.omnisharp/binary", + "platformId": "os-architecture" + }, + { + "description": "Non omnisharp package without platformId", + "url": "https://download.visualstudio.microsoft.com/download/pr/100317420/a30d7e11bc435433d297adc824ee837f/coreclr-debug-win7-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-14-4/coreclr-debug-win7-x64.zip", + "installPath": ".debugger", + "platforms": [ + "win32" + ], + "architectures": [ + "x86_64" + ], + "installTestPath": "./.debugger/vsdbg-ui.exe" + } + ] +}; \ No newline at end of file diff --git a/test/integrationTests/codeActionRename.integration.test.ts b/test/integrationTests/codeActionRename.integration.test.ts index 2930d25c5..f55897288 100644 --- a/test/integrationTests/codeActionRename.integration.test.ts +++ b/test/integrationTests/codeActionRename.integration.test.ts @@ -1,33 +1,35 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as fs from 'async-file'; import * as vscode from 'vscode'; - -import poll from './poll'; import { should, expect } from 'chai'; import testAssetWorkspace from './testAssets/testAssetWorkspace'; +import CSharpExtensionExports from '../../src/CSharpExtensionExports'; + +const chai = require('chai'); +chai.use(require('chai-arrays')); +chai.use(require('chai-fs')); -const chai = require('chai'); -chai.use(require('chai-arrays')); -chai.use(require('chai-fs')); - suite(`Code Action Rename ${testAssetWorkspace.description}`, function() { - suiteSetup(async function() { + suiteSetup(async function() { should(); - let csharpExtension = vscode.extensions.getExtension("ms-vscode.csharp"); - if (!csharpExtension.isActive) { - await csharpExtension.activate(); + let csharpExtension = vscode.extensions.getExtension("ms-vscode.csharp"); + if (!csharpExtension.isActive) { + await csharpExtension.activate(); + } + try { + await csharpExtension.exports.initializationFinished(); + } + catch (err) { + console.log(JSON.stringify(err)); } - - await csharpExtension.exports.initializationFinished; }); - - test("Code actions can rename and open files", async () => { + + test("Code actions can rename and open files", async () => { let fileUri = await testAssetWorkspace.projects[0].addFileWithContents("test.cs", "class C {}"); await vscode.commands.executeCommand("vscode.open", fileUri); let c = await vscode.commands.executeCommand("vscode.executeCodeActionProvider", fileUri, new vscode.Range(0, 7, 0, 7)) as {command: string, title: string, arguments: string[]}[]; @@ -35,11 +37,11 @@ suite(`Code Action Rename ${testAssetWorkspace.description}`, function() { (s) => { return s.title == "Rename file to C.cs"; } ); expect(command, "Didn't find rename class command"); - await vscode.commands.executeCommand(command.command, ...command.arguments) + await vscode.commands.executeCommand(command.command, ...command.arguments); expect(vscode.window.activeTextEditor.document.fileName).contains("C.cs"); }); teardown(async () => { await testAssetWorkspace.cleanupWorkspace(); }); -}); \ No newline at end of file +}); \ No newline at end of file diff --git a/test/integrationTests/hoverProvider.integration.test.ts b/test/integrationTests/hoverProvider.integration.test.ts index 8bf863916..cbfb3ebd7 100644 --- a/test/integrationTests/hoverProvider.integration.test.ts +++ b/test/integrationTests/hoverProvider.integration.test.ts @@ -3,62 +3,38 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as fs from 'async-file'; import * as vscode from 'vscode'; +import * as path from 'path'; -import poll from './poll'; import { should, expect } from 'chai'; import testAssetWorkspace from './testAssets/testAssetWorkspace'; -import { RequestQueueCollection } from '../../src/omnisharp/requestQueue'; -import { OmniSharpServer } from '../../src/omnisharp/server'; -import { omnisharp } from '../../src/omnisharp/extension'; -const chai = require('chai'); -chai.use(require('chai-arrays')); -chai.use(require('chai-fs')); +const chai = require('chai'); +chai.use(require('chai-arrays')); +chai.use(require('chai-fs')); -suite(`Hover Provider: ${testAssetWorkspace.description}`, function() { - suiteSetup(async function() { +suite(`Hover Provider: ${testAssetWorkspace.description}`, function () { + suiteSetup(async function () { should(); - let csharpExtension = vscode.extensions.getExtension("ms-vscode.csharp"); - if (!csharpExtension.isActive) { - await csharpExtension.activate(); + let csharpExtension = vscode.extensions.getExtension("ms-vscode.csharp"); + if (!csharpExtension.isActive) { + await csharpExtension.activate(); } await csharpExtension.exports.initializationFinished; - await omnisharp.restart(); - }); - - test("Hover returns structured documentation with proper newlines", async function () { - - let program = -`using System; -namespace Test -{ - class testissue - { - ///Checks if object is tagged with the tag. - /// The game object. - /// Name of the tag. - /// Returns true if object is tagged with tag. - - public static bool Compare(int gameObject,string tagName) - { - return true; - } - } -}`; - let fileUri = await testAssetWorkspace.projects[0].addFileWithContents("test1.cs", program); - - await omnisharp.waitForEmptyEventQueue(); - - await vscode.commands.executeCommand("vscode.open", fileUri); + }); - let c = await vscode.commands.executeCommand("vscode.executeHoverProvider", fileUri,new vscode.Position(10,29)); + test("Hover returns structured documentation with proper newlines", async function () { + let fileName = 'hover.cs'; + let dir = path.dirname(testAssetWorkspace.projects[0].projectDirectoryPath); + let loc = path.join(dir, fileName); + let fileUri = vscode.Uri.file(loc); - let answer:string = -`Checks if object is tagged with the tag. + await vscode.commands.executeCommand("vscode.open", fileUri); + let c = (await vscode.commands.executeCommand("vscode.executeHoverProvider", fileUri, new vscode.Position(10, 29))); + let answer: string = + `Checks if object is tagged with the tag. Parameters: @@ -66,9 +42,9 @@ Parameters: \t\ttagName: Name of the tag. Returns true if object is tagged with tag.`; - expect(c[0].contents[0].value).to.equal(answer); + expect((<{ language: string; value: string }>c[0].contents[0]).value).to.equal(answer); }); - + teardown(async () => { await testAssetWorkspace.cleanupWorkspace(); }); diff --git a/test/integrationTests/index.ts b/test/integrationTests/index.ts index 1975e5fbe..0a9f1a494 100644 --- a/test/integrationTests/index.ts +++ b/test/integrationTests/index.ts @@ -4,8 +4,10 @@ *--------------------------------------------------------------------------------------------*/ import * as fs from "fs"; +import * as path from "path"; import { SubscribeToAllLoggers } from "../../src/logger"; +import coverageWritingTestRunner from "../coverageWritingTestRunner"; // // PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING @@ -19,7 +21,8 @@ import { SubscribeToAllLoggers } from "../../src/logger"; // to report the results back to the caller. When the tests are finished, return // a possible error to the callback or null if none. -let testRunner = require('vscode/lib/testrunner'); +let testRunner = new coverageWritingTestRunner(require('vscode/lib/testrunner')); + // You can directly control Mocha options by uncommenting the following lines // See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info @@ -30,12 +33,14 @@ testRunner.configure({ useColors: true // colored output from test results }); -if (process.env.OSVC_SUITE) { - if (!fs.existsSync("./.logs")) { - fs.mkdirSync("./.logs"); - } +if (process.env.CODE_EXTENSIONS_PATH && process.env.OSVC_SUITE) { + let logDirPath = path.join(process.env.CODE_EXTENSIONS_PATH, "./.logs"); - let logFilePath = `./.logs/${process.env.OSVC_SUITE}.log`; + if (!fs.existsSync(logDirPath)) { + fs.mkdirSync(logDirPath); + } + + let logFilePath = path.join(logDirPath, `${process.env.OSVC_SUITE}.log`); SubscribeToAllLoggers(message => fs.appendFileSync(logFilePath, message)); } diff --git a/test/integrationTests/launchConfiguration.integration.test.ts b/test/integrationTests/launchConfiguration.integration.test.ts index 6331c7bcc..1f2e63698 100644 --- a/test/integrationTests/launchConfiguration.integration.test.ts +++ b/test/integrationTests/launchConfiguration.integration.test.ts @@ -1,6 +1,6 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as fs from 'async-file'; @@ -30,7 +30,6 @@ suite(`Tasks generation: ${testAssetWorkspace.description}`, function () { await vscode.commands.executeCommand("dotnet.generateAssets"); await poll(async () => await fs.exists(testAssetWorkspace.launchJsonPath), 10000, 100); - }); test("Starting .NET Core Launch (console) from the workspace root should create an Active Debug Session", async () => { diff --git a/test/integrationTests/poll.ts b/test/integrationTests/poll.ts index 2ada6c7d7..c26acdfa2 100644 --- a/test/integrationTests/poll.ts +++ b/test/integrationTests/poll.ts @@ -19,6 +19,6 @@ export default async function poll(getValue: () => T, duration: number, step: throw new Error("Polling did not succeed within the alotted duration."); } -function sleep(ms = 0) { +async function sleep(ms = 0) { return new Promise(r => setTimeout(r, ms)); } \ No newline at end of file diff --git a/test/integrationTests/signatureHelp.integration.test.ts b/test/integrationTests/signatureHelp.integration.test.ts new file mode 100644 index 000000000..62ceabf05 --- /dev/null +++ b/test/integrationTests/signatureHelp.integration.test.ts @@ -0,0 +1,90 @@ +/*--------------------------------------------------------------------------------------------- +* Copyright (c) Microsoft Corporation. All rights reserved. +* Licensed under the MIT License. See License.txt in the project root for license information. +*--------------------------------------------------------------------------------------------*/ + +import * as vscode from 'vscode'; +import * as path from 'path'; + +import { should, expect } from 'chai'; +import testAssetWorkspace from './testAssets/testAssetWorkspace'; + +const chai = require('chai'); +chai.use(require('chai-arrays')); +chai.use(require('chai-fs')); + +suite(`SignatureHelp: ${testAssetWorkspace.description}`, function () { + let fileUri: vscode.Uri; + suiteSetup(async function () { + should(); + + let csharpExtension = vscode.extensions.getExtension("ms-vscode.csharp"); + if (!csharpExtension.isActive) { + await csharpExtension.activate(); + } + + await csharpExtension.exports.initializationFinished; + + let fileName = 'sigHelp.cs'; + let dir = path.dirname(testAssetWorkspace.projects[0].projectDirectoryPath); + let loc = path.join(dir, fileName); + fileUri = vscode.Uri.file(loc); + await vscode.commands.executeCommand("vscode.open", fileUri); + }); + + + test("Returns response with documentation as undefined when method does not have documentation", async function () { + let c = await GetSignatureHelp(fileUri, new vscode.Position(19, 23)); + expect(c.signatures[0].documentation).to.be.undefined; + }); + + test("Returns label when method does not have documentation", async function () { + let c = await GetSignatureHelp(fileUri, new vscode.Position(19, 23)); + expect(c.signatures[0].label).to.equal(`void sigHelp.noDocMethod()`); + }); + + test("Returns summary as documentation for the method", async function () { + let c = await GetSignatureHelp(fileUri, new vscode.Position(18, 18)); + expect(c.signatures[0].documentation).to.equal(`DoWork is some method.`); + }); + + test("Returns label for the method", async function () { + let c = await GetSignatureHelp(fileUri, new vscode.Position(18, 18)); + expect(c.signatures[0].label).to.equal(`void sigHelp.DoWork(int Int1, float Float1, double Double1)`); + }); + + test("Returns label for the parameters", async function () { + let c = await GetSignatureHelp(fileUri, new vscode.Position(18, 18)); + expect(c.signatures[0].parameters[0].label).to.equal(`int Int1`); + expect(c.signatures[0].parameters[1].label).to.equal(`float Float1`); + }); + + test("Returns documentation for the parameters", async function () { + let c = await GetSignatureHelp(fileUri, new vscode.Position(18, 18)); + expect((c.signatures[0].parameters[0].documentation).value).to.equal(`**Int1**: Used to indicate status.`); + expect((c.signatures[0].parameters[1].documentation).value).to.equal(`**Float1**: Used to specify context.`); + }); + + test("Signature Help identifies active parameter if there is no comma", async function () { + let c = await GetSignatureHelp(fileUri, new vscode.Position(18, 18)); + expect(c.signatures[0].parameters[c.activeParameter].label).to.equal(`int Int1`); + }); + + test("Signature Help identifies active parameter based on comma", async function () { + let c = await GetSignatureHelp(fileUri, new vscode.Position(18, 20)); + expect(c.signatures[0].parameters[c.activeParameter].label).to.equal(`float Float1`); + }); + + test("Signature Help identifies active parameter based on comma for multiple commas", async function () { + let c = await GetSignatureHelp(fileUri, new vscode.Position(18, 27)); + expect(c.signatures[0].parameters[c.activeParameter].label).to.equal(`double Double1`); + }); +}); + +suiteTeardown(async () => { + await testAssetWorkspace.cleanupWorkspace(); +}); + +async function GetSignatureHelp(fileUri: vscode.Uri, position: vscode.Position) { + return await vscode.commands.executeCommand("vscode.executeSignatureHelpProvider", fileUri, position); +} \ No newline at end of file diff --git a/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json b/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json new file mode 100644 index 000000000..ba0e6ce6e --- /dev/null +++ b/test/integrationTests/testAssets/singleCsproj/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "omnisharp.path": "latest"" +} \ No newline at end of file diff --git a/test/integrationTests/testAssets/singleCsproj/hover.cs b/test/integrationTests/testAssets/singleCsproj/hover.cs new file mode 100644 index 000000000..cbfc3d9d3 --- /dev/null +++ b/test/integrationTests/testAssets/singleCsproj/hover.cs @@ -0,0 +1,16 @@ +using System; +namespace Test +{ + class testissue + { + ///Checks if object is tagged with the tag. + /// The game object. + /// Name of the tag. + /// Returns true if object is tagged with tag. + + public static bool Compare(int gameObject,string tagName) + { + return true; + } + } +} \ No newline at end of file diff --git a/test/integrationTests/testAssets/singleCsproj/obj/Debug/netcoreapp2.0/singleCsproj.csproj.CoreCompileInputs.cache b/test/integrationTests/testAssets/singleCsproj/obj/Debug/netcoreapp2.0/singleCsproj.csproj.CoreCompileInputs.cache index ccde3e0e4..0cb96c1c5 100644 --- a/test/integrationTests/testAssets/singleCsproj/obj/Debug/netcoreapp2.0/singleCsproj.csproj.CoreCompileInputs.cache +++ b/test/integrationTests/testAssets/singleCsproj/obj/Debug/netcoreapp2.0/singleCsproj.csproj.CoreCompileInputs.cache @@ -1 +1 @@ -fe2f654e9c48e6a308b6a264aa38a2b3defe5730 +ffcdec535c6ed9f5449ad17c7f1a870da5e60671 diff --git a/test/integrationTests/testAssets/singleCsproj/sigHelp.cs b/test/integrationTests/testAssets/singleCsproj/sigHelp.cs new file mode 100644 index 000000000..811e90f8c --- /dev/null +++ b/test/integrationTests/testAssets/singleCsproj/sigHelp.cs @@ -0,0 +1,23 @@ +using System; +namespace Test +{ + class sigHelp + { + ///DoWork is some method. + /// Used to indicate status. + /// Used to specify context. + public static void DoWork(int Int1, float Float1, double Double1) + { + } + + public static void noDocMethod() + { + } + + public static void main() + { + DoWork(4, 4.0f, 5.0); + noDocMethod(); + } + } +} \ No newline at end of file diff --git a/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json b/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json new file mode 100644 index 000000000..15054e359 --- /dev/null +++ b/test/integrationTests/testAssets/slnWithCsproj/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "omnisharp.path": "latest" +} \ No newline at end of file diff --git a/test/integrationTests/testAssets/slnWithCsproj/src/app/hover.cs b/test/integrationTests/testAssets/slnWithCsproj/src/app/hover.cs new file mode 100644 index 000000000..cbfc3d9d3 --- /dev/null +++ b/test/integrationTests/testAssets/slnWithCsproj/src/app/hover.cs @@ -0,0 +1,16 @@ +using System; +namespace Test +{ + class testissue + { + ///Checks if object is tagged with the tag. + /// The game object. + /// Name of the tag. + /// Returns true if object is tagged with tag. + + public static bool Compare(int gameObject,string tagName) + { + return true; + } + } +} \ No newline at end of file diff --git a/test/integrationTests/testAssets/slnWithCsproj/src/app/obj/app.csproj.nuget.cache b/test/integrationTests/testAssets/slnWithCsproj/src/app/obj/app.csproj.nuget.cache index 7ab10deb6..82b6ede62 100644 --- a/test/integrationTests/testAssets/slnWithCsproj/src/app/obj/app.csproj.nuget.cache +++ b/test/integrationTests/testAssets/slnWithCsproj/src/app/obj/app.csproj.nuget.cache @@ -1,5 +1,5 @@ { "version": 1, - "dgSpecHash": "RNA104eAZOOjmBHjHUGqqHR8Fn7tcLprXcob3oYEPt6wIFL2EV8N4mAG22nU31T1NJV+oAzYBZ7kJEOWeYa4gA==", + "dgSpecHash": "LtRbOANp61aGFLSYtqkHdimQE8PhWQFikqq6awdFvLYYWlsGOmoelJYSlZng7sN5owLFPWERZH/mdxVoNUvTlA==", "success": true } \ No newline at end of file diff --git a/test/integrationTests/testAssets/slnWithCsproj/src/app/obj/app.csproj.nuget.g.props b/test/integrationTests/testAssets/slnWithCsproj/src/app/obj/app.csproj.nuget.g.props index a69433598..f19d2600e 100644 --- a/test/integrationTests/testAssets/slnWithCsproj/src/app/obj/app.csproj.nuget.g.props +++ b/test/integrationTests/testAssets/slnWithCsproj/src/app/obj/app.csproj.nuget.g.props @@ -3,9 +3,9 @@ True NuGet - C:\omnisharp-vscode\test\integrationTests\testAssets\slnWithCsproj\src\app\obj\project.assets.json - $(UserProfile)\.nuget\packages\ - C:\Users\rchande\.nuget\packages\;C:\Program Files\dotnet\sdk\NuGetFallbackFolder + /Users/piotrp/code/github/piotrpMSFT/omnisharp-vscode/test/integrationTests/testAssets/slnWithCsproj/src/app/obj/project.assets.json + /Users/piotrp/code/github/piotrpMSFT/cli/.nuget/packages + /Users/piotrp/code/github/piotrpMSFT/cli/.nuget/packages;/usr/local/share/dotnet/sdk/NuGetFallbackFolder PackageReference 4.5.0 @@ -13,6 +13,6 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - + \ No newline at end of file diff --git a/test/integrationTests/testAssets/slnWithCsproj/src/app/obj/app.csproj.nuget.g.targets b/test/integrationTests/testAssets/slnWithCsproj/src/app/obj/app.csproj.nuget.g.targets index 562d65f7d..d0382bbdf 100644 --- a/test/integrationTests/testAssets/slnWithCsproj/src/app/obj/app.csproj.nuget.g.targets +++ b/test/integrationTests/testAssets/slnWithCsproj/src/app/obj/app.csproj.nuget.g.targets @@ -4,7 +4,7 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - - + + \ No newline at end of file diff --git a/test/integrationTests/testAssets/slnWithCsproj/src/app/obj/project.assets.json b/test/integrationTests/testAssets/slnWithCsproj/src/app/obj/project.assets.json index 637e9b95e..0ad3d44a7 100644 --- a/test/integrationTests/testAssets/slnWithCsproj/src/app/obj/project.assets.json +++ b/test/integrationTests/testAssets/slnWithCsproj/src/app/obj/project.assets.json @@ -211,7 +211,7 @@ }, "libraries": { "Microsoft.NETCore.App/2.0.0": { - "sha512": "/mzXF+UtZef+VpzzN88EpvFq5U6z4rj54ZMq/J968H6pcvyLOmcupmTRpJ3CJm8ILoCGh9WI7qpDdiKtuzswrQ==", + "sha512": "u30D3okjSE34FaNeF45fQn0pEe4HTfd5jIKpyun0DD9TK7G8WC4/xLn0ZjbHT/nvWznayTl36J2X2rT8tjx+Dw==", "type": "package", "path": "microsoft.netcore.app/2.0.0", "files": [ @@ -489,7 +489,7 @@ ] }, "Microsoft.NETCore.DotNetAppHost/2.0.0": { - "sha512": "L4GGkcI/Mxl8PKLRpFdGmLb5oI8sGIR05bDTGkzCoamAjdUl1Zhkov2swjEsZvKYT8kkdiz39LtwyGYuCJxm1A==", + "sha512": "YPFCzBe0Rh1wMZcJvbKfDMC2ARi7vPeeTcDcsf2m91Bs6NorZHiCQWznBcZqxnyq9WvkHDpgrS2yNiD5NkvLLQ==", "type": "package", "path": "microsoft.netcore.dotnetapphost/2.0.0", "files": [ @@ -525,7 +525,7 @@ ] }, "Microsoft.NETCore.Platforms/2.0.0": { - "sha512": "VdLJOCXhZaEMY7Hm2GKiULmn7IEPFE4XC5LPSfBVCUIA8YLZVh846gtfBJalsPQF2PlzdD7ecX7DZEulJ402ZQ==", + "sha512": "uh69u8rko8LLHnhuBkDxIpsj/GR8VWJhCUK5WziNhrsGmOCfmuFyhjHnYXZL4w6HMHmkkE822K09GovUVpJkdQ==", "type": "package", "path": "microsoft.netcore.platforms/2.0.0", "files": [ @@ -540,7 +540,7 @@ ] }, "NETStandard.Library/2.0.0": { - "sha512": "7jnbRU+L08FXKMxqUflxEXtVymWvNOrS8yHgu9s6EM8Anr6T/wIX4nZ08j/u3Asz+tCufp3YVwFSEvFTPYmBPA==", + "sha512": "mXtiDxroMxIxZXC07aA40ZvsjLawxCUpcu8ap/TLE8RzzXaeamhNkinkPLf5JPio4TA2r3anFSpQ14ZmG5QdhA==", "type": "package", "path": "netstandard.library/2.0.0", "files": [ @@ -680,37 +680,35 @@ ] }, "packageFolders": { - "C:\\Users\\rchande\\.nuget\\packages\\": {}, - "C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder": {} + "/Users/piotrp/code/github/piotrpMSFT/cli/.nuget/packages": {}, + "/usr/local/share/dotnet/sdk/NuGetFallbackFolder": {} }, "project": { "version": "1.0.0", "restore": { - "projectUniqueName": "C:\\omnisharp-vscode\\test\\integrationTests\\testAssets\\slnWithCsproj\\src\\app\\app.csproj", + "projectUniqueName": "/Users/piotrp/code/github/piotrpMSFT/omnisharp-vscode/test/integrationTests/testAssets/slnWithCsproj/src/app/app.csproj", "projectName": "app", - "projectPath": "C:\\omnisharp-vscode\\test\\integrationTests\\testAssets\\slnWithCsproj\\src\\app\\app.csproj", - "packagesPath": "C:\\Users\\rchande\\.nuget\\packages\\", - "outputPath": "C:\\omnisharp-vscode\\test\\integrationTests\\testAssets\\slnWithCsproj\\src\\app\\obj\\", + "projectPath": "/Users/piotrp/code/github/piotrpMSFT/omnisharp-vscode/test/integrationTests/testAssets/slnWithCsproj/src/app/app.csproj", + "packagesPath": "/Users/piotrp/code/github/piotrpMSFT/cli/.nuget/packages", + "outputPath": "/Users/piotrp/code/github/piotrpMSFT/omnisharp-vscode/test/integrationTests/testAssets/slnWithCsproj/src/app/obj/", "projectStyle": "PackageReference", "fallbackFolders": [ - "C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder" + "/usr/local/share/dotnet/sdk/NuGetFallbackFolder" ], "configFilePaths": [ - "C:\\Users\\rchande\\AppData\\Roaming\\NuGet\\NuGet.Config", - "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" + "/Users/piotrp/.nuget/NuGet/NuGet.Config" ], "originalTargetFrameworks": [ "netcoreapp2.0" ], "sources": { - "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, "https://api.nuget.org/v3/index.json": {} }, "frameworks": { "netcoreapp2.0": { "projectReferences": { - "C:\\omnisharp-vscode\\test\\integrationTests\\testAssets\\slnWithCsproj\\src\\lib\\lib.csproj": { - "projectPath": "C:\\omnisharp-vscode\\test\\integrationTests\\testAssets\\slnWithCsproj\\src\\lib\\lib.csproj" + "/Users/piotrp/code/github/piotrpMSFT/omnisharp-vscode/test/integrationTests/testAssets/slnWithCsproj/src/lib/lib.csproj": { + "projectPath": "/Users/piotrp/code/github/piotrpMSFT/omnisharp-vscode/test/integrationTests/testAssets/slnWithCsproj/src/lib/lib.csproj" } } } diff --git a/test/integrationTests/testAssets/slnWithCsproj/src/app/sigHelp.cs b/test/integrationTests/testAssets/slnWithCsproj/src/app/sigHelp.cs new file mode 100644 index 000000000..811e90f8c --- /dev/null +++ b/test/integrationTests/testAssets/slnWithCsproj/src/app/sigHelp.cs @@ -0,0 +1,23 @@ +using System; +namespace Test +{ + class sigHelp + { + ///DoWork is some method. + /// Used to indicate status. + /// Used to specify context. + public static void DoWork(int Int1, float Float1, double Double1) + { + } + + public static void noDocMethod() + { + } + + public static void main() + { + DoWork(4, 4.0f, 5.0); + noDocMethod(); + } + } +} \ No newline at end of file diff --git a/test/integrationTests/testAssets/slnWithCsproj/src/lib/obj/lib.csproj.nuget.cache b/test/integrationTests/testAssets/slnWithCsproj/src/lib/obj/lib.csproj.nuget.cache index d81779677..768c86650 100644 --- a/test/integrationTests/testAssets/slnWithCsproj/src/lib/obj/lib.csproj.nuget.cache +++ b/test/integrationTests/testAssets/slnWithCsproj/src/lib/obj/lib.csproj.nuget.cache @@ -1,5 +1,5 @@ { "version": 1, - "dgSpecHash": "kbvvEs1KGLSXdJD3jgPzGuM5fxoluDmpkV5iIiARRbuPC1JuGJj3sxeXG3WPnIzo5mVWZNPFzghIYyyAi1DSLQ==", + "dgSpecHash": "t4DdcVkUL77aJkipLzM05OZ6SGKs+aEGz66aPk7/Vmr/RTjuHhKs7tZvWUxVpiI58vpqwsOdF3OsUYKAOssOlg==", "success": true } \ No newline at end of file diff --git a/test/integrationTests/testAssets/slnWithCsproj/src/lib/obj/lib.csproj.nuget.g.props b/test/integrationTests/testAssets/slnWithCsproj/src/lib/obj/lib.csproj.nuget.g.props index 993845b02..22ffac8d6 100644 --- a/test/integrationTests/testAssets/slnWithCsproj/src/lib/obj/lib.csproj.nuget.g.props +++ b/test/integrationTests/testAssets/slnWithCsproj/src/lib/obj/lib.csproj.nuget.g.props @@ -3,9 +3,9 @@ True NuGet - C:\omnisharp-vscode\test\integrationTests\testAssets\slnWithCsproj\src\lib\obj\project.assets.json - $(UserProfile)\.nuget\packages\ - C:\Users\rchande\.nuget\packages\;C:\Program Files\dotnet\sdk\NuGetFallbackFolder + /Users/piotrp/code/github/piotrpMSFT/omnisharp-vscode/test/integrationTests/testAssets/slnWithCsproj/src/lib/obj/project.assets.json + /Users/piotrp/code/github/piotrpMSFT/cli/.nuget/packages + /Users/piotrp/code/github/piotrpMSFT/cli/.nuget/packages;/usr/local/share/dotnet/sdk/NuGetFallbackFolder PackageReference 4.5.0 diff --git a/test/integrationTests/testAssets/slnWithCsproj/src/lib/obj/lib.csproj.nuget.g.targets b/test/integrationTests/testAssets/slnWithCsproj/src/lib/obj/lib.csproj.nuget.g.targets index a4affc1b5..da1229554 100644 --- a/test/integrationTests/testAssets/slnWithCsproj/src/lib/obj/lib.csproj.nuget.g.targets +++ b/test/integrationTests/testAssets/slnWithCsproj/src/lib/obj/lib.csproj.nuget.g.targets @@ -4,6 +4,6 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - + \ No newline at end of file diff --git a/test/integrationTests/testAssets/slnWithCsproj/src/lib/obj/project.assets.json b/test/integrationTests/testAssets/slnWithCsproj/src/lib/obj/project.assets.json index 7056efafe..02ec8bf7d 100644 --- a/test/integrationTests/testAssets/slnWithCsproj/src/lib/obj/project.assets.json +++ b/test/integrationTests/testAssets/slnWithCsproj/src/lib/obj/project.assets.json @@ -11,7 +11,7 @@ "lib/netstandard1.0/_._": {} } }, - "NETStandard.Library/2.0.0": { + "NETStandard.Library/2.0.1": { "type": "package", "dependencies": { "Microsoft.NETCore.Platforms": "1.1.0" @@ -30,22 +30,22 @@ }, "libraries": { "Microsoft.NETCore.Platforms/1.1.0": { - "sha512": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==", + "sha512": "od/G9mrOomIisMb9OSHFhGi1Xi3aQRQX2hztHd5EJouGD0/95C9FevjukfZny1M455zXhwfpR8/+546vPLMvYg==", "type": "package", "path": "microsoft.netcore.platforms/1.1.0", "files": [ + "Microsoft.NETCore.Platforms.1.1.0.nupkg.sha512", + "Microsoft.NETCore.Platforms.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/netstandard1.0/_._", - "microsoft.netcore.platforms.1.1.0.nupkg.sha512", - "microsoft.netcore.platforms.nuspec", "runtime.json" ] }, - "NETStandard.Library/2.0.0": { - "sha512": "7jnbRU+L08FXKMxqUflxEXtVymWvNOrS8yHgu9s6EM8Anr6T/wIX4nZ08j/u3Asz+tCufp3YVwFSEvFTPYmBPA==", + "NETStandard.Library/2.0.1": { + "sha512": "oA6nwv9MhEKYvLpjZ0ggSpb1g4CQViDVQjLUcDWg598jtvJbpfeP2reqwI1GLW2TbxC/Ml7xL6BBR1HmKPXlTg==", "type": "package", - "path": "netstandard.library/2.0.0", + "path": "netstandard.library/2.0.1", "files": [ "LICENSE.TXT", "THIRD-PARTY-NOTICES.TXT", @@ -166,41 +166,39 @@ "build/netstandard2.0/ref/netstandard.dll", "build/netstandard2.0/ref/netstandard.xml", "lib/netstandard1.0/_._", - "netstandard.library.2.0.0.nupkg.sha512", + "netstandard.library.2.0.1.nupkg.sha512", "netstandard.library.nuspec" ] } }, "projectFileDependencyGroups": { ".NETStandard,Version=v2.0": [ - "NETStandard.Library >= 2.0.0" + "NETStandard.Library >= 2.0.1" ] }, "packageFolders": { - "C:\\Users\\rchande\\.nuget\\packages\\": {}, - "C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder": {} + "/Users/piotrp/code/github/piotrpMSFT/cli/.nuget/packages": {}, + "/usr/local/share/dotnet/sdk/NuGetFallbackFolder": {} }, "project": { "version": "1.0.0", "restore": { - "projectUniqueName": "C:\\omnisharp-vscode\\test\\integrationTests\\testAssets\\slnWithCsproj\\src\\lib\\lib.csproj", + "projectUniqueName": "/Users/piotrp/code/github/piotrpMSFT/omnisharp-vscode/test/integrationTests/testAssets/slnWithCsproj/src/lib/lib.csproj", "projectName": "lib", - "projectPath": "C:\\omnisharp-vscode\\test\\integrationTests\\testAssets\\slnWithCsproj\\src\\lib\\lib.csproj", - "packagesPath": "C:\\Users\\rchande\\.nuget\\packages\\", - "outputPath": "C:\\omnisharp-vscode\\test\\integrationTests\\testAssets\\slnWithCsproj\\src\\lib\\obj\\", + "projectPath": "/Users/piotrp/code/github/piotrpMSFT/omnisharp-vscode/test/integrationTests/testAssets/slnWithCsproj/src/lib/lib.csproj", + "packagesPath": "/Users/piotrp/code/github/piotrpMSFT/cli/.nuget/packages", + "outputPath": "/Users/piotrp/code/github/piotrpMSFT/omnisharp-vscode/test/integrationTests/testAssets/slnWithCsproj/src/lib/obj/", "projectStyle": "PackageReference", "fallbackFolders": [ - "C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder" + "/usr/local/share/dotnet/sdk/NuGetFallbackFolder" ], "configFilePaths": [ - "C:\\Users\\rchande\\AppData\\Roaming\\NuGet\\NuGet.Config", - "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" + "/Users/piotrp/.nuget/NuGet/NuGet.Config" ], "originalTargetFrameworks": [ "netstandard2.0" ], "sources": { - "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, "https://api.nuget.org/v3/index.json": {} }, "frameworks": { @@ -220,7 +218,7 @@ "NETStandard.Library": { "suppressParent": "All", "target": "Package", - "version": "[2.0.0, )", + "version": "[2.0.1, )", "autoReferenced": true } }, diff --git a/test/integrationTests/testAssets/slnWithCsproj/test/obj/project.assets.json b/test/integrationTests/testAssets/slnWithCsproj/test/obj/project.assets.json index 2af572aa4..9dc342229 100644 --- a/test/integrationTests/testAssets/slnWithCsproj/test/obj/project.assets.json +++ b/test/integrationTests/testAssets/slnWithCsproj/test/obj/project.assets.json @@ -1721,7 +1721,7 @@ ] }, "Microsoft.DotNet.PlatformAbstractions/1.1.0": { - "sha512": "Bl6KYfbFSIW3QIRHAp931iR5h01qHjKghdpAtncwbzNUs0+IUZ+XfwkIU0sQsR33ufGvi3u4dZMIYYFysjpHAA==", + "sha512": "9C69QwEGETiA6iNVrtna3UejidfNE/pgk3Qh4VxCuxGOJS9BDQdFrRv0qCDzvXrU281b8BZZrsmw5+Uey8lQGg==", "type": "package", "path": "microsoft.dotnet.platformabstractions/1.1.0", "files": [ @@ -1732,7 +1732,7 @@ ] }, "Microsoft.Extensions.DependencyModel/1.1.0": { - "sha512": "TG7dJ8GY1Myz9lZ8DJL4i6D05ncJQBi5CjBMXMdJ4edKxaW+vP2DndDd1jJabdMdmVRdGrvybzqkB+A6Df7eDw==", + "sha512": "80qr1itOqm2TTrQscA/p9T35eFEU2yO0jGlwxEfFpnxlIcvh0n9mxGkWyUp5pp2bvh7EfUz8w0OroIZxZ1fQ7Q==", "type": "package", "path": "microsoft.extensions.dependencymodel/1.1.0", "files": [ @@ -1758,7 +1758,7 @@ ] }, "Microsoft.NETCore.App/2.0.0": { - "sha512": "/mzXF+UtZef+VpzzN88EpvFq5U6z4rj54ZMq/J968H6pcvyLOmcupmTRpJ3CJm8ILoCGh9WI7qpDdiKtuzswrQ==", + "sha512": "u30D3okjSE34FaNeF45fQn0pEe4HTfd5jIKpyun0DD9TK7G8WC4/xLn0ZjbHT/nvWznayTl36J2X2rT8tjx+Dw==", "type": "package", "path": "microsoft.netcore.app/2.0.0", "files": [ @@ -2036,7 +2036,7 @@ ] }, "Microsoft.NETCore.DotNetAppHost/2.0.0": { - "sha512": "L4GGkcI/Mxl8PKLRpFdGmLb5oI8sGIR05bDTGkzCoamAjdUl1Zhkov2swjEsZvKYT8kkdiz39LtwyGYuCJxm1A==", + "sha512": "YPFCzBe0Rh1wMZcJvbKfDMC2ARi7vPeeTcDcsf2m91Bs6NorZHiCQWznBcZqxnyq9WvkHDpgrS2yNiD5NkvLLQ==", "type": "package", "path": "microsoft.netcore.dotnetapphost/2.0.0", "files": [ @@ -2072,7 +2072,7 @@ ] }, "Microsoft.NETCore.Platforms/2.0.0": { - "sha512": "VdLJOCXhZaEMY7Hm2GKiULmn7IEPFE4XC5LPSfBVCUIA8YLZVh846gtfBJalsPQF2PlzdD7ecX7DZEulJ402ZQ==", + "sha512": "uh69u8rko8LLHnhuBkDxIpsj/GR8VWJhCUK5WziNhrsGmOCfmuFyhjHnYXZL4w6HMHmkkE822K09GovUVpJkdQ==", "type": "package", "path": "microsoft.netcore.platforms/2.0.0", "files": [ @@ -2087,15 +2087,15 @@ ] }, "Microsoft.NETCore.Targets/1.1.0": { - "sha512": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg==", + "sha512": "u/lF4I9kZAuAF8+6QglH4th8+x8P+tTiEOnSmmPUT94LfeWY5OJ+DlKpU2rwL42Ewoq8g1XKDhfaUR2J+uJ79g==", "type": "package", "path": "microsoft.netcore.targets/1.1.0", "files": [ + "Microsoft.NETCore.Targets.1.1.0.nupkg.sha512", + "Microsoft.NETCore.Targets.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/netstandard1.0/_._", - "microsoft.netcore.targets.1.1.0.nupkg.sha512", - "microsoft.netcore.targets.nuspec", "runtime.json" ] }, @@ -2222,10 +2222,12 @@ ] }, "Microsoft.Win32.Primitives/4.3.0": { - "sha512": "9ZQKCWxH7Ijp9BfahvL2Zyf1cJIk8XYLF6Yjzr2yi0b2cOut/HQ31qf1ThHAgCc3WiZMdnWcfJCgN82/0UunxA==", + "sha512": "pYyB3Pg/rjEe0KqcOpphXccz25lg5nb7jd7ovmgVPQQO3vVTn5YDzqVcQ1kpvM+Y/u9pTzcTxEghYBXvucVzTw==", "type": "package", "path": "microsoft.win32.primitives/4.3.0", "files": [ + "Microsoft.Win32.Primitives.4.3.0.nupkg.sha512", + "Microsoft.Win32.Primitives.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -2235,8 +2237,6 @@ "lib/xamarinmac20/_._", "lib/xamarintvos10/_._", "lib/xamarinwatchos10/_._", - "microsoft.win32.primitives.4.3.0.nupkg.sha512", - "microsoft.win32.primitives.nuspec", "ref/MonoAndroid10/_._", "ref/MonoTouch10/_._", "ref/net46/Microsoft.Win32.Primitives.dll", @@ -2258,15 +2258,15 @@ ] }, "Microsoft.Win32.Registry/4.3.0": { - "sha512": "Lw1/VwLH1yxz6SfFEjVRCN0pnflLEsWgnV4qsdJ512/HhTwnKXUG+zDQ4yTO3K/EJQemGoNaBHX5InISNKTzUQ==", + "sha512": "qMHGbnpj+Law3LGaj+YvhhuWvb4n0Lt3FtcFJ/yze6DRijZZWHOr16Ei6o6wQkn2P8REa+PZ9k/Q73okge9XaQ==", "type": "package", "path": "microsoft.win32.registry/4.3.0", "files": [ + "Microsoft.Win32.Registry.4.3.0.nupkg.sha512", + "Microsoft.Win32.Registry.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/net46/Microsoft.Win32.Registry.dll", - "microsoft.win32.registry.4.3.0.nupkg.sha512", - "microsoft.win32.registry.nuspec", "ref/net46/Microsoft.Win32.Registry.dll", "ref/netstandard1.3/Microsoft.Win32.Registry.dll", "ref/netstandard1.3/Microsoft.Win32.Registry.xml", @@ -2286,7 +2286,7 @@ ] }, "NETStandard.Library/2.0.0": { - "sha512": "7jnbRU+L08FXKMxqUflxEXtVymWvNOrS8yHgu9s6EM8Anr6T/wIX4nZ08j/u3Asz+tCufp3YVwFSEvFTPYmBPA==", + "sha512": "mXtiDxroMxIxZXC07aA40ZvsjLawxCUpcu8ap/TLE8RzzXaeamhNkinkPLf5JPio4TA2r3anFSpQ14ZmG5QdhA==", "type": "package", "path": "netstandard.library/2.0.0", "files": [ @@ -2438,22 +2438,24 @@ ] }, "runtime.native.System/4.3.0": { - "sha512": "c/qWt2LieNZIj1jGnVNsE2Kl23Ya2aSTBuXMD6V7k9KWr6l16Tqdwq+hJScEpWER9753NWC8h96PaVNY5Ld7Jw==", + "sha512": "catARO44mcjyGUufOxanvv5eXDg06ewDGVR6VaViO3aPbiBh6bRs+ESwmrO01nRRyXBieLg12wX75MexeRZ7xA==", "type": "package", "path": "runtime.native.system/4.3.0", "files": [ "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/netstandard1.0/_._", - "runtime.native.system.4.3.0.nupkg.sha512", - "runtime.native.system.nuspec" + "runtime.native.System.4.3.0.nupkg.sha512", + "runtime.native.System.nuspec" ] }, "System.AppContext/4.1.0": { - "sha512": "3QjO4jNV7PdKkmQAVp9atA+usVnKRwI3Kx1nMwJ93T0LcQfx7pKAYk0nKz5wn1oP5iqlhZuy6RXOFdhr7rDwow==", + "sha512": "9y0N8ZlBy8ikxXsumMHsoV3TrtozVecbcZ22JyVBWDj71YixZL7fIjXRaMSntzlcks3ueSqpZaCs2KSKtU/pTQ==", "type": "package", "path": "system.appcontext/4.1.0", "files": [ + "System.AppContext.4.1.0.nupkg.sha512", + "System.AppContext.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -2497,16 +2499,16 @@ "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", "ref/xamarinwatchos10/_._", - "runtimes/aot/lib/netcore50/System.AppContext.dll", - "system.appcontext.4.1.0.nupkg.sha512", - "system.appcontext.nuspec" + "runtimes/aot/lib/netcore50/System.AppContext.dll" ] }, "System.Collections/4.3.0": { - "sha512": "3Dcj85/TBdVpL5Zr+gEEBUuFe2icOnLalmEh9hfck1PTYbbyWuZgh4fmm2ysCLTrqLQw6t3TgTyJ+VLp+Qb+Lw==", + "sha512": "YQ1B5vE49TzczJ0mik86Ypvb1JJrje+Pz4iYv1hYr2AMEOOT1oPds+KwjJ3kSjJlrxehyvw2ioa7L6jpprqihQ==", "type": "package", "path": "system.collections/4.3.0", "files": [ + "System.Collections.4.3.0.nupkg.sha512", + "System.Collections.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -2563,16 +2565,16 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.collections.4.3.0.nupkg.sha512", - "system.collections.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.Collections.Concurrent/4.3.0": { - "sha512": "ztl69Xp0Y/UXCL+3v3tEU+lIy+bvjKNUmopn1wep/a291pVPK7dxBd6T7WnlQqRog+d1a/hSsgRsmFnIBKTPLQ==", + "sha512": "5gyplJVTtZ4jXBAgxR6AR6XNVWAWg9rWxOw9X75q5AAHtYJB/4Su+zU4wCH+Bru7lTbqsDvMzbi3vz5k0rSweg==", "type": "package", "path": "system.collections.concurrent/4.3.0", "files": [ + "System.Collections.Concurrent.4.3.0.nupkg.sha512", + "System.Collections.Concurrent.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -2629,9 +2631,7 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.collections.concurrent.4.3.0.nupkg.sha512", - "system.collections.concurrent.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.Collections.Immutable/1.2.0": { @@ -2650,7 +2650,7 @@ ] }, "System.Collections.NonGeneric/4.3.0": { - "sha512": "prtjIEMhGUnQq6RnPEYLpFt8AtLbp9yq2zxOSrY7KJJZrw25Fi97IzBqY7iqssbM61Ek5b8f3MG/sG1N2sN5KA==", + "sha512": "1OqrwVzDNV6CkuaE5j/DqGeYLc6MTjdW+rGfpVVgfT4IRrvGzBsbzbClraI/47m3WgOxC5m10R6kdvxkjxplcQ==", "type": "package", "path": "system.collections.nongeneric/4.3.0", "files": [ @@ -2687,7 +2687,7 @@ ] }, "System.Collections.Specialized/4.3.0": { - "sha512": "Epx8PoVZR0iuOnJJDzp7pWvdfMMOAvpUo95pC4ScH2mJuXkKA2Y4aR3cG9qt2klHgSons1WFh4kcGW7cSXvrxg==", + "sha512": "GWG1a+Wbi1ikpYZ99Fq4tNfqG7IhsDnDkNVzf5kBCDuT/cRjUzkQKq2xfHbqjow/mc8WV+M9yyGti95tiSpEtg==", "type": "package", "path": "system.collections.specialized/4.3.0", "files": [ @@ -2724,10 +2724,12 @@ ] }, "System.ComponentModel/4.3.0": { - "sha512": "VyGn1jGRZVfxnh8EdvDCi71v3bMXrsu8aYJOwoV7SNDLVhiEqwP86pPMyRGsDsxhXAm2b3o9OIqeETfN5qfezw==", + "sha512": "ydf+TG2BLEGVIuV5C8W8GC2lujn7vXycP/fcEJXGeaVsdpkQDDSmk2KyMIUT/FDKvUYV4ADhk895+YK8un1JHA==", "type": "package", "path": "system.componentmodel/4.3.0", "files": [ + "System.ComponentModel.4.3.0.nupkg.sha512", + "System.ComponentModel.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -2775,9 +2777,7 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.componentmodel.4.3.0.nupkg.sha512", - "system.componentmodel.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.ComponentModel.EventBasedAsync/4.3.0": { @@ -2849,7 +2849,7 @@ ] }, "System.ComponentModel.Primitives/4.3.0": { - "sha512": "j8GUkCpM8V4d4vhLIIoBLGey2Z5bCkMVNjEZseyAlm4n5arcsJOeI3zkUP+zvZgzsbLTYh4lYeP/ZD/gdIAPrw==", + "sha512": "a6qryXisxsZy9/+HN/dlYvOPmeg6/cK7IF8zCMDzB+ceOoFMKOeUtIZm/AtuT8YDBfnqgzSt8CaSEq0ONGhowA==", "type": "package", "path": "system.componentmodel.primitives/4.3.0", "files": [ @@ -2886,7 +2886,7 @@ ] }, "System.ComponentModel.TypeConverter/4.3.0": { - "sha512": "16pQ6P+EdhcXzPiEK4kbA953Fu0MNG2ovxTZU81/qsCd1zPRsKc3uif5NgvllCY598k6bI0KUyKW8fanlfaDQg==", + "sha512": "Fiv+edg14gLWBuXclCXQzPDzgcPnhfZHR/AsURM5d76CC/yxQykcDPJQixlUqDTa72vpEtzx5uJyF9CKxCQ2EQ==", "type": "package", "path": "system.componentmodel.typeconverter/4.3.0", "files": [ @@ -2937,10 +2937,12 @@ ] }, "System.Diagnostics.Debug/4.3.0": { - "sha512": "ZUhUOdqmaG5Jk3Xdb8xi5kIyQYAA4PnTNlHx1mu9ZY3qv4ELIdKbnL/akbGaKi2RnNUWaZsAs31rvzFdewTj2g==", + "sha512": "3SgIFFKoOdlKBLklHi3mfVhHKvZaHx+MGoh5liGb9BxZg6+YBlwxmsZ8la0ubCWL3QdPsMy0VEds5nTmvLpmvQ==", "type": "package", "path": "system.diagnostics.debug/4.3.0", "files": [ + "System.Diagnostics.Debug.4.3.0.nupkg.sha512", + "System.Diagnostics.Debug.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -2997,16 +2999,16 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.diagnostics.debug.4.3.0.nupkg.sha512", - "system.diagnostics.debug.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.Diagnostics.Process/4.3.0": { - "sha512": "J0wOX07+QASQblsfxmIMFc9Iq7KTXYL3zs2G/Xc704Ylv3NpuVdo6gij6V3PGiptTxqsK0K7CdXenRvKUnkA2g==", + "sha512": "8fR+b8hi08MFrbA+XkBO6FVlIpoDl8MVxSWcKKBtl9CvLQcQvaN7jUny1Pmy64T/h92XKyU0piTEyxdM7XeCCw==", "type": "package", "path": "system.diagnostics.process/4.3.0", "files": [ + "System.Diagnostics.Process.4.3.0.nupkg.sha512", + "System.Diagnostics.Process.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -3052,9 +3054,7 @@ "runtimes/win/lib/net46/System.Diagnostics.Process.dll", "runtimes/win/lib/net461/System.Diagnostics.Process.dll", "runtimes/win/lib/netstandard1.4/System.Diagnostics.Process.dll", - "runtimes/win7/lib/netcore50/_._", - "system.diagnostics.process.4.3.0.nupkg.sha512", - "system.diagnostics.process.nuspec" + "runtimes/win7/lib/netcore50/_._" ] }, "System.Diagnostics.TextWriterTraceListener/4.3.0": { @@ -3095,10 +3095,12 @@ ] }, "System.Diagnostics.Tools/4.3.0": { - "sha512": "UUvkJfSYJMM6x527dJg2VyWPSRqIVB0Z7dbjHst1zmwTXz5CcXSYJFWRpuigfbO1Lf7yfZiIaEUesfnl/g5EyA==", + "sha512": "Vwc6LFQtqsOY0cv6PuUE/hwZa2QpN3b4fj/60KlyISaoQ+qqHWMb88hWPi6wYKgT9MzXfB6+X2Hbu0vVP3Endg==", "type": "package", "path": "system.diagnostics.tools/4.3.0", "files": [ + "System.Diagnostics.Tools.4.3.0.nupkg.sha512", + "System.Diagnostics.Tools.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -3144,9 +3146,7 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.diagnostics.tools.4.3.0.nupkg.sha512", - "system.diagnostics.tools.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.Diagnostics.TraceSource/4.3.0": { @@ -3189,10 +3189,12 @@ ] }, "System.Diagnostics.Tracing/4.3.0": { - "sha512": "rswfv0f/Cqkh78rA5S8eN8Neocz234+emGCtTF3lxPY96F+mmmUen6tbn0glN6PMvlKQb9bPAY5e9u7fgPTkKw==", + "sha512": "f9BrdsWCbQtt+DczMElDeELfBbj/2NGvODIQtzJdSfEed8dw40QYMAh0h10o0WkaJHBmiM4lpP7k72HPKtkxAg==", "type": "package", "path": "system.diagnostics.tracing/4.3.0", "files": [ + "System.Diagnostics.Tracing.4.3.0.nupkg.sha512", + "System.Diagnostics.Tracing.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -3271,9 +3273,7 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.diagnostics.tracing.4.3.0.nupkg.sha512", - "system.diagnostics.tracing.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.Dynamic.Runtime/4.0.11": { @@ -3346,10 +3346,12 @@ ] }, "System.Globalization/4.3.0": { - "sha512": "kYdVd2f2PAdFGblzFswE4hkNANJBKRmsfa2X5LG2AcWE1c7/4t0pYae1L8vfZ5xvE2nK/R9JprtToA61OSHWIg==", + "sha512": "rBOamFl6ZyhGAe1LXk7zJfZedRGU4udVVxOQGv5I3Bk5kkx1kSVc8qNyB1sLbDj3YBy8S2ZjpGcZRcsiSHKyhA==", "type": "package", "path": "system.globalization/4.3.0", "files": [ + "System.Globalization.4.3.0.nupkg.sha512", + "System.Globalization.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -3406,16 +3408,16 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.globalization.4.3.0.nupkg.sha512", - "system.globalization.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.Globalization.Extensions/4.3.0": { - "sha512": "FhKmdR6MPG+pxow6wGtNAWdZh7noIOpdD5TwQ3CprzgIE1bBBoim0vbR1+AWsWjQmU7zXHgQo4TWSP6lCeiWcQ==", + "sha512": "YtUH4Fkd8FN2lLfbai8RIJbL5OSMU1Ihyn0Q9+4Dnu26X7JyQcrqF4I7rLR1+CkkVjItjGEt1z0WPqv7WPx+yw==", "type": "package", "path": "system.globalization.extensions/4.3.0", "files": [ + "System.Globalization.Extensions.4.3.0.nupkg.sha512", + "System.Globalization.Extensions.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -3445,16 +3447,16 @@ "ref/xamarinwatchos10/_._", "runtimes/unix/lib/netstandard1.3/System.Globalization.Extensions.dll", "runtimes/win/lib/net46/System.Globalization.Extensions.dll", - "runtimes/win/lib/netstandard1.3/System.Globalization.Extensions.dll", - "system.globalization.extensions.4.3.0.nupkg.sha512", - "system.globalization.extensions.nuspec" + "runtimes/win/lib/netstandard1.3/System.Globalization.Extensions.dll" ] }, "System.IO/4.3.0": { - "sha512": "3qjaHvxQPDpSOYICjUoTsmoq5u6QJAFRUITgeT/4gqkF1bajbSmb1kwSxEA8AHlofqgcKJcM8udgieRNhaJ5Cg==", + "sha512": "mIdLe418rsu39bT8BCRT/MSF5kA478q8FEKK8RwJdr3F6bz7dqMKjW9i0mIGBH1gw+Jg6y4TcjDgaOVYruNTBQ==", "type": "package", "path": "system.io/4.3.0", "files": [ + "System.IO.4.3.0.nupkg.sha512", + "System.IO.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -3524,16 +3526,16 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.io.4.3.0.nupkg.sha512", - "system.io.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.IO.FileSystem/4.3.0": { - "sha512": "3wEMARTnuio+ulnvi+hkRNROYwa1kylvYahhcLk4HSoVdl+xxTFVeVlYOfLwrDPImGls0mDqbMhrza8qnWPTdA==", + "sha512": "XNIxzZ3O6QM7Ddte6ix0s05KtxOtKZPsbRArwxtjW7ESDWDZWe6iRLieOAp6hkdEcKN+BbQdCTy5lUWldaorLA==", "type": "package", "path": "system.io.filesystem/4.3.0", "files": [ + "System.IO.FileSystem.4.3.0.nupkg.sha512", + "System.IO.FileSystem.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -3560,16 +3562,16 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.io.filesystem.4.3.0.nupkg.sha512", - "system.io.filesystem.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.IO.FileSystem.Primitives/4.3.0": { - "sha512": "6QOb2XFLch7bEc4lIcJH49nJN2HV+OC3fHDgsLVsBVBk3Y4hFAnOBGzJ2lUu7CyDDFo9IBWkSsnbkT6IBwwiMw==", + "sha512": "NOLqpMi0VJMbfLBnqjPbHNbgr5OM/BT8EBV5W1OAqWl08ICRtS2c4d0poCEjtcIoa+ZP3EuI1jBhrbUyX3rzvQ==", "type": "package", "path": "system.io.filesystem.primitives/4.3.0", "files": [ + "System.IO.FileSystem.Primitives.4.3.0.nupkg.sha512", + "System.IO.FileSystem.Primitives.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -3597,16 +3599,16 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.io.filesystem.primitives.4.3.0.nupkg.sha512", - "system.io.filesystem.primitives.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.Linq/4.3.0": { - "sha512": "5DbqIUpsDp0dFftytzuMmc0oeMdQwjcP/EWxsksIz/w1TcFRkZ3yKKz0PqiYFMmEwPSWw+qNVqD7PJ889JzHbw==", + "sha512": "zCipD1BC2DA18yZ9Qe6lBvwwbD2bN+PsOLB948sXqj00aS6UCWhd7a9tmL9sZ3hX0aWx/YZ0X4jqNyM3iNy+8Q==", "type": "package", "path": "system.linq/4.3.0", "files": [ + "System.Linq.4.3.0.nupkg.sha512", + "System.Linq.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -3667,9 +3669,7 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.linq.4.3.0.nupkg.sha512", - "system.linq.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.Linq.Expressions/4.1.0": { @@ -3837,10 +3837,12 @@ ] }, "System.Reflection/4.3.0": { - "sha512": "KMiAFoW7MfJGa9nDFNcfu+FpEdiHpWgTcS2HdMpDvt9saK3y/G4GwprPyzqjFH9NTaGPQeWNHU+iDlDILj96aQ==", + "sha512": "gGamr1E4EEPebmJ97PzWvrShxs84XekbUo/Y6GmWV5QFSCPtxHlrpfhA60RYK1xdp/UUk7Hfnwv5JgYHdriVsA==", "type": "package", "path": "system.reflection/4.3.0", "files": [ + "System.Reflection.4.3.0.nupkg.sha512", + "System.Reflection.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -3910,16 +3912,16 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.reflection.4.3.0.nupkg.sha512", - "system.reflection.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.Reflection.Emit/4.3.0": { - "sha512": "228FG0jLcIwTVJyz8CLFKueVqQK36ANazUManGaJHkO0icjiIypKW7YLWLIWahyIkdh5M7mV2dJepllLyA1SKg==", + "sha512": "+iMkBQSDryRUD4pZLYA/1GE635+Vcq0yzK5XmcoE2PIC+zPrQeQ3g8jL3ObGyMa92yW4il0SdGBJG594aRHoEQ==", "type": "package", "path": "system.reflection.emit/4.3.0", "files": [ + "System.Reflection.Emit.4.3.0.nupkg.sha512", + "System.Reflection.Emit.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -3944,16 +3946,16 @@ "ref/netstandard1.1/ru/System.Reflection.Emit.xml", "ref/netstandard1.1/zh-hans/System.Reflection.Emit.xml", "ref/netstandard1.1/zh-hant/System.Reflection.Emit.xml", - "ref/xamarinmac20/_._", - "system.reflection.emit.4.3.0.nupkg.sha512", - "system.reflection.emit.nuspec" + "ref/xamarinmac20/_._" ] }, "System.Reflection.Emit.ILGeneration/4.3.0": { - "sha512": "59tBslAk9733NXLrUJrwNZEzbMAcu8k344OYo+wfSVygcgZ9lgBdGIzH/nrg3LYhXceynyvTc8t5/GD4Ri0/ng==", + "sha512": "hWLhTM+4nHfwE2fWuG6a7zx4HsDuMHsy9yghS6lF28aVVfmdYJQzVpW0zyr2XgSikWpDQaLFXUXn5KFCHQIc/A==", "type": "package", "path": "system.reflection.emit.ilgeneration/4.3.0", "files": [ + "System.Reflection.Emit.ILGeneration.4.3.0.nupkg.sha512", + "System.Reflection.Emit.ILGeneration.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -3987,16 +3989,16 @@ "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", "ref/xamarinwatchos10/_._", - "runtimes/aot/lib/netcore50/_._", - "system.reflection.emit.ilgeneration.4.3.0.nupkg.sha512", - "system.reflection.emit.ilgeneration.nuspec" + "runtimes/aot/lib/netcore50/_._" ] }, "System.Reflection.Emit.Lightweight/4.3.0": { - "sha512": "oadVHGSMsTmZsAF864QYN1t1QzZjIcuKU3l2S9cZOwDdDueNTrqq1yRj7koFfIGEnKpt6NjpL3rOzRhs4ryOgA==", + "sha512": "Z/CjAbXzacdDtM68j63sNYBdvFmw7xa5rTHaIosxOkqCsZtx9NljbXPUH1uZP7CSYaPUtCTqWoGMIRmfgzF28g==", "type": "package", "path": "system.reflection.emit.lightweight/4.3.0", "files": [ + "System.Reflection.Emit.Lightweight.4.3.0.nupkg.sha512", + "System.Reflection.Emit.Lightweight.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -4030,16 +4032,16 @@ "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", "ref/xamarinwatchos10/_._", - "runtimes/aot/lib/netcore50/_._", - "system.reflection.emit.lightweight.4.3.0.nupkg.sha512", - "system.reflection.emit.lightweight.nuspec" + "runtimes/aot/lib/netcore50/_._" ] }, "System.Reflection.Extensions/4.3.0": { - "sha512": "rJkrJD3kBI5B712aRu4DpSIiHRtr6QlfZSQsb0hYHrDCZORXCFjQfoipo2LaMUHoT9i1B7j7MnfaEKWDFmFQNQ==", + "sha512": "MDfXYjOpzBgjkTs9Qn8bKNwJPduzuKiQsPIASQXFCQdZ4N6cT+rcOzAg09GHqafBwBtD4Ie2/FIxrstx+x5BFA==", "type": "package", "path": "system.reflection.extensions/4.3.0", "files": [ + "System.Reflection.Extensions.4.3.0.nupkg.sha512", + "System.Reflection.Extensions.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -4085,9 +4087,7 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.reflection.extensions.4.3.0.nupkg.sha512", - "system.reflection.extensions.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.Reflection.Metadata/1.3.0": { @@ -4106,10 +4106,12 @@ ] }, "System.Reflection.Primitives/4.3.0": { - "sha512": "5RXItQz5As4xN2/YUDxdpsEkMhvw3e6aNveFXUn4Hl/udNTCNhnKp8lT9fnc3MhvGKh1baak5CovpuQUXHAlIA==", + "sha512": "cC3LNSN1O4HzaICX2X6E+5SzA8frBifE/P22OOJ2ZDcmackDnIEa/JbbS+ZJ17LO4rVMjNh2I9hnnmqyOtRlSA==", "type": "package", "path": "system.reflection.primitives/4.3.0", "files": [ + "System.Reflection.Primitives.4.3.0.nupkg.sha512", + "System.Reflection.Primitives.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -4155,16 +4157,16 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.reflection.primitives.4.3.0.nupkg.sha512", - "system.reflection.primitives.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.Reflection.TypeExtensions/4.3.0": { - "sha512": "7u6ulLcZbyxB5Gq0nMkQttcdBTx57ibzw+4IOXEfR+sXYQoHvjW5LTLyNr8O22UIMrqYbchJQJnos4eooYzYJA==", + "sha512": "3AxQaxLqVAJSDSEeGPVNX9TNX+Gx0/uUdtUrwSwGnVnMFXOvJM5DkARwA9sg5EuMr5zW/uOWvGuMlRRikFCoaw==", "type": "package", "path": "system.reflection.typeextensions/4.3.0", "files": [ + "System.Reflection.TypeExtensions.4.3.0.nupkg.sha512", + "System.Reflection.TypeExtensions.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -4207,16 +4209,16 @@ "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", "ref/xamarinwatchos10/_._", - "runtimes/aot/lib/netcore50/System.Reflection.TypeExtensions.dll", - "system.reflection.typeextensions.4.3.0.nupkg.sha512", - "system.reflection.typeextensions.nuspec" + "runtimes/aot/lib/netcore50/System.Reflection.TypeExtensions.dll" ] }, "System.Resources.ResourceManager/4.3.0": { - "sha512": "/zrcPkkWdZmI4F92gL/TPumP98AVDu/Wxr3CSJGQQ+XN6wbRZcyfSKVoPo17ilb3iOr0cCRqJInGwNMolqhS8A==", + "sha512": "uv2LeuHh1Egcny0vUeIPeAg7LiqHWfmcLfBpc4cdonWbdM8P59oFkfj8Z+km8US0uOzIfS7unVSboNK/aTN/XQ==", "type": "package", "path": "system.resources.resourcemanager/4.3.0", "files": [ + "System.Resources.ResourceManager.4.3.0.nupkg.sha512", + "System.Resources.ResourceManager.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -4262,16 +4264,16 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.resources.resourcemanager.4.3.0.nupkg.sha512", - "system.resources.resourcemanager.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.Runtime/4.3.0": { - "sha512": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==", + "sha512": "x/uKk+KOWUH4Ywuw4vAVdBa0ToVF6HCy9gCG+loWNZZMCWGvEElnPAAD/NTXJXCApWEa6lNe2Jx7IQyahRX2ZA==", "type": "package", "path": "system.runtime/4.3.0", "files": [ + "System.Runtime.4.3.0.nupkg.sha512", + "System.Runtime.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -4352,16 +4354,16 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.runtime.4.3.0.nupkg.sha512", - "system.runtime.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.Runtime.Extensions/4.3.0": { - "sha512": "guW0uK0fn5fcJJ1tJVXYd7/1h5F+pea1r7FLSOz/f8vPEqbR2ZAknuRDvTQ8PzAilDveOxNjSfr0CHfIQfFk8g==", + "sha512": "kMwxdAkAoUCrOzV9+eoo6c9ReRRTU4GJ4uCW/U41CnO6Dau2G9906wQgq87ecsgKi1zPsWhS0MhPNtv+zOKXVg==", "type": "package", "path": "system.runtime.extensions/4.3.0", "files": [ + "System.Runtime.Extensions.4.3.0.nupkg.sha512", + "System.Runtime.Extensions.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -4431,16 +4433,16 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.runtime.extensions.4.3.0.nupkg.sha512", - "system.runtime.extensions.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.Runtime.Handles/4.3.0": { - "sha512": "OKiSUN7DmTWeYb3l51A7EYaeNMnvxwE249YtZz7yooT4gOZhmTjIn48KgSsw2k2lYdLgTKNJw/ZIfSElwDRVgg==", + "sha512": "BHcVBSdAhhFFiXbapRT3kYfGG2cGpTEVcSQWpjPEL1KlKhxz99gpKsAzFdQA4wxLI2OceEhsfcRnhGFoL1YlcA==", "type": "package", "path": "system.runtime.handles/4.3.0", "files": [ + "System.Runtime.Handles.4.3.0.nupkg.sha512", + "System.Runtime.Handles.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -4467,16 +4469,16 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.runtime.handles.4.3.0.nupkg.sha512", - "system.runtime.handles.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.Runtime.InteropServices/4.3.0": { - "sha512": "uv1ynXqiMK8mp1GM3jDqPCFN66eJ5w5XNomaK2XD+TuCroNTLFGeZ+WCmBMcBDyTFKou3P6cR6J/QsaqDp7fGQ==", + "sha512": "mLmD/9/pWxDGrpCU68r5hgBKGw8LXWOGvUcXl7YYm4EQMWhNHUuQuItA7uIX5MtlCK0z/0rLMI1lzdnqTnVf7Q==", "type": "package", "path": "system.runtime.interopservices/4.3.0", "files": [ + "System.Runtime.InteropServices.4.3.0.nupkg.sha512", + "System.Runtime.InteropServices.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -4558,16 +4560,16 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.runtime.interopservices.4.3.0.nupkg.sha512", - "system.runtime.interopservices.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.Runtime.InteropServices.RuntimeInformation/4.3.0": { - "sha512": "cbz4YJMqRDR7oLeMRbdYv7mYzc++17lNhScCX0goO2XpGWdvAt60CGN+FHdePUEHCe/Jy9jUlvNAiNdM+7jsOw==", + "sha512": "FtJ8+tL3wuisy+xGToxUZc1jUmK/EOmYchv/NYwDr0vKj02ySyEtvHB15V3H54rcPNmL5/TAUZct8V5kPyHCXA==", "type": "package", "path": "system.runtime.interopservices.runtimeinformation/4.3.0", "files": [ + "System.Runtime.InteropServices.RuntimeInformation.4.3.0.nupkg.sha512", + "System.Runtime.InteropServices.RuntimeInformation.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -4591,16 +4593,16 @@ "runtimes/unix/lib/netstandard1.1/System.Runtime.InteropServices.RuntimeInformation.dll", "runtimes/win/lib/net45/System.Runtime.InteropServices.RuntimeInformation.dll", "runtimes/win/lib/netcore50/System.Runtime.InteropServices.RuntimeInformation.dll", - "runtimes/win/lib/netstandard1.1/System.Runtime.InteropServices.RuntimeInformation.dll", - "system.runtime.interopservices.runtimeinformation.4.3.0.nupkg.sha512", - "system.runtime.interopservices.runtimeinformation.nuspec" + "runtimes/win/lib/netstandard1.1/System.Runtime.InteropServices.RuntimeInformation.dll" ] }, "System.Runtime.Loader/4.3.0": { - "sha512": "DHMaRn8D8YCK2GG2pw+UzNxn/OHVfaWx7OTLBD/hPegHZZgcZh3H6seWegrC4BYwsfuGrywIuT+MQs+rPqRLTQ==", + "sha512": "6sy0Im/gMm+y1zDgRYM+WB2mEEdw1Z6INUAsNnCfOi7HYWRaSAQeQkYNHqOq2QrDBYHt3yY8xb5OzAuRIhPxtg==", "type": "package", "path": "system.runtime.loader/4.3.0", "files": [ + "System.Runtime.Loader.4.3.0.nupkg.sha512", + "System.Runtime.Loader.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -4621,9 +4623,7 @@ "ref/netstandard1.5/ko/System.Runtime.Loader.xml", "ref/netstandard1.5/ru/System.Runtime.Loader.xml", "ref/netstandard1.5/zh-hans/System.Runtime.Loader.xml", - "ref/netstandard1.5/zh-hant/System.Runtime.Loader.xml", - "system.runtime.loader.4.3.0.nupkg.sha512", - "system.runtime.loader.nuspec" + "ref/netstandard1.5/zh-hant/System.Runtime.Loader.xml" ] }, "System.Runtime.Serialization.Json/4.3.0": { @@ -4755,10 +4755,12 @@ ] }, "System.Text.Encoding/4.3.0": { - "sha512": "BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==", + "sha512": "4Ov0HprPtGIGpK8pVIApj5PKWi2PTD2oJ9/UnB75+Hxu+Wzwwxtft48mY7ssnl5ZyArsGAP7P9rwNezuaj7TFg==", "type": "package", "path": "system.text.encoding/4.3.0", "files": [ + "System.Text.Encoding.4.3.0.nupkg.sha512", + "System.Text.Encoding.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -4815,16 +4817,16 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.text.encoding.4.3.0.nupkg.sha512", - "system.text.encoding.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.Text.Encoding.Extensions/4.3.0": { - "sha512": "YVMK0Bt/A43RmwizJoZ22ei2nmrhobgeiYwFzC4YAN+nue8RF6djXDMog0UCn+brerQoYVyaS+ghy9P/MUVcmw==", + "sha512": "54HDNiawKkxkbFR9Jgf/PK1kgRaX/6XEH1Mdj57d+z2iqS2qfXUiof2eOyU37z/5UI5uUxifKiQbYISUiX3EXg==", "type": "package", "path": "system.text.encoding.extensions/4.3.0", "files": [ + "System.Text.Encoding.Extensions.4.3.0.nupkg.sha512", + "System.Text.Encoding.Extensions.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -4881,16 +4883,16 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.text.encoding.extensions.4.3.0.nupkg.sha512", - "system.text.encoding.extensions.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.Text.RegularExpressions/4.3.0": { - "sha512": "RpT2DA+L660cBt1FssIE9CAGpLFdFPuheB7pLpKpn6ZXNby7jDERe8Ua/Ne2xGiwLVG2JOqziiaVCGDon5sKFA==", + "sha512": "KkErACEE/O5S3SVNb3cybtRBREao0P/m8avuyrVnI3sE5yUdg8B7R133p2cO6l4CO5VssmJ0florOeFOZs+j9g==", "type": "package", "path": "system.text.regularexpressions/4.3.0", "files": [ + "System.Text.RegularExpressions.4.3.0.nupkg.sha512", + "System.Text.RegularExpressions.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -4963,16 +4965,16 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.text.regularexpressions.4.3.0.nupkg.sha512", - "system.text.regularexpressions.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.Threading/4.3.0": { - "sha512": "VkUS0kOBcUf3Wwm0TSbrevDDZ6BlM+b/HRiapRFWjM5O0NS0LviG0glKmFK+hhPDd1XFeSdU1GmlLhb2CoVpIw==", + "sha512": "X2dm0CWNrecCe9KtnS6aG5aMSrQ0R9fcXEabUPo8mCZV516bECrI2NpLSgai8meK4C9VciyxdAs1U1DEoy8fTw==", "type": "package", "path": "system.threading/4.3.0", "files": [ + "System.Threading.4.3.0.nupkg.sha512", + "System.Threading.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -5032,16 +5034,16 @@ "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", "ref/xamarinwatchos10/_._", - "runtimes/aot/lib/netcore50/System.Threading.dll", - "system.threading.4.3.0.nupkg.sha512", - "system.threading.nuspec" + "runtimes/aot/lib/netcore50/System.Threading.dll" ] }, "System.Threading.Tasks/4.3.0": { - "sha512": "LbSxKEdOUhVe8BezB/9uOGGppt+nZf6e1VFyw6v3DN6lqitm0OSn2uXMOdtP0M3W4iMcqcivm2J6UgqiwwnXiA==", + "sha512": "SuzCjdyZY1++6EWmel57slR75YTrYYOrYwMnIBmlSTd5khNE3K8OvE+wkgEgl2hLo9amIzEHlGUXmcdYhdLuwA==", "type": "package", "path": "system.threading.tasks/4.3.0", "files": [ + "System.Threading.Tasks.4.3.0.nupkg.sha512", + "System.Threading.Tasks.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -5098,31 +5100,31 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.threading.tasks.4.3.0.nupkg.sha512", - "system.threading.tasks.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.Threading.Tasks.Extensions/4.3.0": { - "sha512": "npvJkVKl5rKXrtl1Kkm6OhOUaYGEiF9wFbppFRWSMoApKzt2PiPHT2Bb8a5sAWxprvdOAtvaARS9QYMznEUtug==", + "sha512": "zxaGBe/5Z4llgwOFGlfuCV6h2P1vabcSP5NJ1kquBnqNgLAr2VPzFQ7MSfpojJVxNI9wXg8aQPtpLrPKZvzw/w==", "type": "package", "path": "system.threading.tasks.extensions/4.3.0", "files": [ + "System.Threading.Tasks.Extensions.4.3.0.nupkg.sha512", + "System.Threading.Tasks.Extensions.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/netstandard1.0/System.Threading.Tasks.Extensions.dll", "lib/netstandard1.0/System.Threading.Tasks.Extensions.xml", "lib/portable-net45+win8+wp8+wpa81/System.Threading.Tasks.Extensions.dll", - "lib/portable-net45+win8+wp8+wpa81/System.Threading.Tasks.Extensions.xml", - "system.threading.tasks.extensions.4.3.0.nupkg.sha512", - "system.threading.tasks.extensions.nuspec" + "lib/portable-net45+win8+wp8+wpa81/System.Threading.Tasks.Extensions.xml" ] }, "System.Threading.Thread/4.3.0": { - "sha512": "OHmbT+Zz065NKII/ZHcH9XO1dEuLGI1L2k7uYss+9C1jLxTC9kTZZuzUOyXHayRk+dft9CiDf3I/QZ0t8JKyBQ==", + "sha512": "ZVqA9KE6LDBxfLR0lQRdboT+mnKSZnS/d1/i5MPjkyuYvbfcUDfp5WUOx3OIK3yD1U5gNJ6dONieNRz+k2ikjA==", "type": "package", "path": "system.threading.thread/4.3.0", "files": [ + "System.Threading.Thread.4.3.0.nupkg.sha512", + "System.Threading.Thread.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -5151,16 +5153,16 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.threading.thread.4.3.0.nupkg.sha512", - "system.threading.thread.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.Threading.ThreadPool/4.3.0": { - "sha512": "k/+g4b7vjdd4aix83sTgC9VG6oXYKAktSfNIJUNGxPEj7ryEOfzHHhfnmsZvjxawwcD9HyWXKCXmPjX8U4zeSw==", + "sha512": "PXnCQ0n3Fw94SVTR4RPX54uiv6UtsO+E8wPw7ms7gHqj25QpHzV5j0VUUV4/VzNgN2DnzjuR6fWOqiFc6ju7Cg==", "type": "package", "path": "system.threading.threadpool/4.3.0", "files": [ + "System.Threading.ThreadPool.4.3.0.nupkg.sha512", + "System.Threading.ThreadPool.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -5189,16 +5191,16 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.threading.threadpool.4.3.0.nupkg.sha512", - "system.threading.threadpool.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.Xml.ReaderWriter/4.3.0": { - "sha512": "GrprA+Z0RUXaR4N7/eW71j1rgMnEnEVlgii49GZyAjTH7uliMnrOU3HNFBr6fEDBCJCIdlVNq9hHbaDR621XBA==", + "sha512": "nEhSftvdzfKEsHpZ3mh6qYC0YhUv9UncN0pzz6arBMvfZvUeHBjyDyQ/6s3H6hYyTWa31nq60QSIRGYIgmrCJA==", "type": "package", "path": "system.xml.readerwriter/4.3.0", "files": [ + "System.Xml.ReaderWriter.4.3.0.nupkg.sha512", + "System.Xml.ReaderWriter.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -5259,16 +5261,16 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.xml.readerwriter.4.3.0.nupkg.sha512", - "system.xml.readerwriter.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.Xml.XDocument/4.3.0": { - "sha512": "5zJ0XDxAIg8iy+t4aMnQAu0MqVbqyvfoUVl1yDV61xdo3Vth45oA2FoY4pPkxYAH5f8ixpmTqXeEIya95x0aCQ==", + "sha512": "yHtMrzLbOK0UzDdO5aV/58+TZ7MbDZ2pGnN9nY6cNShz93Wro4aRFpKIBErMipN8jOLudfPKaSmHZ0Jjc9gH/A==", "type": "package", "path": "system.xml.xdocument/4.3.0", "files": [ + "System.Xml.XDocument.4.3.0.nupkg.sha512", + "System.Xml.XDocument.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -5327,9 +5329,7 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.xml.xdocument.4.3.0.nupkg.sha512", - "system.xml.xdocument.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.Xml.XmlDocument/4.3.0": { @@ -5439,10 +5439,12 @@ ] }, "System.Xml.XPath/4.0.1": { - "sha512": "UWd1H+1IJ9Wlq5nognZ/XJdyj8qPE4XufBUkAW59ijsCPjZkZe0MUzKKJFBr+ZWBe5Wq1u1d5f2CYgE93uH7DA==", + "sha512": "VQcoW7mBX543Oibk05pP+uaTTq6zLT+Cf+iwMhpxK5P6QROb+R3Jt65Q7RgNQzn1yovbioFl+LwAGkxtSPv9Dw==", "type": "package", "path": "system.xml.xpath/4.0.1", "files": [ + "System.Xml.XPath.4.0.1.nupkg.sha512", + "System.Xml.XPath.nuspec", "ThirdPartyNotices.txt", "dotnet_library_license.txt", "lib/MonoAndroid10/_._", @@ -5470,9 +5472,7 @@ "ref/xamarinios10/_._", "ref/xamarinmac20/_._", "ref/xamarintvos10/_._", - "ref/xamarinwatchos10/_._", - "system.xml.xpath.4.0.1.nupkg.sha512", - "system.xml.xpath.nuspec" + "ref/xamarinwatchos10/_._" ] }, "System.Xml.XPath.XmlDocument/4.0.1": { @@ -5615,30 +5615,28 @@ ] }, "packageFolders": { - "C:\\Users\\rchande\\.nuget\\packages\\": {}, - "C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder": {} + "/Users/piotrp/code/github/piotrpMSFT/cli/.nuget/packages": {}, + "/usr/local/share/dotnet/sdk/NuGetFallbackFolder": {} }, "project": { "version": "1.0.0", "restore": { - "projectUniqueName": "C:\\omnisharp-vscode\\test\\integrationTests\\testAssets\\slnWithCsproj\\test\\test.csproj", + "projectUniqueName": "/Users/piotrp/code/github/piotrpMSFT/omnisharp-vscode/test/integrationTests/testAssets/slnWithCsproj/test/test.csproj", "projectName": "test", - "projectPath": "C:\\omnisharp-vscode\\test\\integrationTests\\testAssets\\slnWithCsproj\\test\\test.csproj", - "packagesPath": "C:\\Users\\rchande\\.nuget\\packages\\", - "outputPath": "C:\\omnisharp-vscode\\test\\integrationTests\\testAssets\\slnWithCsproj\\test\\obj\\", + "projectPath": "/Users/piotrp/code/github/piotrpMSFT/omnisharp-vscode/test/integrationTests/testAssets/slnWithCsproj/test/test.csproj", + "packagesPath": "/Users/piotrp/code/github/piotrpMSFT/cli/.nuget/packages", + "outputPath": "/Users/piotrp/code/github/piotrpMSFT/omnisharp-vscode/test/integrationTests/testAssets/slnWithCsproj/test/obj/", "projectStyle": "PackageReference", "fallbackFolders": [ - "C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder" + "/usr/local/share/dotnet/sdk/NuGetFallbackFolder" ], "configFilePaths": [ - "C:\\Users\\rchande\\AppData\\Roaming\\NuGet\\NuGet.Config", - "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config" + "/Users/piotrp/.nuget/NuGet/NuGet.Config" ], "originalTargetFrameworks": [ "netcoreapp2.0" ], "sources": { - "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {}, "https://api.nuget.org/v3/index.json": {} }, "frameworks": { diff --git a/test/integrationTests/testAssets/slnWithCsproj/test/obj/test.csproj.nuget.cache b/test/integrationTests/testAssets/slnWithCsproj/test/obj/test.csproj.nuget.cache index 63f7da1bb..07bbf6240 100644 --- a/test/integrationTests/testAssets/slnWithCsproj/test/obj/test.csproj.nuget.cache +++ b/test/integrationTests/testAssets/slnWithCsproj/test/obj/test.csproj.nuget.cache @@ -1,5 +1,5 @@ { "version": 1, - "dgSpecHash": "Ze/A7pD6wtcahUh1dvpo0JzwjPmm9JMlqj0tCxpn/Xh+TPfp4veowld1FB7PwZNoNVLOIsSBSEd6OtcEi/MHew==", + "dgSpecHash": "FiNYafjQARYJ5MFqcNAWBYkjbXAZGIJ8mclHfdlzLHwGKZAnN7INPNUVgoMPCrZT2ts042scBipz/HzEwD7lkA==", "success": true } \ No newline at end of file diff --git a/test/integrationTests/testAssets/slnWithCsproj/test/obj/test.csproj.nuget.g.props b/test/integrationTests/testAssets/slnWithCsproj/test/obj/test.csproj.nuget.g.props index 154dca965..ba7d85c24 100644 --- a/test/integrationTests/testAssets/slnWithCsproj/test/obj/test.csproj.nuget.g.props +++ b/test/integrationTests/testAssets/slnWithCsproj/test/obj/test.csproj.nuget.g.props @@ -3,9 +3,9 @@ True NuGet - C:\omnisharp-vscode\test\integrationTests\testAssets\slnWithCsproj\test\obj\project.assets.json - $(UserProfile)\.nuget\packages\ - C:\Users\rchande\.nuget\packages\;C:\Program Files\dotnet\sdk\NuGetFallbackFolder + /Users/piotrp/code/github/piotrpMSFT/omnisharp-vscode/test/integrationTests/testAssets/slnWithCsproj/test/obj/project.assets.json + /Users/piotrp/code/github/piotrpMSFT/cli/.nuget/packages + /Users/piotrp/code/github/piotrpMSFT/cli/.nuget/packages;/usr/local/share/dotnet/sdk/NuGetFallbackFolder PackageReference 4.5.0 @@ -13,8 +13,8 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - - - + + + \ No newline at end of file diff --git a/test/integrationTests/testAssets/slnWithCsproj/test/obj/test.csproj.nuget.g.targets b/test/integrationTests/testAssets/slnWithCsproj/test/obj/test.csproj.nuget.g.targets index 1c827086f..bb3434e2c 100644 --- a/test/integrationTests/testAssets/slnWithCsproj/test/obj/test.csproj.nuget.g.targets +++ b/test/integrationTests/testAssets/slnWithCsproj/test/obj/test.csproj.nuget.g.targets @@ -4,8 +4,8 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - - - + + + \ No newline at end of file diff --git a/test/integrationTests/testAssets/spawnGit.ts b/test/integrationTests/testAssets/spawnGit.ts new file mode 100644 index 000000000..cc4c1d494 --- /dev/null +++ b/test/integrationTests/testAssets/spawnGit.ts @@ -0,0 +1,32 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import { SpawnOptions, spawn } from "child_process"; +import { join, Result } from "async-child-process"; + +export default async function spawnGit(args?: string[], options?: SpawnOptions): Promise { + if (!options) { + options = { + env: {} + }; + } + + let optionsWithFullEnvironment = { + ...options, + env: { + ...process.env, + ...options.env + } + }; + + let spawned = spawn('git', args, optionsWithFullEnvironment); + + spawned.stdout.on('data', (data) => console.log(data.toString())); + spawned.stderr.on('data', (data) => console.log(data.toString())); + + return join(spawned); +} \ No newline at end of file diff --git a/test/integrationTests/testAssets/testAssets.ts b/test/integrationTests/testAssets/testAssets.ts index 6e690edb1..277006910 100644 --- a/test/integrationTests/testAssets/testAssets.ts +++ b/test/integrationTests/testAssets/testAssets.ts @@ -6,7 +6,7 @@ import * as fs from 'async-file'; import * as path from 'path'; import * as vscode from 'vscode'; -import * as cp from 'child_process'; +import spawnGit from './spawnGit'; export class TestAssetProject { constructor(project: ITestAssetProject) { @@ -69,23 +69,11 @@ export class TestAssetWorkspace { async cleanupWorkspace(): Promise { for (let project of this.projects) { let wd = path.dirname(project.projectDirectoryPath); - await this.invokeGit("clean -xdf . ", wd); - await this.invokeGit("checkout -- .", wd); + await spawnGit(["clean", "-xdf", "."], { cwd: wd }); + await spawnGit(["checkout", "--", "."], { cwd: wd }); } } - invokeGit(args: string, workingDirectory: string): Promise<{ stdout: string, stderr: string }> { - return new Promise((resolve, reject) => { - let child = cp.exec('git ' + args, { cwd: path.dirname(workingDirectory) }, - (err, stdout, stderr) => { - return err ? reject(err) : resolve({ - stdout: stdout, - stderr: stderr - }); - }); - }); - } - description: string; projects: TestAssetProject[]; diff --git a/test/releaseTests/offlinePackage.test.ts b/test/releaseTests/offlinePackage.test.ts new file mode 100644 index 000000000..643a54cbf --- /dev/null +++ b/test/releaseTests/offlinePackage.test.ts @@ -0,0 +1,54 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as chai from 'chai'; +import * as glob from 'glob-promise'; +import * as path from 'path'; +import { invokeNode } from './testAssets/testAssets'; +import { PlatformInformation } from '../../src/platform'; +import { rimraf } from 'async-file'; +import * as tmp from 'tmp'; + +suite("Offline packaging of VSIX", function () { + let vsixFiles: string[]; + this.timeout(1000000); + let tmpDir: tmp.SynchrounousResult = null; + + suiteSetup(() => { + chai.should(); + tmpDir = tmp.dirSync(); + let args: string[] = []; + args.push(path.join("node_modules", "gulp", "bin", "gulp.js")); + args.push("package:offline"); + args.push("--retainVsix");// do not delete the existing vsix in the repo + args.push(`-o`); + args.push(tmpDir.name); + invokeNode(args); + vsixFiles = glob.sync(path.join(tmpDir.name, '*.vsix')); + }); + + test("Exactly 3 vsix files should be produced", () => { + vsixFiles.length.should.be.equal(3, "the build should produce exactly 3 vsix files"); + }); + + [ + new PlatformInformation('win32', 'x86_64'), + new PlatformInformation('darwin', 'x86_64'), + new PlatformInformation('linux', 'x86_64') + ].forEach(element => { + test(`Given Platform: ${element.platform} and Architecture: ${element.architecture}, the vsix file is created`, () => { + vsixFiles.findIndex(elem => elem.indexOf(element.platform) != -1).should.not.be.equal(-1); + vsixFiles.findIndex(elem => elem.indexOf(element.architecture) != -1).should.not.be.equal(-1); + }); + }); + + suiteTeardown(async () => { + if (tmpDir) { + await rimraf(tmpDir.name); + } + + tmpDir = null; + }); +}); diff --git a/test/releaseTests/testAssets/testAssets.ts b/test/releaseTests/testAssets/testAssets.ts new file mode 100644 index 000000000..1906b6b10 --- /dev/null +++ b/test/releaseTests/testAssets/testAssets.ts @@ -0,0 +1,13 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as cp from 'child_process'; + +export function invokeNode(args: string[]){ + let proc = cp.spawnSync('node', args); + if (proc.error) { + console.error(proc.error.toString()); + } +} \ No newline at end of file diff --git a/test/unitTests/Packages/FileDownloader.test.ts b/test/unitTests/Packages/FileDownloader.test.ts new file mode 100644 index 000000000..92a1a17b9 --- /dev/null +++ b/test/unitTests/Packages/FileDownloader.test.ts @@ -0,0 +1,156 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as fs from 'async-file'; +import * as chai from 'chai'; +import * as util from '../../../src/common'; +import { EventStream } from '../../../src/EventStream'; +import { DownloadFile } from '../../../src/packageManager/FileDownloader'; +import NetworkSettings from '../../../src/NetworkSettings'; +import { TmpAsset, CreateTmpFile } from '../../../src/CreateTmpAsset'; +import { BaseEvent, DownloadStart, DownloadSizeObtained, DownloadProgress, DownloadSuccess, DownloadFallBack, DownloadFailure } from '../../../src/omnisharp/loggingEvents'; +import { getRequestHandler } from '../testAssets/MockHttpServerRequestHandler'; + +const getPort = require('get-port'); +const ServerMock = require("mock-http-server"); +chai.use(require("chai-as-promised")); +chai.use(require('chai-arrays')); +const expect = chai.expect; + +suite("FileDownloader", () => { + const fileDescription = "Test file"; + const correctUrlPath = `/resource`; + const redirectUrlPath = '/redirectResource'; + const errorUrlPath = '/errorResource'; + const networkSettingsProvider = () => new NetworkSettings(undefined, false); + const eventStream = new EventStream(); + let eventBus: BaseEvent[]; + const getPrimaryURLEvents = () => { + return [ + new DownloadStart(fileDescription), + new DownloadSizeObtained(12), + new DownloadProgress(100, fileDescription), + new DownloadSuccess(' Done!')]; + }; + + const getFallBackURLEvents = () => { + return [ + new DownloadStart(fileDescription), + new DownloadFailure("failed (error code '404')"), + new DownloadFallBack(`${httpsServerUrl}${correctUrlPath}`), + new DownloadSizeObtained(12), + new DownloadProgress(100, fileDescription), + new DownloadSuccess(' Done!')]; + }; + eventStream.subscribe((event) => eventBus.push(event)); + + let server: any; + let httpsServerUrl: string; + let tmpFile: TmpAsset; + + suiteSetup(async () => { + let port = await getPort(); + server = new ServerMock(null, + { + host: "localhost", + port: port, + key: await fs.readFile("test/unitTests/testAssets/private.pem"), + cert: await fs.readFile("test/unitTests/testAssets/public.pem") + }); + + httpsServerUrl = `https://127.0.0.1:${port}`; + }); + + + setup(async () => { + await new Promise(resolve => server.start(resolve)); + tmpFile = await CreateTmpFile(); + util.setExtensionPath(tmpFile.name); + eventBus = []; + server.on(getRequestHandler('GET', correctUrlPath, 200, { "content-type": "text/plain" }, "Test content")); + server.on(getRequestHandler('GET', errorUrlPath, 404)); + server.on(getRequestHandler('GET', redirectUrlPath, 301, { "location": `${httpsServerUrl}${correctUrlPath}` })); + }); + + suite('If the response status Code is 200, the download succeeds', () => { + + [ + { + description: "Primary url", + urlPath: correctUrlPath, + fallBackUrlPath: "", + getEventSequence: getPrimaryURLEvents + }, + { + description: "Fallback url", + urlPath: errorUrlPath, + fallBackUrlPath: correctUrlPath, + getEventSequence: getFallBackURLEvents + } + ].forEach((elem) => { + suite(elem.description, () => { + test('File is downloaded', async () => { + await DownloadFile(tmpFile.fd, fileDescription, eventStream, networkSettingsProvider, getURL(elem.urlPath), getURL(elem.fallBackUrlPath)); + const stats = await fs.stat(tmpFile.name); + expect(stats.size).to.not.equal(0); + let text = await fs.readFile(tmpFile.name, 'utf8'); + expect(text).to.be.equal("Test content"); + }); + + test('Events are created in the correct order', async () => { + await DownloadFile(tmpFile.fd, fileDescription, eventStream, networkSettingsProvider, getURL(elem.urlPath), getURL(elem.fallBackUrlPath)); + expect(eventBus).to.be.deep.equal(elem.getEventSequence()); + }); + }); + }); + }); + + suite('If the response status Code is 301, redirect occurs and the download succeeds', () => { + test('File is downloaded from the redirect url', async () => { + await DownloadFile(tmpFile.fd, fileDescription, eventStream, networkSettingsProvider, getURL(redirectUrlPath)); + const stats = await fs.stat(tmpFile.name); + expect(stats.size).to.not.equal(0); + let text = await fs.readFile(tmpFile.name, "utf8"); + expect(text).to.be.equal("Test content"); + }); + }); + + suite('If the response status code is not 301, 302 or 200 then the download fails', () => { + test('Error is thrown', async () => { + expect(DownloadFile(tmpFile.fd, fileDescription, eventStream, networkSettingsProvider, getURL(errorUrlPath))).be.rejected; + }); + + test('Download Start and Download Failure events are created', async () => { + let eventsSequence = [ + new DownloadStart(fileDescription), + new DownloadFailure("failed (error code '404')") + ]; + try { + await DownloadFile(tmpFile.fd, fileDescription, eventStream, networkSettingsProvider, getURL(errorUrlPath)); + } + catch (error) { + expect(eventBus).to.be.deep.equal(eventsSequence); + } + }); + }); + + test('Error is thrown on invalid input file', async () => { + //fd=0 means there is no file + expect(DownloadFile(0, fileDescription, eventStream, networkSettingsProvider, getURL(errorUrlPath))).to.be.rejected; + }); + + teardown(async () => { + await new Promise((resolve, reject) => server.stop(resolve)); + if (tmpFile) { + tmpFile.dispose(); + } + }); + + function getURL(urlPath: string) { + return `${httpsServerUrl}${urlPath}`; + } +}); + + diff --git a/test/unitTests/Packages/PackageFilterer.test.ts b/test/unitTests/Packages/PackageFilterer.test.ts new file mode 100644 index 000000000..d17e9024c --- /dev/null +++ b/test/unitTests/Packages/PackageFilterer.test.ts @@ -0,0 +1,103 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import * as chai from 'chai'; +import * as util from '../../../src/common'; +import { CreateTmpFile, TmpAsset } from "../../../src/CreateTmpAsset"; +import { PlatformInformation } from "../../../src/platform"; +import { filterPackages } from "../../../src/packageManager/PackageFilterer"; +import { ResolveFilePaths } from "../../../src/packageManager/PackageFilePathResolver"; +import { Package } from "../../../src/packageManager/Package"; + +let expect = chai.expect; + +suite('PackageFilterer', () => { + let tmpFile: TmpAsset; + const extensionPath = "ExtensionPath"; + const packages = [ + { + "description": "Platfrom1-Architecture1 uninstalled package", + "platforms": [ "platform1" ], + "architectures": [ "architecture1" ], + "installTestPath": "path1" + }, + { + //already installed package + "description": "Platfrom1-Architecture1 installed package", + "platforms": [ "platform1" ], + "architectures": [ "architecture1" ], + "installTestPath": "path5" + }, + { + "description": "Platfrom2-Architecture2 uninstalled package", + "platforms": [ "platform2" ], + "architectures": [ "architecture2" ], + "installTestPath": "path2" + }, + { + "description": "Platfrom1-Architecture2 uninstalled package", + "platforms": [ "platform1" ], + "architectures": [ "architecture2" ], + "installTestPath": "path3" + }, + { + "description": "Platfrom2-Architecture1 uninstalled package", + "platforms": [ "platform2" ], + "architectures": [ "architecture1" ], + "installTestPath": "path4" + }, + { + "description": "Platfrom1-Architecture2 uninstalled package", + "platforms": [ "platform1" ], + "architectures": [ "architecture2" ], + "installTestPath": "path3" + }, + { + "description": "Platfrom3-Architecture3 with no installTestPath specified", + "platforms": [ "platform3" ], + "architectures": [ "architecture3" ], + }, + ]; + + setup(async () => { + tmpFile = await CreateTmpFile(); + packages[1].installTestPath = tmpFile.name; + util.setExtensionPath(extensionPath); + // we need to set the extension path because fileresolver uses it + packages.forEach(pkg => ResolveFilePaths(pkg)); + }); + + test('Filters the packages based on Platform Information', async () => { + let platformInfo = new PlatformInformation("platform2", "architecture2"); + let filteredPackages = await filterPackages(packages, platformInfo); + expect(filteredPackages.length).to.be.equal(1); + expect(filteredPackages[0].description).to.be.equal("Platfrom2-Architecture2 uninstalled package"); + expect(filteredPackages[0].platforms[0]).to.be.equal("platform2"); + expect(filteredPackages[0].architectures[0]).to.be.equal("architecture2"); + }); + + test('Returns only uninstalled packages', async () => { + let platformInfo = new PlatformInformation("platform1", "architecture1"); + let filteredPackages = await filterPackages(packages, platformInfo); + expect(filteredPackages.length).to.be.equal(1); + expect(filteredPackages[0].description).to.be.equal("Platfrom1-Architecture1 uninstalled package"); + expect(filteredPackages[0].platforms[0]).to.be.equal("platform1"); + expect(filteredPackages[0].architectures[0]).to.be.equal("architecture1"); + }); + + test('Doesnot filter the package if install test path is not specified', async () => { + let platformInfo = new PlatformInformation("platform3", "architecture3"); + let filteredPackages = await filterPackages(packages, platformInfo); + expect(filteredPackages.length).to.be.equal(1); + expect(filteredPackages[0].description).to.be.equal("Platfrom3-Architecture3 with no installTestPath specified"); + expect(filteredPackages[0].platforms[0]).to.be.equal("platform3"); + expect(filteredPackages[0].architectures[0]).to.be.equal("architecture3"); + }); + + teardown(() => { + if (tmpFile) { + tmpFile.dispose(); + } + }); +}); \ No newline at end of file diff --git a/test/unitTests/Packages/PackageManager.test.ts b/test/unitTests/Packages/PackageManager.test.ts new file mode 100644 index 000000000..bf0eaab42 --- /dev/null +++ b/test/unitTests/Packages/PackageManager.test.ts @@ -0,0 +1,117 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as fs from 'async-file'; +import * as path from 'path'; +import * as chai from 'chai'; +import * as util from '../../../src/common'; +import { CreateTmpDir, TmpAsset } from '../../../src/CreateTmpAsset'; +import { Binaries, Files, createTestZipAsync } from '../testAssets/CreateTestZip'; +import { Package } from '../../../src/packageManager/Package'; +import { DownloadAndInstallPackages } from '../../../src/packageManager/PackageManager'; +import NetworkSettings from '../../../src/NetworkSettings'; +import { PlatformInformation } from '../../../src/platform'; +import { EventStream } from '../../../src/EventStream'; +import { BaseEvent, DownloadStart, DownloadSizeObtained, DownloadProgress, DownloadSuccess, InstallationStart } from '../../../src/omnisharp/loggingEvents'; +import { getRequestHandler } from '../testAssets/MockHttpServerRequestHandler'; + +chai.use(require("chai-as-promised")); +const expect = chai.expect; +const ServerMock = require("mock-http-server"); +const getPort = require('get-port'); + +suite("Package Manager", () => { + let tmpSourceDir: TmpAsset; + let tmpInstallDir: TmpAsset; + let server: any; + let downloadUrl: string; + let testDirPath: string; + let allFiles: Array<{ content: string, path: string }>; + let installationPath: string; + let eventBus: Array; + let packages: Package[]; + + const packageDescription = "Test Package"; + const eventStream = new EventStream(); + eventStream.subscribe(event => eventBus.push(event)); + + const windowsPlatformInfo = new PlatformInformation("win32", "x86"); + const linuxPlatformInfo = new PlatformInformation("linux", "x86"); + const networkSettingsProvider = () => new NetworkSettings(undefined, false); + + suiteSetup(async () => { + let port = await getPort(); + downloadUrl = `https://localhost:${port}/package`; + server = new ServerMock(null, + { + host: "localhost", + port: port, + key: await fs.readFile("test/unitTests/testAssets/private.pem"), + cert: await fs.readFile("test/unitTests/testAssets/public.pem") + }); + }); + + setup(async () => { + eventBus = []; + tmpSourceDir = await CreateTmpDir(true); + tmpInstallDir = await CreateTmpDir(true); + installationPath = tmpInstallDir.name; + packages = [ + { + url: downloadUrl, + description: packageDescription, + installPath: installationPath, + platforms: [windowsPlatformInfo.platform], + architectures: [windowsPlatformInfo.architecture] + }]; + allFiles = [...Files, ...Binaries]; + testDirPath = tmpSourceDir.name + "/test.zip"; + await createTestZipAsync(testDirPath, allFiles); + await new Promise(resolve => server.start(resolve)); //start the server + server.on(getRequestHandler('GET', '/package', 200, { + "content-type": "application/zip", + "content-length": (await fs.stat(testDirPath)).size + }, await fs.readFile(testDirPath))); + }); + + test("Downloads the package and installs at the specified path", async () => { + await DownloadAndInstallPackages(packages, networkSettingsProvider, windowsPlatformInfo, eventStream); + for (let elem of allFiles) { + let filePath = path.join(installationPath, elem.path); + expect(await util.fileExists(filePath)).to.be.true; + } + }); + + test("Events are created in the correct order", async () => { + let eventsSequence = [ + new DownloadStart(packageDescription), + new DownloadSizeObtained(396), + new DownloadProgress(100, packageDescription), + new DownloadSuccess(' Done!'), + new InstallationStart(packageDescription) + ]; + + await DownloadAndInstallPackages(packages, networkSettingsProvider, windowsPlatformInfo, eventStream); + expect(eventBus).to.be.deep.equal(eventsSequence); + }); + + test("Installs only the platform specific packages", async () => { + //since there is no linux package specified no package should be installed + await DownloadAndInstallPackages(packages, networkSettingsProvider, linuxPlatformInfo, eventStream); + let files = await fs.readdir(tmpInstallDir.name); + expect(files.length).to.equal(0); + }); + + teardown(async () => { + if (tmpSourceDir) { + tmpSourceDir.dispose(); + } + if (tmpInstallDir) { + tmpInstallDir.dispose(); + } + + await new Promise((resolve, reject) => server.stop(resolve)); + }); +}); \ No newline at end of file diff --git a/test/unitTests/Packages/ZipInstaller.test.ts b/test/unitTests/Packages/ZipInstaller.test.ts new file mode 100644 index 000000000..930b1ec14 --- /dev/null +++ b/test/unitTests/Packages/ZipInstaller.test.ts @@ -0,0 +1,89 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as fs from 'async-file'; +import * as path from 'path'; +import * as chai from 'chai'; +import * as util from '../../../src/common'; +import { CreateTmpDir, TmpAsset, CreateTmpFile } from '../../../src/CreateTmpAsset'; +import { InstallZip } from '../../../src/packageManager/ZipInstaller'; +import { EventStream } from '../../../src/EventStream'; +import { PlatformInformation } from '../../../src/platform'; +import { BaseEvent, InstallationStart } from '../../../src/omnisharp/loggingEvents'; +import { Files, Binaries, createTestZipAsync } from '../testAssets/CreateTestZip'; + +chai.use(require("chai-as-promised")); +let expect = chai.expect; + +suite('ZipInstaller', () => { + let tmpSourceDir: TmpAsset; + let tmpInstallDir: TmpAsset; + let testDirPath: string; + let zipFileDescriptor: number; + let txtFile: TmpAsset; + let installationPath: string; + + const fileDescription = "somefile"; + const eventStream = new EventStream(); + let eventBus: BaseEvent[]; + eventStream.subscribe((event) => eventBus.push(event)); + let allFiles: Array<{ content: string, path: string }>; + + setup(async () => { + eventBus = []; + tmpSourceDir = await CreateTmpDir(true); + tmpInstallDir = await CreateTmpDir(true); + installationPath = tmpInstallDir.name; + txtFile = await CreateTmpFile(); + allFiles = [...Files, ...Binaries]; + testDirPath = tmpSourceDir.name + "/test.zip"; + await createTestZipAsync(testDirPath, allFiles); + zipFileDescriptor = await fs.open(path.resolve(testDirPath), 'r'); + util.setExtensionPath(tmpInstallDir.name); + }); + + test('The folder is unzipped and all the files are present at the expected paths', async () => { + await InstallZip(zipFileDescriptor, fileDescription, installationPath, [], eventStream); + for (let elem of allFiles) { + let filePath = path.join(installationPath, elem.path); + expect(await util.fileExists(filePath)).to.be.true; + } + }); + + test('The folder is unzipped and all the expected events are created', async () => { + await InstallZip(zipFileDescriptor, fileDescription, installationPath, [], eventStream); + let eventSequence: BaseEvent[] = [ + new InstallationStart(fileDescription) + ]; + expect(eventBus).to.be.deep.equal(eventSequence); + }); + + test('The folder is unzipped and the binaries have the expected permissions(except on Windows)', async () => { + if (!((await PlatformInformation.GetCurrent()).isWindows())) { + let resolvedBinaryPaths = Binaries.map(binary => path.join(installationPath, binary.path)); + await InstallZip(zipFileDescriptor, fileDescription, installationPath, resolvedBinaryPaths, eventStream); + for (let binaryPath of resolvedBinaryPaths) { + expect(await util.fileExists(binaryPath)).to.be.true; + let mode = (await fs.stat(binaryPath)).mode; + expect(mode & 0o7777).to.be.equal(0o755, `Expected mode for path ${binaryPath}`); + } + } + }); + + test('Error is thrown when the file is not a zip', async () => { + expect(InstallZip(txtFile.fd, "Text File", installationPath, [], eventStream)).to.be.rejected; + }); + + test('Error is thrown on invalid input file', async () => { + //fd=0 means there is no file + expect(InstallZip(0, fileDescription, "someRandomPath", [], eventStream)).to.be.rejected; + }); + + teardown(async () => { + await fs.close(zipFileDescriptor); + tmpSourceDir.dispose(); + tmpInstallDir.dispose(); + }); +}); diff --git a/test/unitTests/common.test.ts b/test/unitTests/common.test.ts index 585752ba5..fd076e03d 100644 --- a/test/unitTests/common.test.ts +++ b/test/unitTests/common.test.ts @@ -7,17 +7,17 @@ import * as path from 'path'; import { buildPromiseChain, isSubfolderOf, safeLength, sum } from '../../src/common'; -import { should } from 'chai'; +import { should, expect } from 'chai'; suite("Common", () => { suiteSetup(() => should()); suite("buildPromiseChain", () => { - test("produce a sequence of promises", () => { + test("produce a sequence of promises", async () => { let array: number[] = []; let items = [1, 2, 3, 4, 5]; - let promise = buildPromiseChain(items, n => new Promise((resolve, reject) => { + let promise = buildPromiseChain(items, async n => new Promise((resolve, reject) => { array.push(n); resolve(); })); @@ -30,7 +30,7 @@ suite("Common", () => { suite("safeLength", () => { test("return 0 for empty array", () => { - let array = []; + let array: any[] = []; let result = safeLength(array); result.should.equal(0); }); @@ -73,28 +73,28 @@ suite("Common", () => { let subfolder: string = ["C:", "temp", "VS", "dotnetProject"].join(path.sep); let folder: string= ["C:", "temp", "VS", "dotnetProject"].join(path.sep); - isSubfolderOf(subfolder, folder).should.be.true; + expect(isSubfolderOf(subfolder, folder)).to.be.true; }); test("correct subfolder", () => { let subfolder: string = ["C:", "temp", "VS"].join(path.sep); let folder: string= ["C:", "temp", "VS", "dotnetProject"].join(path.sep); - isSubfolderOf(subfolder, folder).should.be.true; + expect(isSubfolderOf(subfolder, folder)).to.be.true; }); test("longer subfolder", () => { let subfolder: string = ["C:", "temp", "VS", "a", "b", "c"].join(path.sep); let folder: string= ["C:", "temp", "VS"].join(path.sep); - isSubfolderOf(subfolder, folder).should.be.false; + expect(isSubfolderOf(subfolder, folder)).to.be.false; }); test("Different drive", () => { let subfolder: string = ["C:", "temp", "VS"].join(path.sep); let folder: string= ["E:", "temp", "VS"].join(path.sep); - isSubfolderOf(subfolder, folder).should.be.false; + expect(isSubfolderOf(subfolder, folder)).to.be.false; }); }); }); diff --git a/test/unitTests/logging/CsharpChannelObserver.test.ts b/test/unitTests/logging/CsharpChannelObserver.test.ts new file mode 100644 index 000000000..8df396eca --- /dev/null +++ b/test/unitTests/logging/CsharpChannelObserver.test.ts @@ -0,0 +1,32 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { should, expect } from 'chai'; +import { getNullChannel } from '../testAssets/Fakes'; +import { CsharpChannelObserver } from '../../../src/observers/CsharpChannelObserver'; +import { InstallationFailure, DebuggerNotInstalledFailure, DebuggerPrerequisiteFailure, ProjectJsonDeprecatedWarning, BaseEvent, DownloadStart } from '../../../src/omnisharp/loggingEvents'; + +suite("CsharpChannelObserver", () => { + suiteSetup(() => should()); + [ + new InstallationFailure("someStage", "someError"), + new DownloadStart("somePackage"), + new DebuggerNotInstalledFailure(), + new DebuggerPrerequisiteFailure("some failure"), + new ProjectJsonDeprecatedWarning() + ].forEach((event: BaseEvent) => { + test(`${event.constructor.name}: Channel is shown`, () => { + let hasShown = false; + + let observer = new CsharpChannelObserver({ + ...getNullChannel(), + show: () => { hasShown = true; } + }); + + observer.post(event); + expect(hasShown).to.be.true; + }); + }); +}); diff --git a/test/unitTests/logging/CsharpLoggerObserver.test.ts b/test/unitTests/logging/CsharpLoggerObserver.test.ts new file mode 100644 index 000000000..678af6f57 --- /dev/null +++ b/test/unitTests/logging/CsharpLoggerObserver.test.ts @@ -0,0 +1,161 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { should, expect } from 'chai'; +import { getNullChannel } from '../testAssets/Fakes'; +import { CsharpLoggerObserver } from '../../../src/observers/CsharpLoggerObserver'; +import { PlatformInformation } from '../../../src/platform'; +import * as Event from '../../../src/omnisharp/loggingEvents'; +import { PackageError } from '../../../src/packageManager/PackageError'; + +suite("CsharpLoggerObserver", () => { + suiteSetup(() => should()); + + let logOutput = ""; + let observer = new CsharpLoggerObserver({ + ...getNullChannel(), + append: (text?: string) => { logOutput += text || ""; }, + }); + + setup(() => { + logOutput = ""; + }); + + test('PlatformInfo: Logs contain the Platform and Architecture', () => { + let event = new Event.LogPlatformInfo(new PlatformInformation("MyPlatform", "MyArchitecture")); + observer.post(event); + expect(logOutput).to.contain("MyPlatform"); + expect(logOutput).to.contain("MyArchitecture"); + }); + + suite("InstallationFailure", () => { + test('Stage and Error is logged if not a PackageError', () => { + let event = new Event.InstallationFailure("someStage", new Error("someError")); + observer.post(event); + expect(logOutput).to.contain(event.stage); + expect(logOutput).to.contain(event.error.toString()); + }); + + test('Stage and Error is logged if a PackageError without inner error', () => { + let event = new Event.InstallationFailure("someStage", new PackageError("someError", null, null)); + observer.post(event); + expect(logOutput).to.contain(event.stage); + expect(logOutput).to.contain(event.error.message); + }); + + test('Stage and Inner error is logged if a PackageError without inner error', () => { + let event = new Event.InstallationFailure("someStage", new PackageError("someError", null, "innerError")); + observer.post(event); + expect(logOutput).to.contain(event.stage); + expect(logOutput).to.contain(event.error.innerError.toString()); + }); + }); + + suite('Download', () => { + let packageName = "somePackage"; + [ + { + events: [], + expected: "" + }, + { + events: [new Event.DownloadStart("somePackage")], + expected: "Downloading package 'somePackage' " + }, + { + events: [new Event.DownloadStart("somePackage"), new Event.DownloadSizeObtained(500), new Event.DownloadProgress(100, packageName)], + expected: "Downloading package 'somePackage' (1 KB)...................." + }, + { + events: [new Event.DownloadStart("somePackage"), new Event.DownloadSizeObtained(500), new Event.DownloadProgress(10, packageName), new Event.DownloadProgress(50, packageName), new Event.DownloadProgress(100, packageName)], + expected: "Downloading package 'somePackage' (1 KB)...................." + }, + { + events: [new Event.DownloadStart("somePackage"), new Event.DownloadSizeObtained(500), new Event.DownloadProgress(10, packageName), new Event.DownloadProgress(50, packageName)], + expected: "Downloading package 'somePackage' (1 KB).........." + }, + { + events: [new Event.DownloadStart("somePackage"), new Event.DownloadSizeObtained(2000), new Event.DownloadProgress(50, packageName)], + expected: "Downloading package 'somePackage' (2 KB).........." + }, + { + events: [new Event.DownloadStart("somePackage"), new Event.DownloadSizeObtained(2000), new Event.DownloadProgress(50, packageName), new Event.DownloadProgress(50, packageName), new Event.DownloadProgress(50, packageName)], + expected: "Downloading package 'somePackage' (2 KB).........." + }, + { + events: [new Event.DownloadStart("somePackage"), new Event.DownloadSizeObtained(3000), new Event.DownloadProgress(100, packageName), new Event.DownloadSuccess("Done")], + expected: "Downloading package 'somePackage' (3 KB)....................Done\n" + }, + { + events: [new Event.DownloadStart("somePackage"), new Event.DownloadSizeObtained(4000), new Event.DownloadProgress(50, packageName), new Event.DownloadFailure("Failed")], + expected: "Downloading package 'somePackage' (4 KB)..........Failed\n" + } + ].forEach((element) => { + test(`Prints the download status to the logger as ${element.expected}`, () => { + let logOutput = ""; + + let observer = new CsharpLoggerObserver({ + ...getNullChannel(), + appendLine: (text?: string) => { logOutput += `${text}\n`; }, + append: (text?: string) => { logOutput += text; } + }); + + element.events.forEach((message: Event.BaseEvent) => observer.post(message)); + expect(logOutput).to.be.equal(element.expected); + }); + }); + }); + + [ + { + message: new Event.DebuggerPrerequisiteFailure('Some failure message'), + expected: `Some failure message` + }, + { + message: new Event.DebuggerPrerequisiteWarning("Some warning message"), + expected: `Some warning message` + } + ].forEach((element) => + test(`${element.message.constructor.name} is shown`, () => { + observer.post(element.message); + expect(logOutput).to.contain(element.expected); + })); + + test(`ActivationFailure: Some message is logged`, () => { + let event = new Event.ActivationFailure(); + observer.post(event); + expect(logOutput).to.not.be.empty; + }); + + test(`ProjectJsonDeprecatedWarning: Some message is logged`, () => { + let event = new Event.ProjectJsonDeprecatedWarning(); + observer.post(event); + expect(logOutput).to.not.be.empty; + }); + + test(`InstallationSuccess: Some message is logged`, () => { + let event = new Event.InstallationSuccess(); + observer.post(event); + expect(logOutput).to.not.be.empty; + }); + + test(`InstallationProgress: Progress message is logged`, () => { + let event = new Event.InstallationStart("somPackage"); + observer.post(event); + expect(logOutput).to.contain(event.packageDescription); + }); + + test('PackageInstallation: Package name is logged', () => { + let event = new Event.PackageInstallation("somePackage"); + observer.post(event); + expect(logOutput).to.contain(event.packageInfo); + }); + + test('DownloadFallBack: The fallbackurl is logged', () => { + let event = new Event.DownloadFallBack("somrurl"); + observer.post(event); + expect(logOutput).to.contain(event.fallbackUrl); + }); +}); diff --git a/test/unitTests/logging/DotnetChannelObserver.test.ts b/test/unitTests/logging/DotnetChannelObserver.test.ts new file mode 100644 index 000000000..1453201a7 --- /dev/null +++ b/test/unitTests/logging/DotnetChannelObserver.test.ts @@ -0,0 +1,33 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { should, expect } from 'chai'; +import { DotNetChannelObserver } from "../../../src/observers/DotnetChannelObserver"; +import { getNullChannel } from '../testAssets/Fakes'; +import { CommandDotNetRestoreStart } from '../../../src/omnisharp/loggingEvents'; + +suite("DotnetChannelObserver", () => { + suiteSetup(() => should()); + let hasShown: boolean; + let hasCleared: boolean; + + let observer = new DotNetChannelObserver({ + ...getNullChannel(), + clear: () => { hasCleared = true; }, + show: () => { hasShown = true; } + }); + + setup(() => { + hasShown = false; + hasCleared = false; + }); + + test(`CommandDotNetRestoreStart : Clears and shows the channel`, () => { + let event = new CommandDotNetRestoreStart(); + observer.post(event); + expect(hasCleared).to.be.true; + expect(hasShown).to.be.true; + }); +}); diff --git a/test/unitTests/logging/DotnetLoggerObserver.test.ts b/test/unitTests/logging/DotnetLoggerObserver.test.ts new file mode 100644 index 000000000..b0aa92359 --- /dev/null +++ b/test/unitTests/logging/DotnetLoggerObserver.test.ts @@ -0,0 +1,30 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { should, expect } from 'chai'; +import { getNullChannel } from '../testAssets/Fakes'; +import { DotnetLoggerObserver } from '../../../src/observers/DotnetLoggerObserver'; +import { CommandDotNetRestoreProgress, CommandDotNetRestoreSucceeded, CommandDotNetRestoreFailed, EventWithMessage } from '../../../src/omnisharp/loggingEvents'; + +suite("DotnetLoggerObserver", () => { + suiteSetup(() => should()); + + [ + new CommandDotNetRestoreProgress("Some message"), + new CommandDotNetRestoreSucceeded("Some message"), + new CommandDotNetRestoreFailed("Some message") + ].forEach((event: EventWithMessage) => { + test(`${event.constructor.name}: Message is logged`, () => { + let appendedMessage = ""; + let observer = new DotnetLoggerObserver({ + ...getNullChannel(), + append: (text: string) => { appendedMessage += text; }, + }); + + observer.post(event); + expect(appendedMessage).to.contain(event.message); + }); + }); +}); diff --git a/test/unitTests/logging/InformationMessageObserver.test.ts b/test/unitTests/logging/InformationMessageObserver.test.ts new file mode 100644 index 000000000..849c082bd --- /dev/null +++ b/test/unitTests/logging/InformationMessageObserver.test.ts @@ -0,0 +1,122 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { InformationMessageObserver } from '../../../src/observers/InformationMessageObserver'; +import { use as chaiUse, expect, should } from 'chai'; +import { vscode, Uri } from '../../../src/vscodeAdapter'; +import { getFakeVsCode, getNullWorkspaceConfiguration, getUnresolvedDependenices } from '../testAssets/Fakes'; +import { Observable } from 'rxjs/Observable'; +import 'rxjs/add/observable/fromPromise'; +import 'rxjs/add/operator/timeout'; + +chaiUse(require('chai-as-promised')); +chaiUse(require('chai-string')); + +suite("InformationMessageObserver", () => { + suiteSetup(() => should()); + + let doClickOk: () => void; + let doClickCancel: () => void; + let signalCommandDone: () => void; + let commandDone = new Promise(resolve => { + signalCommandDone = () => { resolve(); }; + }); + let vscode: vscode = getFakeVsCode(); + let infoMessage: string; + let relativePath: string; + let invokedCommand: string; + let observer: InformationMessageObserver = new InformationMessageObserver(vscode); + + vscode.window.showInformationMessage = async (message: string, ...items: string[]) => { + infoMessage = message; + return new Promise(resolve => { + doClickCancel = () => { + resolve(undefined); + }; + + doClickOk = () => { + resolve(message); + }; + }); + }; + + vscode.commands.executeCommand = (command: string, ...rest: any[]) => { + invokedCommand = command; + signalCommandDone(); + return undefined; + }; + + vscode.workspace.asRelativePath = (pathOrUri?: string, includeWorspaceFolder?: boolean) => { + relativePath = pathOrUri; + return relativePath; + }; + + setup(() => { + infoMessage = undefined; + relativePath = undefined; + invokedCommand = undefined; + commandDone = new Promise(resolve => { + signalCommandDone = () => { resolve(); }; + }); + }); + + suite('OmnisharpServerUnresolvedDependencies', () => { + let event = getUnresolvedDependenices("someFile"); + + suite('Suppress Dotnet Restore Notification is true', () => { + setup(() => { + vscode.workspace.getConfiguration = (section?: string, resource?: Uri) => { + return { + ...getNullWorkspaceConfiguration(), + get: (section: string) => { + return true;// suppress the restore information + } + }; + }; + }); + + test('The information message is not shown', () => { + observer.post(event); + expect(infoMessage).to.be.undefined; + }); + }); + + suite('Suppress Dotnet Restore Notification is false', () => { + setup(() => { + vscode.workspace.getConfiguration = (section?: string, resource?: Uri) => { + return { + ...getNullWorkspaceConfiguration(), + get: (section: string) => { + return false; // do not suppress the restore info + } + }; + }; + }); + + test('The information message is shown', async () => { + observer.post(event); + expect(relativePath).to.not.be.empty; + expect(infoMessage).to.not.be.empty; + doClickOk(); + await commandDone; + expect(invokedCommand).to.be.equal('dotnet.restore'); + }); + + test('Given an information message if the user clicks Restore, the command is executed', async () => { + observer.post(event); + doClickOk(); + await commandDone; + expect(invokedCommand).to.be.equal('dotnet.restore'); + }); + + test('Given an information message if the user clicks cancel, the command is not executed', async () => { + observer.post(event); + doClickCancel(); + await expect(Observable.fromPromise(commandDone).timeout(1).toPromise()).to.be.rejected; + expect(invokedCommand).to.be.undefined; + }); + }); + }); +}); \ No newline at end of file diff --git a/test/unitTests/logging/OmnisharpChannelObserver.test.ts b/test/unitTests/logging/OmnisharpChannelObserver.test.ts new file mode 100644 index 000000000..3776058b7 --- /dev/null +++ b/test/unitTests/logging/OmnisharpChannelObserver.test.ts @@ -0,0 +1,23 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import { should, expect } from 'chai'; +import { getNullChannel } from '../testAssets/Fakes'; +import { OmnisharpChannelObserver } from '../../../src/observers/OmnisharpChannelObserver'; +import { OmnisharpFailure } from '../../../src/omnisharp/loggingEvents'; + +suite("OmnisharpChannelObserver", () => { + suiteSetup(() => should()); + test(`OmnisharpFailure: Shows the channel`, () => { + let event = new OmnisharpFailure("errorMessage", new Error("error")); + let hasShown = false; + let observer = new OmnisharpChannelObserver({ + ...getNullChannel(), + show: () => { hasShown = true; } + }); + + observer.post(event); + expect(hasShown).to.be.true; + }); +}); \ No newline at end of file diff --git a/test/unitTests/logging/OmnisharpDebugModeLoggerObserver.test.ts b/test/unitTests/logging/OmnisharpDebugModeLoggerObserver.test.ts new file mode 100644 index 000000000..57c03065e --- /dev/null +++ b/test/unitTests/logging/OmnisharpDebugModeLoggerObserver.test.ts @@ -0,0 +1,103 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import { use, should, expect } from 'chai'; +import { getNullChannel } from '../testAssets/Fakes'; +import { OmnisharpServerVerboseMessage, EventWithMessage, OmnisharpRequestMessage, OmnisharpServerEnqueueRequest, OmnisharpServerDequeueRequest, OmnisharpServerProcessRequestStart, OmnisharpEventPacketReceived, OmnisharpServerProcessRequestComplete } from '../../../src/omnisharp/loggingEvents'; +import { OmnisharpDebugModeLoggerObserver } from '../../../src/observers/OmnisharpDebugModeLoggerObserver'; + +use(require("chai-string")); + +suite("OmnisharpDebugModeLoggerObserver", () => { + suiteSetup(() => should()); + let logOutput = ""; + let observer = new OmnisharpDebugModeLoggerObserver({ + ...getNullChannel(), + append: (text: string) => { logOutput += text; }, + }); + + setup(() => { + logOutput = ""; + }); + + [ + new OmnisharpServerVerboseMessage("server verbose message") + ].forEach((event: EventWithMessage) => { + test(`${event.constructor.name}: Message is logged`, () => { + observer.post(event); + expect(logOutput).to.contain(event.message); + }); + }); + + test(`OmnisharpServerEnqueueRequest: Name and Command is logged`, () => { + let event = new OmnisharpServerEnqueueRequest("foo", "someCommand"); + observer.post(event); + expect(logOutput).to.contain(event.name); + expect(logOutput).to.contain(event.command); + }); + + test(`OmnisharpServerDequeueRequest: Name and Command is logged`, () => { + let event = new OmnisharpServerDequeueRequest("foo", "someCommand", 1); + observer.post(event); + expect(logOutput).to.contain(event.name); + expect(logOutput).to.contain(event.command); + expect(logOutput).to.contain(event.id); + }); + + test(`OmnisharpProcessRequestStart: Name is logged`, () => { + let event = new OmnisharpServerProcessRequestStart("foobar"); + observer.post(event); + expect(logOutput).to.contain(event.name); + }); + + test(`OmnisharpServer messages increase and decrease indent`, () => { + observer.post(new OmnisharpServerVerboseMessage("!indented_1")); + observer.post(new OmnisharpServerProcessRequestStart("name")); + observer.post(new OmnisharpServerVerboseMessage("indented")); + observer.post(new OmnisharpServerProcessRequestComplete()); + observer.post(new OmnisharpServerVerboseMessage("!indented_2")); + + expect(logOutput).to.startWith(" !indented_1"); + expect(logOutput).to.contain("\n indented"); + expect(logOutput).to.contain("\n !indented_2"); + }); + + suite('OmnisharpEventPacketReceived', () => { + test(`Information messages with name OmniSharp.Middleware.LoggingMiddleware and follow pattern /^\/[\/\w]+: 200 \d+ms/ are logged`, () => { + let event = new OmnisharpEventPacketReceived("INFORMATION", "OmniSharp.Middleware.LoggingMiddleware", "/codecheck: 200 339ms"); + observer.post(event); + expect(logOutput).to.contain(event.message); + expect(logOutput).to.contain(event.name); + }); + + [ + new OmnisharpEventPacketReceived("TRACE", "foo", "someMessage"), + new OmnisharpEventPacketReceived("DEBUG", "foo", "someMessage"), + new OmnisharpEventPacketReceived("INFORMATION", "foo", "someMessage"), + new OmnisharpEventPacketReceived("WARNING", "foo", "someMessage"), + new OmnisharpEventPacketReceived("ERROR", "foo", "someMessage"), + new OmnisharpEventPacketReceived("CRITICAL", "foo", "someMessage"), + ].forEach((event: OmnisharpEventPacketReceived) => { + test(`${event.logLevel} messages are not logged`, () => { + observer.post(event); + expect(logOutput).to.be.empty; + }); + }); + }); + + suite('OmnisharpRequestMessage', () => { + test(`Request Command and Id is logged`, () => { + let event = new OmnisharpRequestMessage({ command: "someCommand", onSuccess: () => { }, onError: () => { } }, 1); + observer.post(event); + expect(logOutput).to.contain(event.id); + expect(logOutput).to.contain(event.request.command); + }); + + test(`Request Data is logged when it is not empty`, () => { + let event = new OmnisharpRequestMessage({ command: "someCommand", onSuccess: () => { }, onError: () => { }, data: "someData" }, 1); + observer.post(event); + expect(logOutput).to.contain(event.request.data); + }); + }); +}); diff --git a/test/unitTests/logging/OmnisharpLoggerObserver.test.ts b/test/unitTests/logging/OmnisharpLoggerObserver.test.ts new file mode 100644 index 000000000..25a601268 --- /dev/null +++ b/test/unitTests/logging/OmnisharpLoggerObserver.test.ts @@ -0,0 +1,185 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import { should, expect } from 'chai'; +import { getNullChannel } from '../testAssets/Fakes'; +import { OmnisharpLoggerObserver } from '../../../src/observers/OmnisharpLoggerObserver'; +import { OmnisharpServerMsBuildProjectDiagnostics, EventWithMessage, OmnisharpServerOnStdErr, OmnisharpServerMessage, OmnisharpServerOnServerError, OmnisharpInitialisation, OmnisharpLaunch, OmnisharpServerOnError, OmnisharpFailure, OmnisharpEventPacketReceived } from '../../../src/omnisharp/loggingEvents'; + +suite("OmnisharpLoggerObserver", () => { + suiteSetup(() => should()); + + let logOutput = ""; + let observer = new OmnisharpLoggerObserver({ + ...getNullChannel(), + append: (text: string) => { logOutput += text; }, + }); + + setup(() => { + logOutput = ""; + }); + + suite('OmnisharpServerMsBuildProjectDiagnostics', () => { + + test("Logged message is empty if there are no warnings and erros", () => { + let event = new OmnisharpServerMsBuildProjectDiagnostics({ + FileName: "someFile", + Warnings: [], + Errors: [] + }); + observer.post(event); + expect(logOutput).to.be.empty; + }); + + test(`Logged message contains the Filename if there is atleast one error or warning`, () => { + let event = new OmnisharpServerMsBuildProjectDiagnostics({ + FileName: "someFile", + Warnings: [{ FileName: "warningFile", LogLevel: "", Text: "", StartLine: 0, EndLine: 0, StartColumn: 0, EndColumn: 0 }], + Errors: [] + }); + observer.post(event); + expect(logOutput).to.contain(event.diagnostics.FileName); + }); + + [ + new OmnisharpServerMsBuildProjectDiagnostics({ + FileName: "someFile", + Warnings: [{ FileName: "warningFile", LogLevel: "", Text: "someWarningText", StartLine: 1, EndLine: 2, StartColumn: 3, EndColumn: 4 }], + Errors: [{ FileName: "errorFile", LogLevel: "", Text: "someErrorText", StartLine: 5, EndLine: 6, StartColumn: 7, EndColumn: 8 }] + }) + ].forEach((event: OmnisharpServerMsBuildProjectDiagnostics) => { + test(`Logged message contains the Filename, StartColumn, StartLine and Text for the diagnostic warnings`, () => { + observer.post(event); + event.diagnostics.Warnings.forEach(element => { + expect(logOutput).to.contain(element.FileName); + expect(logOutput).to.contain(element.StartLine); + expect(logOutput).to.contain(element.StartColumn); + expect(logOutput).to.contain(element.Text); + }); + }); + + test(`Logged message contains the Filename, StartColumn, StartLine and Text for the diagnostics errors`, () => { + observer.post(event); + event.diagnostics.Errors.forEach(element => { + expect(logOutput).to.contain(element.FileName); + expect(logOutput).to.contain(element.StartLine); + expect(logOutput).to.contain(element.StartColumn); + expect(logOutput).to.contain(element.Text); + }); + }); + }); + }); + + [ + new OmnisharpServerOnStdErr("on std error message"), + new OmnisharpServerMessage("server message"), + ].forEach((event: EventWithMessage) => { + test(`${event.constructor.name}: Message is logged`, () => { + observer.post(event); + expect(logOutput).to.contain(event.message); + }); + }); + + test(`OmnisharpServerOnServerError: Message is logged`, () => { + let event = new OmnisharpServerOnServerError("on server error message"); + observer.post(event); + expect(logOutput).to.contain(event.err); + }); + + + [ + new OmnisharpInitialisation(new Date(5), "somePath"), + ].forEach((event: OmnisharpInitialisation) => { + test(`${event.constructor.name}: TimeStamp and SolutionPath are logged`, () => { + observer.post(event); + expect(logOutput).to.contain(event.timeStamp.toLocaleString()); + expect(logOutput).to.contain(event.solutionPath); + }); + }); + + test('OmnisharpFailure: Failure message is logged', () => { + let event = new OmnisharpFailure("failureMessage", new Error("errorMessage")); + observer.post(event); + expect(logOutput).to.contain(event.message); + }); + + suite('OmnisharpEventPacketReceived', () => { + [ + new OmnisharpEventPacketReceived("TRACE", "foo", "someMessage"), + new OmnisharpEventPacketReceived("DEBUG", "foo", "someMessage"), + new OmnisharpEventPacketReceived("INFORMATION", "foo", "someMessage"), + new OmnisharpEventPacketReceived("WARNING", "foo", "someMessage"), + new OmnisharpEventPacketReceived("ERROR", "foo", "someMessage"), + new OmnisharpEventPacketReceived("CRITICAL", "foo", "someMessage"), + ].forEach((event: OmnisharpEventPacketReceived) => { + test(`${event.logLevel} messages are logged with name and the message`, () => { + observer.post(event); + expect(logOutput).to.contain(event.name); + expect(logOutput).to.contain(event.message); + }); + }); + + test('Throws error on unknown log level', () => { + let event = new OmnisharpEventPacketReceived("random log level", "foo", "someMessage"); + let fn = function () { observer.post(event); }; + expect(fn).to.throw(Error); + }); + + test(`Information messages with name OmniSharp.Middleware.LoggingMiddleware and follow pattern /^\/[\/\w]+: 200 \d+ms/ are not logged`, () => { + let event = new OmnisharpEventPacketReceived("INFORMATION", "OmniSharp.Middleware.LoggingMiddleware", "/codecheck: 200 339ms"); + observer.post(event); + expect(logOutput).to.be.empty; + }); + }); + + suite('OmnisharpLaunch', () => { + [ + new OmnisharpLaunch("5.8.0", "someCommand", 4), + new OmnisharpLaunch(undefined, "someCommand", 4) + ].forEach((event: OmnisharpLaunch) => { + + test(`Command and Pid are displayed`, () => { + observer.post(event); + expect(logOutput).to.contain(event.command); + expect(logOutput).to.contain(event.pid); + }); + + test(`Message is displayed depending on usingMono value`, () => { + observer.post(event); + if (event.monoVersion) { + expect(logOutput).to.contain("OmniSharp server started with Mono 5.8.0"); + } + else { + expect(logOutput).to.contain("OmniSharp server started"); + } + }); + }); + }); + + suite('OmnisharpServerOnError', () => { + test(`Doesnot throw error if FileName is null`, () => { + let event = new OmnisharpServerOnError({ Text: "someText", FileName: null, Line: 1, Column: 2 }); + let fn = function () { observer.post(event); }; + expect(fn).to.not.throw(Error); + }); + + [ + new OmnisharpServerOnError({ Text: "someText", FileName: "someFile", Line: 1, Column: 2 }), + ].forEach((event: OmnisharpServerOnError) => { + test(`Contains the error message text`, () => { + observer.post(event); + expect(logOutput).to.contain(event.errorMessage.Text); + }); + + test(`Contains the error message FileName, Line and column if FileName is not null`, () => { + observer.post(event); + if (event.errorMessage.FileName) { + expect(logOutput).to.contain(event.errorMessage.FileName); + expect(logOutput).to.contain(event.errorMessage.Line); + expect(logOutput).to.contain(event.errorMessage.Column); + } + }); + }); + }); +}); diff --git a/test/unitTests/logging/OmnisharpStatusBarObserver.test.ts b/test/unitTests/logging/OmnisharpStatusBarObserver.test.ts new file mode 100644 index 000000000..a46536d0f --- /dev/null +++ b/test/unitTests/logging/OmnisharpStatusBarObserver.test.ts @@ -0,0 +1,96 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { StatusBarItem } from '../../../src/vscodeAdapter'; +import { OmnisharpOnBeforeServerInstall, OmnisharpOnBeforeServerStart, OmnisharpServerOnServerError, OmnisharpServerOnStart, OmnisharpServerOnStop, DownloadStart, InstallationStart, DownloadProgress } from '../../../src/omnisharp/loggingEvents'; +import { expect, should } from 'chai'; +import { OmnisharpStatusBarObserver } from '../../../src/observers/OmnisharpStatusBarObserver'; + +suite('OmnisharpStatusBarObserver', () => { + suiteSetup(() => should()); + let showCalled: boolean; + let hideCalled: boolean; + + setup(() => { + statusBarItem.text = undefined; + statusBarItem.color = undefined; + statusBarItem.command = undefined; + statusBarItem.tooltip = undefined; + showCalled = false; + hideCalled = false; + }); + + let statusBarItem = { + show: () => { showCalled = true; }, + hide: () => { hideCalled = true; } + }; + + let observer = new OmnisharpStatusBarObserver( statusBarItem); + + test('OnServerError: Status bar is shown with the error text', () => { + let event = new OmnisharpServerOnServerError("someError"); + observer.post(event); + expect(showCalled).to.be.true; + expect(statusBarItem.text).to.equal(`$(flame)`); + expect(statusBarItem.command).to.equal('o.showOutput'); + expect(statusBarItem.tooltip).to.equal('Error starting OmniSharp'); + }); + + test('OnBeforeServerInstall: Status bar is shown with the installation text', () => { + let event = new OmnisharpOnBeforeServerInstall(); + observer.post(event); + expect(showCalled).to.be.true; + expect(statusBarItem.text).to.be.equal('$(flame) Installing OmniSharp...'); + expect(statusBarItem.command).to.equal('o.showOutput'); + }); + + test('OnBeforeServerStart: Status bar is shown with the starting text', () => { + let event = new OmnisharpOnBeforeServerStart(); + observer.post(event); + expect(showCalled).to.be.true; + expect(statusBarItem.text).to.be.equal('$(flame)'); + expect(statusBarItem.command).to.equal('o.showOutput'); + expect(statusBarItem.tooltip).to.equal('Starting OmniSharp server'); + }); + + test('OnServerStart: Status bar is shown with the flame and "Running" text', () => { + let event = new OmnisharpServerOnStart(); + observer.post(event); + expect(showCalled).to.be.true; + expect(statusBarItem.text).to.be.equal('$(flame)'); + expect(statusBarItem.command).to.equal('o.showOutput'); + expect(statusBarItem.tooltip).to.be.equal('OmniSharp server is running'); + }); + + test('OnServerStop: Status bar is hidden and the attributes are set to undefined', () => { + let event = new OmnisharpServerOnStop(); + observer.post(event); + expect(hideCalled).to.be.true; + expect(statusBarItem.text).to.be.undefined; + expect(statusBarItem.command).to.be.undefined; + expect(statusBarItem.color).to.be.undefined; + }); + + test('DownloadStart: Text and tooltip are set ', () => { + let event = new DownloadStart("somePackage"); + observer.post(event); + expect(statusBarItem.text).to.contain("Downloading packages"); + expect(statusBarItem.tooltip).to.contain(event.packageDescription); + }); + + test('InstallationProgress: Text and tooltip are set', () => { + let event = new InstallationStart("somePackage"); + observer.post(event); + expect(statusBarItem.text).to.contain("Installing packages"); + expect(statusBarItem.tooltip).to.contain(event.packageDescription); + }); + + test('DownloadProgress: Tooltip contains package description and download percentage', () => { + let event = new DownloadProgress(50, "somePackage"); + observer.post(event); + expect(statusBarItem.tooltip).to.contain(event.packageDescription); + expect(statusBarItem.tooltip).to.contain(event.downloadPercentage); + }); +}); \ No newline at end of file diff --git a/test/unitTests/logging/ProjectStatusBarObserver.test.ts b/test/unitTests/logging/ProjectStatusBarObserver.test.ts new file mode 100644 index 000000000..156dd91f7 --- /dev/null +++ b/test/unitTests/logging/ProjectStatusBarObserver.test.ts @@ -0,0 +1,62 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { expect, should } from 'chai'; +import { getWorkspaceInformationUpdated, getMSBuildWorkspaceInformation } from '../testAssets/Fakes'; +import { StatusBarItem } from '../../../src/vscodeAdapter'; +import { ProjectStatusBarObserver } from '../../../src/observers/ProjectStatusBarObserver'; +import { OmnisharpOnMultipleLaunchTargets, OmnisharpServerOnStop } from '../../../src/omnisharp/loggingEvents'; + +suite('ProjectStatusBarObserver', () => { + suiteSetup(() => should()); + + let showCalled: boolean; + let hideCalled: boolean; + let statusBarItem = { + show: () => { showCalled = true; }, + hide: () => { hideCalled = true; } + }; + let observer = new ProjectStatusBarObserver(statusBarItem); + + setup(() => { + showCalled = false; + hideCalled = false; + }); + + test('OnServerStop: Status bar is hidden and the attributes are set to undefined', () => { + let event = new OmnisharpServerOnStop(); + observer.post(event); + expect(hideCalled).to.be.true; + expect(statusBarItem.text).to.be.undefined; + expect(statusBarItem.command).to.be.undefined; + expect(statusBarItem.color).to.be.undefined; + }); + + test('OnMultipleLaunchTargets: Status bar is shown with the select project option and the comand to pick a project', () => { + let event = new OmnisharpOnMultipleLaunchTargets([]); + observer.post(event); + expect(showCalled).to.be.true; + expect(statusBarItem.text).to.contain('Select project'); + expect(statusBarItem.command).to.equal('o.pickProjectAndStart'); + }); + + suite('WorkspaceInformationUpdated', () => { + test('Project status is hidden if there is no MSBuild Object', () => { + let event = getWorkspaceInformationUpdated(null); + observer.post(event); + expect(hideCalled).to.be.true; + expect(statusBarItem.text).to.be.undefined; + expect(statusBarItem.command).to.be.undefined; + }); + + test('Project status is shown if there is an MSBuild object', () => { + let event = getWorkspaceInformationUpdated(getMSBuildWorkspaceInformation("somePath", [])); + observer.post(event); + expect(showCalled).to.be.true; + expect(statusBarItem.text).to.contain(event.info.MsBuild.SolutionPath); + expect(statusBarItem.command).to.equal('o.pickProjectAndStart'); + }); + }); +}); \ No newline at end of file diff --git a/test/unitTests/logging/TelemetryObserver.test.ts b/test/unitTests/logging/TelemetryObserver.test.ts new file mode 100644 index 000000000..e7398fab5 --- /dev/null +++ b/test/unitTests/logging/TelemetryObserver.test.ts @@ -0,0 +1,114 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import { should, expect } from 'chai'; +import { TelemetryObserver } from '../../../src/observers/TelemetryObserver'; +import { PlatformInformation } from '../../../src/platform'; +import { PackageInstallation, InstallationFailure, InstallationSuccess, TestExecutionCountReport, TelemetryEventWithMeasures, OmnisharpDelayTrackerEventMeasures, OmnisharpStart } from '../../../src/omnisharp/loggingEvents'; +import { getNullTelemetryReporter } from '../testAssets/Fakes'; +import { Package } from '../../../src/packageManager/Package'; +import { PackageError } from '../../../src/packageManager/PackageError'; + +const chai = require('chai'); +chai.use(require('chai-arrays')); + +suite('TelemetryReporterObserver', () => { + suiteSetup(() => should()); + let platformInfo = new PlatformInformation("platform", "architecture"); + let name = ""; + let property: { [key: string]: string } = null; + let measure: { [key: string]: number }[] = []; + let observer = new TelemetryObserver(platformInfo, () => { + return { + ...getNullTelemetryReporter, + sendTelemetryEvent: (eventName: string, properties?: { [key: string]: string }, measures?: { [key: string]: number }) => { + name += eventName; + property = properties; + measure.push(measures); + } + }; + }); + + setup(() => { + name = ""; + property = null; + measure = []; + }); + + test('PackageInstallation: AcquisitionStart is reported', () => { + let event = new PackageInstallation("somePackage"); + observer.post(event); + expect(name).to.be.not.empty; + }); + + test('InstallationSuccess: Telemetry props contain installation stage', () => { + let event = new InstallationSuccess(); + observer.post(event); + expect(name).to.be.equal("Acquisition"); + expect(property).to.have.property("installStage", "completeSuccess"); + }); + + [ + new OmnisharpDelayTrackerEventMeasures("someEvent", { someKey: 1 }), + new OmnisharpStart("startEvent", { someOtherKey: 2 }) + ].forEach((event: TelemetryEventWithMeasures) => { + test(`${event.constructor.name}: SendTelemetry event is called with the name and measures`, () => { + observer.post(event); + expect(name).to.contain(event.eventName); + expect(measure).to.be.containingAllOf([event.measures]); + }); + }); + + suite('InstallationFailure', () => { + test("Telemetry Props contains platform information, install stage and an event name", () => { + let event = new InstallationFailure("someStage", "someError"); + observer.post(event); + expect(property).to.have.property("platform.architecture", platformInfo.architecture); + expect(property).to.have.property("platform.platform", platformInfo.platform); + expect(property).to.have.property("installStage"); + expect(name).to.not.be.empty; + }); + + test(`Telemetry Props contains message and packageUrl if error is package error`, () => { + let error = new PackageError("someError", { "description": "foo", "url": "someurl" }); + let event = new InstallationFailure("someStage", error); + observer.post(event); + expect(property).to.have.property("error.message", error.message); + expect(property).to.have.property("error.packageUrl", error.pkg.url); + }); + }); + + suite('TestExecutionCountReport', () => { + test('SendTelemetryEvent is called for "RunTest" and "DebugTest"', () => { + let event = new TestExecutionCountReport({ "framework1": 20 }, { "framework2": 30 }); + observer.post(event); + expect(name).to.contain("RunTest"); + expect(name).to.contain("DebugTest"); + expect(measure).to.be.containingAllOf([event.debugCounts, event.runCounts]); + }); + + test('SendTelemetryEvent is not called for empty run count', () => { + let event = new TestExecutionCountReport({ "framework1": 20 }, null); + observer.post(event); + expect(name).to.not.contain("RunTest"); + expect(name).to.contain("DebugTest"); + expect(measure).to.be.containingAllOf([event.debugCounts]); + }); + + test('SendTelemetryEvent is not called for empty debug count', () => { + let event = new TestExecutionCountReport(null, { "framework1": 20 }); + observer.post(event); + expect(name).to.contain("RunTest"); + expect(name).to.not.contain("DebugTest"); + expect(measure).to.be.containingAllOf([event.runCounts]); + }); + + test('SendTelemetryEvent is not called for empty debug and run counts', () => { + let event = new TestExecutionCountReport(null, null); + observer.post(event); + expect(name).to.be.empty; + expect(measure).to.be.empty; + }); + }); +}); diff --git a/test/unitTests/logging/WarningMessageObserver.test.ts b/test/unitTests/logging/WarningMessageObserver.test.ts new file mode 100644 index 000000000..c7b896f2a --- /dev/null +++ b/test/unitTests/logging/WarningMessageObserver.test.ts @@ -0,0 +1,174 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { WarningMessageObserver } from '../../../src/observers/WarningMessageObserver'; +import { assert, use as chaiUse, expect, should } from 'chai'; +import { getFakeVsCode, getMSBuildDiagnosticsMessage, getOmnisharpMSBuildProjectDiagnosticsEvent, getOmnisharpServerOnErrorEvent } from '../testAssets/Fakes'; +import { BaseEvent } from '../../../src/omnisharp/loggingEvents'; +import { vscode } from '../../../src/vscodeAdapter'; +import { TestScheduler } from 'rxjs/testing/TestScheduler'; +import { Observable } from 'rxjs/Observable'; +import "rxjs/add/operator/map"; +import "rxjs/add/operator/debounceTime"; +import 'rxjs/add/operator/timeout'; +import 'rxjs/add/observable/fromPromise'; +import 'rxjs/add/observable/timer'; +import { Subject } from 'rxjs/Subject'; + +chaiUse(require('chai-as-promised')); +chaiUse(require('chai-string')); + +suite('WarningMessageObserver', () => { + suiteSetup(() => should()); + + let doClickOk: () => void; + let doClickCancel: () => void; + let signalCommandDone: () => void; + let commandDone = new Promise(resolve => { + signalCommandDone = () => { resolve(); }; + }); + + let warningMessages: string[]; + let invokedCommand: string; + let scheduler: TestScheduler; + let assertionObservable: Subject; + let observer: WarningMessageObserver; + let vscode: vscode = getFakeVsCode(); + + vscode.window.showWarningMessage = async (message: string, ...items: T[]) => { + warningMessages.push(message); + assertionObservable.next(`[${warningMessages.length}] ${message}`); + return new Promise(resolve => { + doClickCancel = () => { + resolve(undefined); + }; + + doClickOk = () => { + resolve(items[0]); + }; + }); + }; + + vscode.commands.executeCommand = (command: string, ...rest: any[]) => { + invokedCommand = command; + signalCommandDone(); + return undefined; + }; + + setup(() => { + assertionObservable = new Subject(); + scheduler = new TestScheduler(assert.deepEqual); + scheduler.maxFrames = 9000; + observer = new WarningMessageObserver(vscode, scheduler); + warningMessages = []; + invokedCommand = undefined; + commandDone = new Promise(resolve => { + signalCommandDone = () => { resolve(); }; + }); + }); + + test('OmnisharpServerMsBuildProjectDiagnostics: No action is taken if the errors array is empty', () => { + let event = getOmnisharpMSBuildProjectDiagnosticsEvent("someFile", + [getMSBuildDiagnosticsMessage("warningFile", "", "", 0, 0, 0, 0)], + []); + observer.post(event); + expect(invokedCommand).to.be.undefined; + }); + + [ + getOmnisharpMSBuildProjectDiagnosticsEvent("someFile", + [getMSBuildDiagnosticsMessage("warningFile", "", "", 1, 2, 3, 4)], + [getMSBuildDiagnosticsMessage("errorFile", "", "", 5, 6, 7, 8)]), + getOmnisharpServerOnErrorEvent("someText", "someFile", 1, 2) + ].forEach((event: BaseEvent) => { + suite(`${event.constructor.name}`, () => { + + test(`When the event is fired then a warning message is displayed`, () => { + let marble = `${timeToMarble(1500)}a`; + let marble_event_map = { a: event }; + let eventList = scheduler.createHotObservable(marble, marble_event_map); + eventList.subscribe(e => observer.post(e)); + scheduler.expectObservable(assertionObservable).toBe(`${timeToMarble(3000)}a`, { a: '[1] Some projects have trouble loading. Please review the output for more details.' }); + scheduler.flush(); + + expect(warningMessages.length).to.be.equal(1); + expect(warningMessages[0]).to.be.equal("Some projects have trouble loading. Please review the output for more details."); + }); + + test(`When events are fired rapidly, then they are debounced by 1500 ms`, () => { + let marble = `${timeToMarble(1000)}a${timeToMarble(500)}b${timeToMarble(500)}c`; + + let eventB = getOmnisharpMSBuildProjectDiagnosticsEvent("BFile", + [getMSBuildDiagnosticsMessage("warningFile", "", "", 1, 2, 3, 4)], + [getMSBuildDiagnosticsMessage("errorFile", "", "", 5, 6, 7, 8)]); + + let eventC = getOmnisharpMSBuildProjectDiagnosticsEvent("CFile", + [getMSBuildDiagnosticsMessage("warningFile", "", "", 1, 2, 3, 4)], + [getMSBuildDiagnosticsMessage("errorFile", "", "", 5, 6, 7, 8)]); + + let marble_event_map = { a: event, b: eventB, c: eventC }; + let eventList = scheduler.createHotObservable(marble, marble_event_map); + eventList.subscribe(e => observer.post(e)); + scheduler.expectObservable(assertionObservable).toBe(`${timeToMarble(3520)}a`, { a: '[1] Some projects have trouble loading. Please review the output for more details.' }); + scheduler.flush(); + + expect(warningMessages.length).to.be.equal(1); + expect(warningMessages[0]).to.be.equal("Some projects have trouble loading. Please review the output for more details."); + }); + + test(`When events are 1500 ms apart, then they are not debounced`, () => { + let marble = `${timeToMarble(1000)}a${timeToMarble(490)}b${timeToMarble(1500)}c`; + + let eventB = getOmnisharpMSBuildProjectDiagnosticsEvent("BFile", + [getMSBuildDiagnosticsMessage("warningFile", "", "", 1, 2, 3, 4)], + [getMSBuildDiagnosticsMessage("errorFile", "", "", 5, 6, 7, 8)]); + + let eventC = getOmnisharpMSBuildProjectDiagnosticsEvent("CFile", + [getMSBuildDiagnosticsMessage("warningFile", "", "", 1, 2, 3, 4)], + [getMSBuildDiagnosticsMessage("errorFile", "", "", 5, 6, 7, 8)]); + + let marble_event_map = { a: event, b: eventB, c: eventC }; + let eventList = scheduler.createHotObservable(marble, marble_event_map); + eventList.subscribe(e => observer.post(e)); + scheduler.expectObservable(assertionObservable).toBe(`${timeToMarble(3000)}a${timeToMarble(1500)}b`, + { + a: '[1] Some projects have trouble loading. Please review the output for more details.', + b: '[2] Some projects have trouble loading. Please review the output for more details.' + }); + scheduler.flush(); + expect(warningMessages.length).to.be.equal(2); + expect(warningMessages[0]).to.be.equal("Some projects have trouble loading. Please review the output for more details."); + }); + + test(`Given a warning message, when the user clicks ok the command is executed`, async () => { + let marble = `${timeToMarble(1500)}a`; + let eventList = scheduler.createHotObservable(marble, { a: event }); + scheduler.expectObservable(eventList.map(e => observer.post(e))); + scheduler.flush(); + doClickOk(); + await commandDone; + expect(invokedCommand).to.be.equal("o.showOutput"); + }); + + test(`Given a warning message, when the user clicks cancel the command is not executed`, async () => { + let marble = `${timeToMarble(1500)}a--|`; + let eventList = scheduler.createHotObservable(marble, { a: event }); + scheduler.expectObservable(eventList.map(e => observer.post(e))); + scheduler.flush(); + doClickCancel(); + await expect(Observable.fromPromise(commandDone).timeout(1).toPromise()).to.be.rejected; + expect(invokedCommand).to.be.undefined; + }); + }); + }); +}); + +function timeToMarble(timeinMilliseconds: number): string { + let marble = ""; + for (let i = 0; i < (timeinMilliseconds / 10); i++) { + marble += "-"; + } + return marble; +} \ No newline at end of file diff --git a/test/unitTests/testAssets/CreateTestZip.ts b/test/unitTests/testAssets/CreateTestZip.ts new file mode 100644 index 000000000..8b0ce5ee3 --- /dev/null +++ b/test/unitTests/testAssets/CreateTestZip.ts @@ -0,0 +1,52 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as archiver from 'archiver'; +import * as fs from 'async-file'; + +export const Files = [ + { + content: "File 1", + path: "file1.txt", + + }, + { + content: "File 2", + path: "folder/file2.txt" + } +]; + +export const Binaries = [ + { + content: "Binary 1", + path: "binary1.txt" + }, +]; + + +export async function createTestZipAsync(dirPath: string, filesToAdd: Array<{ content: string, path: string }>): Promise<{}> { + let output = fs.createWriteStream(dirPath); + + return new Promise((resolve, reject) => { + output.on('close', function () { + resolve(); // the installer needs to wait for the filestream to be closed here + }); + + let archive = archiver('zip'); + archive.on('warning', function (err: any) { + if (err.code === 'ENOENT') { + console.log(err); + } else { + // throw error + reject(err); + } + }); + + archive.on('error', reject); + archive.pipe(output); + filesToAdd.forEach(elem => archive.append(elem.content, { name: elem.path })); + archive.finalize(); + }); +} \ No newline at end of file diff --git a/test/unitTests/testAssets/Fakes.ts b/test/unitTests/testAssets/Fakes.ts new file mode 100644 index 000000000..1a83637e3 --- /dev/null +++ b/test/unitTests/testAssets/Fakes.ts @@ -0,0 +1,140 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as vscode from '../../../src/vscodeAdapter'; +import * as protocol from '../../../src/omnisharp/protocol'; +import { DocumentSelector, MessageItem, TextDocument, Uri, GlobPattern } from '../../../src/vscodeAdapter'; +import { ITelemetryReporter } from '../../../src/observers/TelemetryObserver'; +import { MSBuildDiagnosticsMessage } from '../../../src/omnisharp/protocol'; +import { OmnisharpServerMsBuildProjectDiagnostics, OmnisharpServerOnError, OmnisharpServerUnresolvedDependencies, WorkspaceInformationUpdated } from '../../../src/omnisharp/loggingEvents'; + +export const getNullChannel = (): vscode.OutputChannel => { + let returnChannel: vscode.OutputChannel = { + name: "", + append: (value: string) => { }, + appendLine: (value: string) => { }, + clear: () => { }, + show: (preserveFocusOrColumn?: boolean | vscode.ViewColumn, preserveFocus?: boolean) => { }, + hide: () => { }, + dispose: () => { } + }; + return returnChannel; +}; + +export const getNullTelemetryReporter = (): ITelemetryReporter => { + let reporter: ITelemetryReporter = { + sendTelemetryEvent: (eventName: string, properties?: { [key: string]: string }, measures?: { [key: string]: number }) => { } + }; + + return reporter; +}; + +export const getNullWorkspaceConfiguration = (): vscode.WorkspaceConfiguration => { + let workspace: vscode.WorkspaceConfiguration = { + get: (section: string): T| undefined => { + return undefined; + }, + has: (section: string) => { return undefined; }, + inspect: () => { + return { + key: undefined + }; + }, + update: async () => { return Promise.resolve(); }, + }; + return workspace; +}; + +export function getOmnisharpMSBuildProjectDiagnosticsEvent(fileName: string, warnings: MSBuildDiagnosticsMessage[], errors: MSBuildDiagnosticsMessage[]): OmnisharpServerMsBuildProjectDiagnostics { + return new OmnisharpServerMsBuildProjectDiagnostics({ + FileName: fileName, + Warnings: warnings, + Errors: errors + }); +} + +export function getMSBuildDiagnosticsMessage(logLevel: string, + fileName: string, + text: string, + startLine: number, + startColumn: number, + endLine: number, + endColumn: number): MSBuildDiagnosticsMessage { + return { + LogLevel: logLevel, + FileName: fileName, + Text: text, + StartLine: startLine, + StartColumn: startColumn, + EndLine: endLine, + EndColumn: endColumn + }; +} + +export function getOmnisharpServerOnErrorEvent(text: string, fileName: string, line: number, column: number): OmnisharpServerOnError { + return new OmnisharpServerOnError({ + Text: text, + FileName: fileName, + Line: line, + Column: column + }); +} + +export function getUnresolvedDependenices(fileName: string): OmnisharpServerUnresolvedDependencies { + return new OmnisharpServerUnresolvedDependencies({ + UnresolvedDependencies: [], + FileName: fileName + }); +} + +export function getFakeVsCode(): vscode.vscode { + return { + commands: { + executeCommand: (command: string, ...rest: any[]) => { + throw new Error("Not Implemented"); + } + }, + languages: { + match: (selector: DocumentSelector, document: TextDocument) => { + throw new Error("Not Implemented"); + } + }, + window: { + activeTextEditor: undefined, + showInformationMessage: (message: string, ...items: string[]) => { + throw new Error("Not Implemented"); + }, + showWarningMessage: (message: string, ...items: T[]) => { + throw new Error("Not Implemented"); + } + }, + workspace: { + getConfiguration: (section?: string, resource?: Uri) => { + throw new Error("Not Implemented"); + }, + asRelativePath: (pathOrUri: string | Uri, includeWorkspaceFolder?: boolean) => { + throw new Error("Not Implemented"); + }, + createFileSystemWatcher: (globPattern: GlobPattern, ignoreCreateEvents?: boolean, ignoreChangeEvents?: boolean, ignoreDeleteEvents?: boolean) => { + throw new Error("Not Implemented"); + } + } + }; +} + +export function getMSBuildWorkspaceInformation(msBuildSolutionPath: string, msBuildProjects: protocol.MSBuildProject[]): protocol.MsBuildWorkspaceInformation { + return { + SolutionPath: msBuildSolutionPath, + Projects: msBuildProjects + }; +} + +export function getWorkspaceInformationUpdated(msbuild: protocol.MsBuildWorkspaceInformation): WorkspaceInformationUpdated { + let a: protocol.WorkspaceInformationResponse = { + MsBuild: msbuild + }; + + return new WorkspaceInformationUpdated(a); +} \ No newline at end of file diff --git a/test/unitTests/testAssets/MockHttpServerRequestHandler.ts b/test/unitTests/testAssets/MockHttpServerRequestHandler.ts new file mode 100644 index 000000000..97b81054d --- /dev/null +++ b/test/unitTests/testAssets/MockHttpServerRequestHandler.ts @@ -0,0 +1,27 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +export interface MockHttpServerRequestHandler { + method: string; + path: string; + reply: { + status: number; + headers?: any; + body: any; + }; + +} + +export function getRequestHandler(method: string, path: string, reply_status: number, reply_headers?: any, reply_body?: any): MockHttpServerRequestHandler { + return { + method, + path, + reply: { + status: reply_status, + headers: reply_headers, + body: reply_body + } + }; +} \ No newline at end of file diff --git a/test/unitTests/testAssets/private.pem b/test/unitTests/testAssets/private.pem new file mode 100644 index 000000000..9b11477cc --- /dev/null +++ b/test/unitTests/testAssets/private.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAu1cmHrPygWBVWr0ng17mEXxW+jgre5vi39GLDXbSczM6rFJ7 +M0Um/4UhSWttcnP48ctg0osm4cQRrgC/F05MCQyPWFmq0/SV+Ct86KM1jRpW0nlw +fqX7kxZfA6aKR3XJb/PNhX/LrKMCj3hTlEmTvJOJmCQLYQ9jff59L7HR6CuY1368 +dHz4pH4if2OmYf3GABcQqunXe/1VMRvdWQbXERbbHYuGstY11bHfc0t6zRhC3SqK +WCXp+1q79mUfV6hwOPP+skdoOFi0CDwvWXFkXvrri/Iu3G+YUIxhStkvJlZtdK2O +pwX7sGc722QqIFT0okcrvS4ksRgbtmbWURV2sQIDAQABAoIBAD9ITw4sBw0A95Qx +NTnBQsJBWDgp5TZaECc+51PjAW/8rCMtsYQ+JdBGrlnYuh3hYwR6iPhWHQpCax52 +DhbXUgP0hC96CqSSiF5OgmErUJmbfhyW/RMrCnJDKlFXXnqJJUR1/MTNyIVGg0Tn +hoQe3pLi26XS9y0QP7F919fWn2tnSbNaMrnMQoH4gD0GfrAH20zhFsAvmaNY7QGv +FVqUAIQLVDwnHGiLnEWgmOsA8G9NgwHaB3m20Eqmau6WbWbefGsaglhz2/t1yVZt +jDZBXSfb7FJpUd0MqXB56oe7ScUfk/S1pG5vv/DEXuN18juMhcYQE3gHJg08O/ys +6J23DkkCgYEA9uSQJiMZx0SFGE91gCDHy0vKddt15bOq2eD6t2RMZ01aRoic6oAj +Ox/co2zLNKaFjD+SZhqRCXcSUopV8zjzcZw7FXWc9w9qjuGTaar3v0dduyAd6SNl +l+iiLfc7m1P5ZJt8styTm7UKi6ZortuxxVDq+uRqw5vEAYHyaHfdUdMCgYEAwkA5 +zCLR8pqRDjGcMDd3wxjOuaXdhjRv/Q1V9bcxamvsOFrL9VvvfrVoFrmgW8uc1vSW +q08b5W0N8y6R+4OFkWh9RW+RQEC1ScJ1xLB4FDrHWUit5oCCTlU8MxOH6Z7dnKF7 +IaKqRSXYDiFcRjgX8OmiY36+RGCg/NhrZPXU/usCgYB2QNeCTMGmHf2ZvUVMT2ci +ynR4qtr3YGzu2sF7YYDu4a/hpMFz2FgHk6U8aXmTCEdi+3gFi6f4Xp3aBwRP8PE5 +c1khWCoMc8fYE9dlf0wWw/nzDNkGt7uLXROA7LASH9CODaNWkCvrInWgmd3+EqA9 +IBrMfOdeNZdWGYWf3/mTnQKBgBSxDLcO+ngyOMNfS3jjX7F7ggHKhkdWbJtzATYU +VoI0jswN9+3h5igEINtS2J8OmF1ZXndPDPSqYjMGQeydvOuZSsbLtJg4jFcYDL1v +4sqc3EFJeaS1CaxYbfou2WpsTsTxepFBp4uIFXSj3xVnwj0aVf7tME1OUbe9QetW +OGMTAoGAUSjmIjzlWW6sbCBoJJicklQmamvGd07Vg3TxP4NE1Xh7DZ4LNM3saarF +Z57gAqocWfb+RExEPnCbmhjws2THU2oUheLU2f5llubf74rrWZHzkGBnA+KCs9UT +lL1fs/fg9NjSdggkw7M1Unt9iAufZhsaGri+QTD3Jmm64q4LEKI= +-----END RSA PRIVATE KEY----- diff --git a/test/unitTests/testAssets/public.pem b/test/unitTests/testAssets/public.pem new file mode 100644 index 000000000..40f77a623 --- /dev/null +++ b/test/unitTests/testAssets/public.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDcTCCAlmgAwIBAgIJAIUrQVQLJdmOMA0GCSqGSIb3DQEBCwUAME8xCzAJBgNV +BAYTAlVTMQswCQYDVQQIDAJXQTEQMA4GA1UEBwwHU2VhdHRsZTEhMB8GA1UECgwY +SW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMB4XDTE4MDQxMTIyMTM0OFoXDTIxMDEw +NTIyMTM0OFowTzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdT +ZWF0dGxlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7VyYes/KBYFVavSeDXuYRfFb6OCt7 +m+Lf0YsNdtJzMzqsUnszRSb/hSFJa21yc/jxy2DSiybhxBGuAL8XTkwJDI9YWarT +9JX4K3zoozWNGlbSeXB+pfuTFl8DpopHdclv882Ff8usowKPeFOUSZO8k4mYJAth +D2N9/n0vsdHoK5jXfrx0fPikfiJ/Y6Zh/cYAFxCq6dd7/VUxG91ZBtcRFtsdi4ay +1jXVsd9zS3rNGELdKopYJen7Wrv2ZR9XqHA48/6yR2g4WLQIPC9ZcWRe+uuL8i7c +b5hQjGFK2S8mVm10rY6nBfuwZzvbZCogVPSiRyu9LiSxGBu2ZtZRFXaxAgMBAAGj +UDBOMB0GA1UdDgQWBBRtfbc2ltDm/xqKyiTH7o7gFFqTGDAfBgNVHSMEGDAWgBRt +fbc2ltDm/xqKyiTH7o7gFFqTGDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUA +A4IBAQCjj08qk3NBi9XcALdxL0vQSBODeflRlKgQss1hxwp2RJNVNjVXchk4DPxb +87EE9dRO9soARrHWWdl3teqnIGPSmJ65FLSWQzkeX8duQDFLwT6JRazl2sonBLeO +NUhodmrmw+Yb7ABXhITLSyuC7iPCwBVTUGbY1BGYrh9GJM5qjf4+krI+2MMw3N/o +yHmPUl4q4mmBOas+g2ngyv7B2GJL1FEnMPWJToAQdIct+K9orrEfp69sK8ydBxb/ +4FD2skruTux7AkXSfQb5WEJKswvs7yQFxVBsImiRO/EIwwCU98bsyVcPbVlBmUle +T7h9SDA3e33HulS38W625h1wWi4J +-----END CERTIFICATE----- diff --git a/tsconfig.json b/tsconfig.json index ba759a3c0..069183dbf 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,12 +6,18 @@ "lib": [ "es6" ], - "sourceMap": true, - "rootDir": "." + "inlineSourceMap": true, + "moduleResolution": "node", + "alwaysStrict": true, + "noImplicitAny": true, + "skipLibCheck": true, + "noImplicitThis": true, + "noUnusedLocals": true, + "noFallthroughCasesInSwitch": true, }, "exclude": [ - "node_modules", "syntaxes", - ".vscode-test" + ".vscode-test", + "vsix" ] } \ No newline at end of file diff --git a/tslint.json b/tslint.json index c03188cfb..f484c6414 100644 --- a/tslint.json +++ b/tslint.json @@ -5,10 +5,13 @@ "no-duplicate-variable": true, "no-var-keyword": true, "promise-must-complete": true, + "promise-function-async": true, "curly": true, "semicolon": true, "indent": [true, "spaces", 4], "file-header": [true, ".*"] }, - "rulesDirectory": ["node_modules/tslint-microsoft-contrib", "node_modules/tslint-no-unused-expression-chai/rules"] + "rulesDirectory": [ + "tslint-microsoft-contrib", + "tslint-no-unused-expression-chai"] } \ No newline at end of file diff --git a/typings/async-child-process.d.ts b/typings/async-child-process.d.ts new file mode 100644 index 000000000..528db863c --- /dev/null +++ b/typings/async-child-process.d.ts @@ -0,0 +1,11 @@ +declare module 'async-child-process' { + + import { ChildProcess } from "child_process"; + + export function join(childProcess: ChildProcess): Promise; + + export interface Result { + code: string; + signal: string; + } +} diff --git a/typings/unzip2.d.ts b/typings/unzip2.d.ts new file mode 100644 index 000000000..6621060ed --- /dev/null +++ b/typings/unzip2.d.ts @@ -0,0 +1,4 @@ + +declare module 'unzip2' { + export function Extract(options: any): WritableStream; +} diff --git a/typings/yauzl/yauzl.d.ts b/typings/yauzl/yauzl.d.ts deleted file mode 100644 index 3f90f724d..000000000 --- a/typings/yauzl/yauzl.d.ts +++ /dev/null @@ -1,48 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -declare module 'yauzl' { - - import { EventEmitter } from 'events'; - import { Readable } from 'stream'; - - export class Entry { - fileName: string; - extraFields: { id: number; data: Buffer; }[]; - comment: string; - versionMadeBy: number; - versionNeededToExtract: number; - generalPurposeBitFlag: number; - compressionMethod: number; - lastModFileTime: number; - lastModFileDate: number; - crc32: number; - compressedSize: number; - uncompressedSize: number; - fileNameLength: number; - extraFieldLength: number; - fileCommentLength: number; - internalFileAttributes: number; - externalFileAttributes: number; - relativeOffsetOfLocalHeader: number; - getLastModDate(): Date; - } - - export class ZipFile extends EventEmitter { - readEntry(); - openReadStream(entry: Entry, callback: (err?: Error, stream?: Readable)=>void); - close(); - isOpen: boolean; - entryCount: number; - comment: string; - } - - export interface IOptions { - autoClose?: boolean; - lazyEntries?: boolean; - } - - export function fromFd(fd: number, options: IOptions, callback: (err?: Error, zipfile?: ZipFile)=>void): void; -} \ No newline at end of file diff --git a/wallaby.js b/wallaby.js new file mode 100644 index 000000000..eb8180c3c --- /dev/null +++ b/wallaby.js @@ -0,0 +1,20 @@ +module.exports = function(wallaby) { + return { + env: { + type: "node" + }, + files: [ + "src/**/*.ts*", + "src/**/*.css", + "test/unitTests/**/*.ts*", + "!test/unitTests/**/*.test.ts*" + ], + tests: ["test/unitTests/**/*.test.ts*"], + + debug: true, + + setup: function(wallaby) { + wallaby.testFramework.ui("tdd"); + } + }; +};