├── .gitignore ├── .mention-bot ├── .travis.yml ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── .vscodeignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── SECURITY.md ├── ThirdPartyNotices.txt ├── appveyor.yml ├── coverconfig.json ├── gulpfile.js ├── images └── extension-icon.png ├── install.js ├── issue_template.md ├── karma-test-shim.js ├── karma.conf.js ├── localization └── xliff │ └── enu │ ├── constants │ └── localizedConstants.enu.xlf │ └── localizedPackage.json.enu.xlf ├── npm-shrinkwrap.json ├── package.json ├── package.nls.json ├── samples ├── sql2016-crud-demo.sql └── sql2016-security-demo.sql ├── scripts └── upload.ps1 ├── snippets └── pgsql.json ├── src ├── configurations │ ├── config.ts │ ├── dev.config.json │ ├── extConfig.ts │ └── production.config.json ├── connectionconfig │ ├── connectionconfig.ts │ └── iconnectionconfig.ts ├── constants │ └── constants.ts ├── controllers │ ├── connectionManager.ts │ ├── localWebService.ts │ ├── mainController.ts │ ├── queryNotificationHandler.ts │ ├── queryRunner.ts │ ├── untitledSqlDocumentService.ts │ └── vscodeWrapper.ts ├── credentialstore │ ├── credentialstore.ts │ └── icredentialstore.ts ├── extension.ts ├── languageservice │ ├── decompressProvider.ts │ ├── httpClient.ts │ ├── interfaces.ts │ ├── proxy.ts │ ├── server.ts │ ├── serverStatus.ts │ ├── serviceDownloadProvider.ts │ ├── serviceInstallerUtil.ts │ └── serviceclient.ts ├── models │ ├── connectionCredentials.ts │ ├── connectionInfo.ts │ ├── connectionProfile.ts │ ├── connectionStore.ts │ ├── contracts.ts │ ├── contracts │ │ ├── connection.ts │ │ ├── languageService.ts │ │ ├── queryCancel.ts │ │ ├── queryDispose.ts │ │ └── queryExecute.ts │ ├── errors.ts │ ├── interfaces.ts │ ├── logger.ts │ ├── platform.ts │ ├── propertyUpdater.ts │ ├── resultsSerializer.ts │ ├── sqlOutputContentProvider.ts │ ├── telemetry.ts │ └── utils.ts ├── prompts │ ├── adapter.ts │ ├── checkbox.ts │ ├── confirm.ts │ ├── expand.ts │ ├── factory.ts │ ├── input.ts │ ├── list.ts │ ├── password.ts │ ├── progressIndicator.ts │ ├── prompt.ts │ └── question.ts ├── utils │ ├── EscapeException.ts │ ├── symbol.ts │ └── validationException.ts └── views │ ├── connectionUI.ts │ ├── htmlcontent │ ├── gulpfile.js │ ├── package.json │ ├── src │ │ ├── css │ │ │ ├── color-theme-dark.css │ │ │ ├── color-theme-light.css │ │ │ ├── flexbox.css │ │ │ └── styles.css │ │ ├── html │ │ │ ├── app.html │ │ │ ├── contextmenu.component.html │ │ │ ├── messagescontextmenu.component.html │ │ │ └── sqlOutput.ejs │ │ ├── images │ │ │ ├── ExitFullScreen_16x.png │ │ │ ├── ExitFullScreen_16x.svg │ │ │ ├── ExitFullScreen_16x_inverse.svg │ │ │ ├── ExitFullScreen_16x_vscode.svg │ │ │ ├── ExitFullScreen_16x_vscode_inverse.svg │ │ │ ├── ExtendToFullScreen_16x.png │ │ │ ├── ExtendToFullScreen_16x.svg │ │ │ ├── ExtendToFullScreen_16x_inverse.svg │ │ │ ├── ExtendToFullScreen_16x_vscode.svg │ │ │ ├── ExtendToFullScreen_16x_vscode_inverse.svg │ │ │ ├── ResultToCSV_16x.png │ │ │ ├── ResultToCSV_16x.svg │ │ │ ├── ResultToCSV_16x_inverse.svg │ │ │ ├── ResultToCSV_16x_vscode.svg │ │ │ ├── ResultToCSV_16x_vscode_inverse.svg │ │ │ ├── ResultToJSON_16x.png │ │ │ ├── ResultToJSON_16x.svg │ │ │ ├── ResultToJSON_16x_inverse.svg │ │ │ ├── ResultToJSON_16x_vscode.svg │ │ │ ├── ResultToJSON_16x_vscode_inverse.svg │ │ │ ├── ResultToText_16x.png │ │ │ ├── ResultToText_16x.svg │ │ │ ├── ResultToText_16x_inverse.svg │ │ │ ├── ResultToText_16x_vscode.svg │ │ │ ├── ResultToText_16x_vscode_inverse.svg │ │ │ ├── ResultToXlsx_16x_vscode.svg │ │ │ ├── ResultToXlsx_16x_vscode_inverse.svg │ │ │ ├── add-all.svg │ │ │ ├── app_Icon.icns │ │ │ ├── app_Icon.ico │ │ │ ├── app_Icon.png │ │ │ ├── app_Icon.svg │ │ │ ├── arrow-down.svg │ │ │ ├── arrow-left-white.svg │ │ │ ├── arrow-up-white.svg │ │ │ ├── arrow-up.svg │ │ │ ├── chevron-down.svg │ │ │ ├── circle.svg │ │ │ ├── close-red.svg │ │ │ ├── close-white.svg │ │ │ ├── close.svg │ │ │ ├── col-type-boolean.svg │ │ │ ├── col-type-number.svg │ │ │ ├── col-type-string.svg │ │ │ ├── col-type-timedate.svg │ │ │ ├── create-project.svg │ │ │ ├── data-profile.svg │ │ │ ├── delete.svg │ │ │ ├── edit-white.svg │ │ │ ├── edit.svg │ │ │ ├── filter-white.svg │ │ │ ├── filter.svg │ │ │ ├── filteradd.svg │ │ │ ├── filtersubtract.svg │ │ │ ├── input.svg │ │ │ ├── maximize.svg │ │ │ ├── minus-all-objects.svg │ │ │ ├── open-datasource.svg │ │ │ ├── open-project.svg │ │ │ ├── output.svg │ │ │ ├── progress_36x_animation.gif │ │ │ ├── query.svg │ │ │ ├── recent-project.svg │ │ │ ├── refine.svg │ │ │ ├── robot-cowboy.svg │ │ │ ├── sad.svg │ │ │ ├── shift-left.svg │ │ │ ├── smiley.svg │ │ │ ├── sort-ascending.svg │ │ │ ├── status-fail.svg │ │ │ ├── status-none.svg │ │ │ ├── status-success.svg │ │ │ ├── status_inprogress.svg │ │ │ ├── table.svg │ │ │ └── tutorial.json │ │ └── js │ │ │ ├── app.module.ts │ │ │ ├── components │ │ │ ├── app.component.ts │ │ │ ├── contextmenu.component.ts │ │ │ └── messagescontextmenu.component.ts │ │ │ ├── constants.ts │ │ │ ├── directives │ │ │ ├── mousedown.directive.ts │ │ │ └── scroll.directive.ts │ │ │ ├── displayCodes.json │ │ │ ├── interfaces.ts │ │ │ ├── keycodes.json │ │ │ ├── main.ts │ │ │ ├── services │ │ │ ├── data.service.ts │ │ │ └── shortcuts.service.ts │ │ │ ├── slick.autosizecolumn.ts │ │ │ ├── slick.dragrowselector.ts │ │ │ └── utils.ts │ ├── systemjs.config.extras.js │ ├── systemjs.config.js │ ├── test │ │ ├── app.component.spec.ts │ │ ├── contextmenu.component.spec.ts │ │ ├── data.service.spec.ts │ │ ├── dragrowselection.spec.ts │ │ ├── messagescontextmenu.component.spec.ts │ │ ├── shortcuts.service.spec.ts │ │ ├── testResources │ │ │ ├── mockConfig1.spec.ts │ │ │ ├── mockGetRows1.spec.ts │ │ │ ├── mockMessageBatchStart.spec.ts │ │ │ ├── mockMessageError.spec.ts │ │ │ ├── mockMessageResultSet.spec.ts │ │ │ ├── mockMessageSimple.spec.ts │ │ │ ├── mockResultSetBig.spec.ts │ │ │ └── mockResultSetSmall.spec.ts │ │ ├── testUtils.ts │ │ └── utils.spec.ts │ ├── tsconfig.json │ ├── tsd.json │ ├── tslint.json │ └── typings │ │ ├── globals │ │ └── jqueryui │ │ │ ├── index.d.ts │ │ │ └── typings.json │ │ ├── index.d.ts │ │ ├── jasmine │ │ ├── README.md │ │ ├── index.d.ts │ │ ├── package.json │ │ └── types-metadata.json │ │ ├── jquery │ │ └── jquery.d.ts │ │ ├── require.d.ts │ │ ├── tsd.d.ts │ │ └── underscore.d.ts │ └── statusView.ts ├── syntaxes ├── SQL.plist └── sql.configuration.json ├── tasks ├── config.js ├── covertasks.js ├── htmltasks.js ├── localizationtasks.js └── packagetasks.js ├── test ├── config.test.ts ├── connectionCredentials.test.ts ├── connectionProfile.test.ts ├── connectionStore.test.ts ├── connectionconfig.test.ts ├── download.test.ts ├── extConfig.test.ts ├── index.ts ├── initialization.test.ts ├── istanbultestrunner.ts ├── localization.test.ts ├── mainController.test.ts ├── perFileConnection.test.ts ├── platform.test.ts ├── queryNotificationHandler.test.ts ├── queryRunner.test.ts ├── resources │ ├── messages.json │ ├── results.json │ └── sqlTest.sql ├── saveResults.test.ts ├── server.test.ts ├── serviceClient.test.ts ├── sqlOutputContentProvider.test.ts ├── statusView.test.ts ├── stubs.ts ├── telemetry.test.ts ├── untitledSqlDocumentService.test.ts ├── utils.test.ts └── webServiceRequestHandlers.test.ts ├── tsconfig.json ├── tslint.json └── typings ├── chai.d.ts ├── getmac.d.ts ├── globals ├── istanbul │ ├── index.d.ts │ └── typings.json └── underscore │ └── index.d.ts ├── index.d.ts ├── mocha.d.ts ├── tmp.d.ts └── vscode-extension-telemetry.d.ts /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | node_modules 3 | packages 4 | .DS_Store 5 | *.dat 6 | *.db 7 | *.exe 8 | *.log 9 | *.nupkg 10 | *.orig 11 | *.vsix 12 | *BROWSE.VC* 13 | tools 14 | examples 15 | pgsqltoolsservice 16 | coverage 17 | test-reports 18 | .vscode-test 19 | localization/i18n/ 20 | src/constants/localizedConstants.ts 21 | package.nls.*.json -------------------------------------------------------------------------------- /.mention-bot: -------------------------------------------------------------------------------- 1 | { 2 | "maxReviewers": 3, 3 | "requiredOrgs": ["Microsoft"], 4 | "skipAlreadyAssignedPR": true, 5 | "skipAlreadyMentionedPR": true, 6 | "skipCollaboratorPR": false 7 | } -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | dist: trusty 3 | 4 | # safelist 5 | branches: 6 | only: 7 | - master 8 | - dev 9 | 10 | language: node_js 11 | node_js: 12 | - "6.9.1" 13 | 14 | os: 15 | - linux 16 | - osx 17 | 18 | addons: 19 | apt: 20 | packages: 21 | - libsecret-1-dev 22 | 23 | before_install: 24 | - export CHROME_BIN=chromium-browser 25 | # Set up chrome on osx 26 | - if [ $TRAVIS_OS_NAME == "osx" ]; then 27 | brew cask install google-chrome; 28 | export CHROME_BIN=/Applications/Google\ Chrome.app; 29 | fi 30 | - export BUILDMACHINE=true 31 | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get update; fi 32 | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install xclip; fi 33 | - npm install -g npm@4 34 | install: 35 | - npm install -g --silent gulp-cli 36 | - npm install -g --silent xvfb-maybe@0.1.3 37 | - npm install 38 | - gulp install 39 | script: 40 | - gulp build 41 | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then gulp cover:enableconfig; fi 42 | - if [ $TRAVIS_OS_NAME == "osx" ]; then 43 | sudo xvfb-maybe ./node_modules/.bin/karma start; 44 | else 45 | xvfb-maybe ./node_modules/.bin/karma start; 46 | fi 47 | - xvfb-maybe node ./node_modules/vscode/bin/test 48 | - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then 49 | gulp cover:combine; 50 | node_modules/.bin/coveralls < coverage/lcov.info; 51 | fi 52 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | { 3 | "version": "0.1.0", 4 | "configurations": [ 5 | { 6 | "type": "node", 7 | "request": "launch", 8 | "name": "Gulp task", 9 | "program": "${workspaceRoot}/node_modules/gulp/bin/gulp.js", 10 | "args": [ 11 | "ext:localization:xliff-to-package.nls" 12 | ] 13 | }, 14 | { 15 | "name": "Launch Extension", 16 | "type": "extensionHost", 17 | "request": "launch", 18 | "runtimeExecutable": "${execPath}", 19 | "args": ["--extensionDevelopmentPath=${workspaceRoot}" ], 20 | "stopOnEntry": false, 21 | "sourceMaps": true, 22 | "outFiles": ["${workspaceRoot}/out/src/**/*.js"], 23 | "preLaunchTask": "cover:disable" 24 | }, 25 | { 26 | "name": "Launch Tests", 27 | "type": "extensionHost", 28 | "request": "launch", 29 | "runtimeExecutable": "${execPath}", 30 | "args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test"], 31 | "stopOnEntry": false, 32 | "sourceMaps": true, 33 | "outFiles": ["${workspaceRoot}/out/test/**/*,js"], 34 | "preLaunchTask": "cover:disable" 35 | }, 36 | { 37 | "name": "Launch Code Coverage", 38 | "type": "extensionHost", 39 | "request": "launch", 40 | "runtimeExecutable": "${execPath}", 41 | "args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test"], 42 | "stopOnEntry": false, 43 | "sourceMaps": true, 44 | "outFiles": ["${workspaceRoot}/out/test/**/*,js"], 45 | "preLaunchTask": "cover:enable" 46 | } 47 | ] 48 | } 49 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.trimTrailingWhitespace": true, 4 | 5 | "files.exclude": { 6 | "out": false // set this to true to hide the "out" folder with the compiled JS files 7 | }, 8 | "search.exclude": { 9 | "out": true, // set this to false to include "out" folder in search results 10 | "coverage": true 11 | }, 12 | "typescript.tsdk": "./node_modules/typescript/lib", // we want to use the TS server from our node_modules folder to control its version 13 | "files.watcherExclude": { 14 | "**/.git/objects/**": true, 15 | "**/out/*" : true 16 | }, 17 | 18 | "lcov.path": ["coverage/lcov.info"] 19 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "0.1.0", 5 | "command": "gulp", 6 | "isShellCommand": true, 7 | "args": [ 8 | "--no-color" 9 | ], 10 | "tasks": [ 11 | { 12 | "taskName": "build", 13 | "args": [], 14 | "isBuildCommand": true, 15 | "isWatching": false, 16 | "problemMatcher": [ 17 | "$lessCompile", 18 | "$tsc", 19 | "$jshint" 20 | ] 21 | }, 22 | { 23 | "taskName": "cover:enable", 24 | "args": [], 25 | "isBuildCommand": false, 26 | "isWatching": false 27 | }, 28 | { 29 | "taskName": "cover:disable", 30 | "args": [], 31 | "isBuildCommand": false, 32 | "isWatching": false 33 | } 34 | ] 35 | } -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | typings/** 3 | out/test/** 4 | **/*.ts 5 | test/** 6 | **/*.map 7 | .gitignore 8 | tsconfig.json 9 | src/** 10 | tasks/** 11 | packages/** 12 | samples/** 13 | *.exe 14 | *.dat 15 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/vscode-postgresql/a3ee951dc73387eff177a4aba702a855930d529d/CHANGELOG.md -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ------------------ START OF LICENSE ----------------------------------------- 2 | 3 | PostgreSQL extension for VSCODE 4 | 5 | Copyright (c) Microsoft Corporation All rights reserved. 6 | 7 | MIT License 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the Software), to deal 11 | in the Software without restriction, including without limitation the rights to use, 12 | copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 13 | and to permit persons to whom the Software is furnished to do so, 14 | subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in 17 | all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 20 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 21 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 23 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 24 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | 26 | ------------------- END OF LICENSE ------------------------------------------ 27 | 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > [!IMPORTANT] 2 | > This project is deprecated. The PostgreSQL extension for Visual Studio Code has moved to [PostgreSQL for VS Code](https://marketplace.visualstudio.com/items?itemName=ms-ossdata.vscode-pgsql). The new repository is located at [https://github.com/Microsoft/vscode-pgsql](https://github.com/Microsoft/vscode-pgsql). 3 | 4 | # PostgreSQL for Visual Studio Code 5 | 6 | Welcome to PostgreSQL for Visual Studio Code! An extension for developing PostgreSQL with functionalities including: 7 | 8 | * Connect to PostgreSQL instances 9 | * Manage connection profiles 10 | * Connect to a different Postgres instance or database in each tab 11 | * View object DDL with 'Go to Definition' and 'Peek Definition' 12 | * Write queries with IntelliSense 13 | * Run queries and save results as JSON, csv, or Excel 14 | 15 | Install link: https://marketplace.visualstudio.com/items?itemName=ms-ossdata.vscode-postgresql 16 | 17 | ## Quickstart 18 | 19 | 1) Open the Command Palette (Ctrl + Shift + P). 20 | 21 | 2) Search and select 'PostgreSQL: New Query' 22 | 23 | 3) In the command palette, select 'Create Connection Profile'. Follow the prompts to enter your Postgres instance's hostname, database, username, and password. 24 | 25 | You are now connected to your Postgres database. You can confirm this via the Status Bar (the ribbon at the bottom of the VS Code window). It will show your connected hostname, database, and user. 26 | 27 | 4) You can type a query like 'SELECT * FROM pg_stat_activity'; 28 | 29 | 5) Right-click, select 'Execute Query' and the results will show in a new window. 30 | 31 | You can save the query results to JSON, csv or Excel. 32 | 33 | ## Offline Installation 34 | The extension will download and install a required PostgreSQL Tools Service package during activation. For machines with no Internet access, you can still use the extension by choosing the 35 | `Install from VSIX...` option in the Extension view and installing a bundled release from our [Releases](https://github.com/Microsoft/vscode-postgresql/releases) page. 36 | Each operating system has a .vsix file with the required service included. Pick the file for your OS, download and install to get started. 37 | We recommend you choose a full release and ignore any alpha or beta releases as these are our daily builds used in testing. 38 | 39 | ## Support 40 | Support for this extension is provided on our [GitHub Issue Tracker]. You can submit a [bug report], a [feature suggestion] or participate in [discussions]. 41 | 42 | ## Contributing to the Extension 43 | See the [developer documentation] for details on how to contribute to this extension. 44 | 45 | ## Code of Conduct 46 | This project has adopted the [Microsoft Open Source Code of Conduct]. For more information see the [Code of Conduct FAQ] or contact [opencode@microsoft.com] with any additional questions or comments. 47 | 48 | ## Privacy Statement 49 | The [Microsoft Enterprise and Developer Privacy Statement] describes the privacy statement of this software. 50 | 51 | ## License 52 | This extension is [licensed under the MIT License]. Please see the [third-party notices] file for additional copyright notices and license terms applicable to portions of the software. 53 | 54 | [GitHub Issue Tracker]:https://github.com/Microsoft/vscode-postgresql/issues 55 | [bug report]:https://github.com/Microsoft/vscode-postgresql/issues/new 56 | [feature suggestion]:https://github.com/Microsoft/vscode-postgresql/issues/new 57 | [developer documentation]:https://github.com/Microsoft/vscode-postgresql/wiki/How-to-Contribute 58 | [Microsoft Enterprise and Developer Privacy Statement]:https://go.microsoft.com/fwlink/?LinkId=786907&lang=en7 59 | [licensed under the MIT License]: https://github.com/Microsoft/vscode-postgresql/blob/master/LICENSE 60 | [third-party notices]: https://github.com/Microsoft/vscode-postgresql/blob/master/ThirdPartyNotices.txt 61 | [Microsoft Open Source Code of Conduct]:https://opensource.microsoft.com/codeofconduct/ 62 | [Code of Conduct FAQ]:https://opensource.microsoft.com/codeofconduct/faq/ 63 | [opencode@microsoft.com]:mailto:opencode@microsoft.com 64 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | nodejs_version: "6.9.1" 3 | # Temporary Code version due to https://github.com/Microsoft/vscode-extension-vscode/issues/64 4 | CODE_VERSION: 1.23.0 5 | 6 | 7 | # safelist 8 | branches: 9 | only: 10 | - master 11 | - dev 12 | 13 | # Install scripts. (runs after repo cloning) 14 | install: 15 | - choco install --ignore-checksums googlechrome 16 | - set BUILDMACHINE=true 17 | # Get the latest stable version of Node.js or io.js 18 | - ps: Install-Product node $env:nodejs_version 19 | - npm install -g npm@4 20 | # show versions 21 | - npm --version 22 | - node --version 23 | - npm install -g --silent gulp-cli 24 | # install modules 25 | - npm install 26 | - gulp install 27 | 28 | build_script: 29 | - gulp build 30 | 31 | test_script: 32 | - ./node_modules/.bin/karma start 33 | - node ./node_modules/vscode/bin/test 34 | 35 | on_finish: 36 | - ps: scripts\upload.ps1 -------------------------------------------------------------------------------- /coverconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "enabled": false, 3 | "relativeSourcePath": "../src", 4 | "relativeCoverageDir": "../../coverage", 5 | "ignorePatterns": ["**/node_modules/**", "**/libs/**", "**/lib/**", "**/htmlcontent/**/*.js", "**/*.bundle.js"], 6 | "includePid": false, 7 | "reports": ["json"], 8 | "verbose": false 9 | } -------------------------------------------------------------------------------- /images/extension-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/vscode-postgresql/a3ee951dc73387eff177a4aba702a855930d529d/images/extension-icon.png -------------------------------------------------------------------------------- /install.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var install = require('gulp-install'); 3 | 4 | gulp.task('install', function(){ 5 | return gulp.src(['./package.json', './src/views/htmlcontent/package.json']) 6 | .pipe(install()); 7 | }); -------------------------------------------------------------------------------- /issue_template.md: -------------------------------------------------------------------------------- 1 | - PGSQL Extension Version: 2 | - VSCode Version: 3 | - OS Version: 4 | 5 | Steps to Reproduce: 6 | 7 | 1. 8 | 2. 9 | -------------------------------------------------------------------------------- /karma-test-shim.js: -------------------------------------------------------------------------------- 1 | // #docregion 2 | // /*global jasmine, __karma__, window*/ 3 | Error.stackTraceLimit = 0; // "No stacktrace"" is usually best for app testing. 4 | 5 | // Uncomment to get full stacktrace output. 6 | // Error.stackTraceLimit = Infinity; // 7 | 8 | var builtPath = '/base/out/src/views/htmlcontent/dist/js/'; 9 | 10 | __karma__.loaded = function () { }; 11 | 12 | function isJsFile(path) { 13 | return path.slice(-3) == '.js'; 14 | } 15 | 16 | function isSpecFile(path) { 17 | return /\.spec\.(.*\.)?js$/.test(path); 18 | } 19 | 20 | function isBuiltFile(path) { 21 | return isJsFile(path) && (path.substr(0, builtPath.length) == builtPath); 22 | } 23 | 24 | var allSpecFiles = Object.keys(window.__karma__.files) 25 | .filter(isSpecFile); 26 | 27 | System.config({ 28 | baseURL: 'base/out/src/views/htmlcontent', 29 | // Extend usual application package list with test folder 30 | packages: { 'testing': { main: 'index.js', defaultExtension: 'js' } }, 31 | 32 | // Assume npm: is set in `paths` in systemjs.config 33 | // Map the angular testing umd bundles 34 | map: { 35 | '@angular/core/testing': 'lib/js/@angular/core/bundles/core-testing.umd.js', 36 | '@angular/common/testing': 'lib/js/@angular/common/bundles/common-testing.umd.js', 37 | '@angular/compiler/testing': 'lib/js/@angular/compiler/bundles/compiler-testing.umd.js', 38 | '@angular/platform-browser/testing': 'lib/js/@angular/platform-browser/bundles/platform-browser-testing.umd.js', 39 | '@angular/platform-browser-dynamic/testing': 'lib/js/@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js', 40 | '@angular/http/testing': 'lib/js/@angular/http/bundles/http-testing.umd.js', 41 | '@angular/router/testing': 'lib/js/@angular/router/bundles/router-testing.umd.js', 42 | '@angular/forms/testing': 'ib/js/@angular/forms/bundles/forms-testing.umd.js', 43 | }, 44 | }); 45 | 46 | System.import('lib/js/systemjs.config.js') 47 | .then(initTestBed) 48 | .then(initTesting); 49 | 50 | function initTestBed(){ 51 | return Promise.all([ 52 | System.import('@angular/core/testing'), 53 | System.import('@angular/platform-browser-dynamic/testing') 54 | ]) 55 | 56 | .then(function (providers) { 57 | var coreTesting = providers[0]; 58 | var browserTesting = providers[1]; 59 | 60 | jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; 61 | 62 | coreTesting.TestBed.initTestEnvironment( 63 | browserTesting.BrowserDynamicTestingModule, 64 | browserTesting.platformBrowserDynamicTesting()); 65 | }) 66 | } 67 | 68 | // Import all spec files and start karma 69 | function initTesting () { 70 | return Promise.all( 71 | allSpecFiles.map(function (moduleName) { 72 | return System.import(moduleName); 73 | }) 74 | ) 75 | .then(__karma__.start, __karma__.error); 76 | } 77 | -------------------------------------------------------------------------------- /samples/sql2016-crud-demo.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/vscode-postgresql/a3ee951dc73387eff177a4aba702a855930d529d/samples/sql2016-crud-demo.sql -------------------------------------------------------------------------------- /samples/sql2016-security-demo.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/vscode-postgresql/a3ee951dc73387eff177a4aba702a855930d529d/samples/sql2016-security-demo.sql -------------------------------------------------------------------------------- /scripts/upload.ps1: -------------------------------------------------------------------------------- 1 | $wc = New-Object 'System.Net.WebClient' 2 | $wc.UploadFile("https://ci.appveyor.com/api/testresults/junit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path 'test-reports\*')[0]) 3 | $wc.UploadFile("https://ci.appveyor.com/api/testresults/junit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path 'test-reports\*')[1]) -------------------------------------------------------------------------------- /snippets/pgsql.json: -------------------------------------------------------------------------------- 1 | { 2 | "Create a new Database": { 3 | "prefix": "pgCreateDatabase", 4 | "body": [ 5 | "-- Create a new database called '${1:DatabaseName}'", 6 | "CREATE DATABASE ${1:DatabaseName}" 7 | ], 8 | "description": "Create a new PostgreSQL Database" 9 | }, 10 | "List databases": { 11 | "prefix": "pgListDatabases", 12 | "body": [ 13 | "-- Get a list of databases", 14 | "SELECT datname FROM pg_database", 15 | "WHERE datistemplate = false" 16 | ], 17 | "description": "List PostgreSQL databases" 18 | } 19 | } -------------------------------------------------------------------------------- /src/configurations/config.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | 'use strict'; 7 | const fs = require('fs'); 8 | import * as path from 'path'; 9 | import * as Constants from '../constants/constants'; 10 | import {IConfig} from '../languageservice/interfaces'; 11 | 12 | /* 13 | * Config class handles getting values from config.json. 14 | */ 15 | export default class Config implements IConfig { 16 | private static _configJsonContent = undefined; 17 | private _sqlToolsServiceConfigKey: string; 18 | private version: number; 19 | 20 | public static get configJsonContent(): any { 21 | if (this._configJsonContent === undefined) { 22 | this._configJsonContent = this.loadConfig(); 23 | } 24 | return this._configJsonContent; 25 | } 26 | 27 | constructor() { 28 | this._sqlToolsServiceConfigKey = Constants.sqlToolsServiceConfigKey; 29 | this.version = 2; 30 | } 31 | 32 | public getSqlToolsServiceDownloadUrl(): string { 33 | return this.getSqlToolsConfigValue(Constants.sqlToolsServiceDownloadUrlConfigKey); 34 | } 35 | 36 | public getSqlToolsInstallDirectory(): string { 37 | return this.getSqlToolsConfigValue(Constants.sqlToolsServiceInstallDirConfigKey); 38 | } 39 | 40 | public getSqlToolsExecutableFiles(): string[] { 41 | return this.getSqlToolsConfigValue(Constants.sqlToolsServiceExecutableFilesConfigKey); 42 | } 43 | 44 | public getSqlToolsPackageVersion(): string { 45 | return this.getSqlToolsConfigValue(Constants.sqlToolsServiceVersionConfigKey); 46 | } 47 | 48 | public useServiceVersion(version: number): void { 49 | switch (version) { 50 | case 1: 51 | this._sqlToolsServiceConfigKey = Constants.v1SqlToolsServiceConfigKey; 52 | break; 53 | default: 54 | this._sqlToolsServiceConfigKey = Constants.sqlToolsServiceConfigKey; 55 | } 56 | this.version = version; 57 | } 58 | 59 | public getServiceVersion(): number { 60 | return this.version; 61 | } 62 | 63 | public getSqlToolsConfigValue(configKey: string): any { 64 | let json = Config.configJsonContent; 65 | let toolsConfig = json[this._sqlToolsServiceConfigKey]; 66 | let configValue: string = undefined; 67 | if (toolsConfig !== undefined) { 68 | configValue = toolsConfig[configKey]; 69 | } 70 | return configValue; 71 | } 72 | 73 | public getExtensionConfig(key: string, defaultValue?: any): any { 74 | let json = Config.configJsonContent; 75 | let extensionConfig = json[Constants.extensionConfigSectionName]; 76 | let configValue = extensionConfig[key]; 77 | if (!configValue) { 78 | configValue = defaultValue; 79 | } 80 | return configValue; 81 | } 82 | 83 | public getWorkspaceConfig(key: string, defaultValue?: any): any { 84 | let json = Config.configJsonContent; 85 | let configValue = json[key]; 86 | if (!configValue) { 87 | configValue = defaultValue; 88 | } 89 | return configValue; 90 | } 91 | 92 | static loadConfig(): any { 93 | let configContent = fs.readFileSync(path.join(__dirname, '../config.json')); 94 | return JSON.parse(configContent); 95 | } 96 | } 97 | 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /src/configurations/dev.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "service": { 3 | "downloadUrl": "https://github.com/Microsoft/pgtoolsservice/releases/download/{#version#}/pgsqltoolsservice-{#fileName#}", 4 | "version": "v1.1.0", 5 | "downloadFileNames": { 6 | "Windows_7_86": "win-x86.zip", 7 | "Windows_7_64": "win-x64.zip", 8 | "OSX_10_11_64": "osx.tar.gz", 9 | "CentOS_7": "linux-x64.tar.gz", 10 | "Debian_8": "linux-x64.tar.gz", 11 | "Fedora_23": "linux-x64.tar.gz", 12 | "OpenSUSE_13_2": "linux-x64.tar.gz", 13 | "SLES_12_2": "linux-x64.tar.gz", 14 | "RHEL_7": "linux-x64.tar.gz", 15 | "Ubuntu_14": "linux-x64.tar.gz", 16 | "Ubuntu_16": "linux-x64.tar.gz" 17 | }, 18 | "installDir": "../pgsqltoolsservice/{#version#}/{#platform#}", 19 | "executableFiles": [ 20 | "pgsqltoolsservice/pgtoolsservice_main", 21 | "pgsqltoolsservice/pgtoolsservice_main.exe" 22 | ] 23 | } 24 | } -------------------------------------------------------------------------------- /src/configurations/extConfig.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | 'use strict'; 7 | 8 | import Config from './config'; 9 | import { workspace, WorkspaceConfiguration } from 'vscode'; 10 | import * as Constants from '../constants/constants'; 11 | import {IConfig} from '../languageservice/interfaces'; 12 | 13 | /* 14 | * ExtConfig class handles getting values from workspace config or config.json. 15 | */ 16 | export default class ExtConfig implements IConfig { 17 | 18 | constructor(private _config?: IConfig, 19 | private _extensionConfig?: WorkspaceConfiguration, 20 | private _workspaceConfig?: WorkspaceConfiguration) { 21 | if (this._config === undefined) { 22 | this._config = new Config(); 23 | } 24 | if (this._extensionConfig === undefined) { 25 | this._extensionConfig = workspace.getConfiguration(Constants.extensionConfigSectionName); 26 | } 27 | if (this._workspaceConfig === undefined) { 28 | this._workspaceConfig = workspace.getConfiguration(); 29 | } 30 | } 31 | 32 | public getSqlToolsServiceDownloadUrl(): string { 33 | return this.getSqlToolsConfigValue(Constants.sqlToolsServiceDownloadUrlConfigKey); 34 | } 35 | 36 | public getSqlToolsInstallDirectory(): string { 37 | return this.getSqlToolsConfigValue(Constants.sqlToolsServiceInstallDirConfigKey); 38 | } 39 | 40 | public getSqlToolsExecutableFiles(): string[] { 41 | return this.getSqlToolsConfigValue(Constants.sqlToolsServiceExecutableFilesConfigKey); 42 | } 43 | 44 | public getSqlToolsPackageVersion(): string { 45 | return this.getSqlToolsConfigValue(Constants.sqlToolsServiceVersionConfigKey); 46 | } 47 | 48 | public useServiceVersion(version: number): void { 49 | return this._config.useServiceVersion(version); 50 | } 51 | 52 | public getServiceVersion(): number { 53 | return this._config.getServiceVersion(); 54 | } 55 | 56 | public getSqlToolsConfigValue(configKey: string): any { 57 | let configValue: string = this.getExtensionConfig(`${Constants.sqlToolsServiceConfigKey}.${configKey}`); 58 | if (!configValue) { 59 | configValue = this._config.getSqlToolsConfigValue(configKey); 60 | } 61 | return configValue; 62 | } 63 | 64 | public getExtensionConfig(key: string, defaultValue?: any): any { 65 | let configValue = this._extensionConfig.get(key); 66 | if (configValue === undefined) { 67 | configValue = defaultValue; 68 | } 69 | return configValue; 70 | } 71 | 72 | public getWorkspaceConfig(key: string, defaultValue?: any): any { 73 | let configValue = this._workspaceConfig.get(key); 74 | if (configValue === undefined) { 75 | configValue = defaultValue; 76 | } 77 | return configValue; 78 | } 79 | } 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /src/configurations/production.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "service": { 3 | "downloadUrl": "https://github.com/Microsoft/pgtoolsservice/releases/download/{#version#}/pgsqltoolsservice-{#fileName#}", 4 | "version": "v1.1.0", 5 | "downloadFileNames": { 6 | "Windows_7_86": "win-x86.zip", 7 | "Windows_7_64": "win-x64.zip", 8 | "OSX_10_11_64": "osx.tar.gz", 9 | "CentOS_7": "linux-x64.tar.gz", 10 | "Debian_8": "linux-x64.tar.gz", 11 | "Fedora_23": "linux-x64.tar.gz", 12 | "OpenSUSE_13_2": "linux-x64.tar.gz", 13 | "SLES_12_2": "linux-x64.tar.gz", 14 | "RHEL_7": "linux-x64.tar.gz", 15 | "Ubuntu_14": "linux-x64.tar.gz", 16 | "Ubuntu_16": "linux-x64.tar.gz" 17 | }, 18 | "installDir": "../pgsqltoolsservice/{#version#}/{#platform#}", 19 | "executableFiles": [ 20 | "pgsqltoolsservice/pgtoolsservice_main", 21 | "pgsqltoolsservice/pgtoolsservice_main.exe" 22 | ] 23 | } 24 | } -------------------------------------------------------------------------------- /src/connectionconfig/iconnectionconfig.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 'use strict'; 6 | 7 | import { IConnectionProfile } from '../models/interfaces'; 8 | 9 | /** 10 | * Interface for a configuration file that stores connection profiles. 11 | * 12 | * @export 13 | * @interface IConnectionConfig 14 | */ 15 | export interface IConnectionConfig { 16 | addConnection(profile: IConnectionProfile): Promise; 17 | getConnections(getWorkspaceConnections: boolean): IConnectionProfile[]; 18 | removeConnection(profile: IConnectionProfile): Promise; 19 | } 20 | -------------------------------------------------------------------------------- /src/controllers/untitledSqlDocumentService.ts: -------------------------------------------------------------------------------- 1 | /* -------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | * ------------------------------------------------------------------------------------------ */ 5 | 6 | import VscodeWrapper from './vscodeWrapper'; 7 | 8 | /** 9 | * Service for creating untitled documents for SQL query 10 | */ 11 | export default class UntitledSqlDocumentService { 12 | 13 | constructor(private vscodeWrapper: VscodeWrapper) { 14 | } 15 | 16 | /** 17 | * Creates new untitled document for SQL query and opens in new editor tab 18 | */ 19 | public newQuery(): Promise { 20 | 21 | return new Promise((resolve, reject) => { 22 | try { 23 | 24 | // Open an untitled document. So the file doesn't have to exist in disk 25 | this.vscodeWrapper.openPgSqlTextDocument().then(doc => { 26 | // Show the new untitled document in the editor's first tab and change the focus to it. 27 | this.vscodeWrapper.showTextDocument(doc, 1, false).then(textDoc => { 28 | resolve(true); 29 | }); 30 | }); 31 | } catch (error) { 32 | reject(error); 33 | } 34 | }); 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /src/credentialstore/credentialstore.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 'use strict'; 6 | 7 | import * as Contracts from '../models/contracts'; 8 | import { ICredentialStore } from './icredentialstore'; 9 | import SqlToolsServerClient from '../languageservice/serviceclient'; 10 | 11 | /** 12 | * Implements a credential storage for Windows, Mac (darwin), or Linux. 13 | * 14 | * Allows a single credential to be stored per service (that is, one username per service); 15 | */ 16 | export class CredentialStore implements ICredentialStore { 17 | 18 | constructor(private _client?: SqlToolsServerClient) { 19 | if (!this._client) { 20 | this._client = SqlToolsServerClient.instance; 21 | } 22 | } 23 | 24 | /** 25 | * Gets a credential saved in the credential store 26 | * 27 | * @param {string} credentialId the ID uniquely identifying this credential 28 | * @returns {Promise} Promise that resolved to the credential, or undefined if not found 29 | */ 30 | public readCredential(credentialId: string): Promise { 31 | let self = this; 32 | let cred: Contracts.Credential = new Contracts.Credential(); 33 | cred.credentialId = credentialId; 34 | return new Promise( (resolve, reject) => { 35 | self._client 36 | .sendRequest(Contracts.ReadCredentialRequest.type, cred) 37 | .then(returnedCred => { 38 | resolve(returnedCred); 39 | }, err => reject(err)); 40 | }); 41 | } 42 | 43 | 44 | public saveCredential(credentialId: string, password: any): Promise { 45 | let self = this; 46 | let cred: Contracts.Credential = new Contracts.Credential(); 47 | cred.credentialId = credentialId; 48 | cred.password = password; 49 | return new Promise( (resolve, reject) => { 50 | self._client 51 | .sendRequest(Contracts.SaveCredentialRequest.type, cred) 52 | .then(status => { 53 | resolve(status); 54 | }, err => reject(err)); 55 | }); 56 | } 57 | 58 | public deleteCredential(credentialId: string): Promise { 59 | let self = this; 60 | let cred: Contracts.Credential = new Contracts.Credential(); 61 | cred.credentialId = credentialId; 62 | return new Promise( (resolve, reject) => { 63 | self._client 64 | .sendRequest(Contracts.DeleteCredentialRequest.type, cred) 65 | .then(status => { 66 | resolve(status); 67 | }, err => reject(err)); 68 | }); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/credentialstore/icredentialstore.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 'use strict'; 6 | 7 | 8 | // This code is originally from https://github.com/microsoft/vsts-vscode 9 | // License: https://github.com/Microsoft/vsts-vscode/blob/master/LICENSE.txt 10 | 11 | import { Credential } from '../models/contracts'; 12 | 13 | /** 14 | * A credential store that securely stores sensitive information in a platform-specific manner 15 | * 16 | * @export 17 | * @interface ICredentialStore 18 | */ 19 | export interface ICredentialStore { 20 | readCredential(credentialId: string): Promise; 21 | saveCredential(credentialId: string, password: any): Promise; 22 | deleteCredential(credentialId: string): Promise; 23 | } 24 | -------------------------------------------------------------------------------- /src/extension.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | import vscode = require('vscode'); 3 | import Constants = require('./constants/constants'); 4 | import * as LocalizedConstants from './constants/localizedConstants'; 5 | import MainController from './controllers/mainController'; 6 | import VscodeWrapper from './controllers/vscodeWrapper'; 7 | 8 | let controller: MainController = undefined; 9 | 10 | // this method is called when your extension is activated 11 | // your extension is activated the very first time the command is executed 12 | export function activate(context: vscode.ExtensionContext): Promise { 13 | let vscodeWrapper = new VscodeWrapper(); 14 | controller = new MainController(context, undefined, vscodeWrapper); 15 | context.subscriptions.push(controller); 16 | 17 | // Checking if localization should be applied 18 | let config = vscodeWrapper.getConfiguration(Constants.extensionConfigSectionName); 19 | let applyLocalization = config[Constants.configApplyLocalization]; 20 | if (applyLocalization) { 21 | LocalizedConstants.loadLocalizedConstants(vscode.env.language); 22 | } 23 | 24 | return controller.activate(); 25 | } 26 | 27 | // this method is called when your extension is deactivated 28 | export function deactivate(): void { 29 | if (controller) { 30 | controller.deactivate(); 31 | } 32 | } 33 | 34 | /** 35 | * Exposed for testing purposes 36 | */ 37 | export function getController(): MainController { 38 | return controller; 39 | } 40 | -------------------------------------------------------------------------------- /src/languageservice/decompressProvider.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | 'use strict'; 7 | 8 | import {IDecompressProvider, IPackage} from './interfaces'; 9 | import {ILogger} from '../models/interfaces'; 10 | const decompress = require('decompress'); 11 | 12 | export default class DecompressProvider implements IDecompressProvider { 13 | public decompress(pkg: IPackage, logger: ILogger): Promise { 14 | return new Promise((resolve, reject) => { 15 | decompress(pkg.tmpFile.name, pkg.installPath).then(files => { 16 | logger.appendLine(`Done! ${files.length} files unpacked.\n`); 17 | resolve(); 18 | }).catch(decompressErr => { 19 | logger.appendLine(`[ERROR] ${decompressErr}`); 20 | reject(decompressErr); 21 | }); 22 | }); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/languageservice/interfaces.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | import * as tmp from 'tmp'; 6 | import {ILogger} from '../models/interfaces'; 7 | 8 | export interface IStatusView { 9 | installingService(): void; 10 | serviceInstalled(): void; 11 | serviceInstallationFailed(): void; 12 | updateServiceDownloadingProgress(downloadPercentage: number): void; 13 | } 14 | 15 | export interface IConfig { 16 | getSqlToolsServiceDownloadUrl(): string; 17 | getSqlToolsInstallDirectory(): string; 18 | getSqlToolsInstallDirectory(): string; 19 | getSqlToolsExecutableFiles(): string[]; 20 | getSqlToolsPackageVersion(): string; 21 | getExtensionConfig(key: string, defaultValue?: any): any; 22 | getWorkspaceConfig(key: string, defaultValue?: any): any; 23 | getSqlToolsConfigValue(configKey: string): any; 24 | useServiceVersion(version: number): void; 25 | getServiceVersion(): number; 26 | } 27 | 28 | export interface IPackage { 29 | url: string; 30 | installPath?: string; 31 | tmpFile: tmp.SynchronousResult; 32 | } 33 | 34 | export class PackageError extends Error { 35 | // Do not put PII (personally identifiable information) in the 'message' field as it will be logged to telemetry 36 | constructor(public message: string, 37 | public pkg: IPackage = undefined, 38 | public innerError: any = undefined) { 39 | super(message); 40 | } 41 | } 42 | 43 | export interface IHttpClient { 44 | downloadFile(urlString: string, pkg: IPackage, logger: ILogger, statusView: IStatusView, proxy: string, strictSSL: boolean, authorization?: string): 45 | Promise; 46 | } 47 | 48 | export interface IDecompressProvider { 49 | decompress(pkg: IPackage, logger: ILogger): Promise; 50 | } 51 | -------------------------------------------------------------------------------- /src/languageservice/proxy.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | 'use strict'; 7 | 8 | import { Url, parse as parseUrl } from 'url'; 9 | let HttpProxyAgent = require('http-proxy-agent'); 10 | let HttpsProxyAgent = require('https-proxy-agent'); 11 | 12 | function getSystemProxyURL(requestURL: Url): string { 13 | if (requestURL.protocol === 'http:') { 14 | return process.env.HTTP_PROXY || process.env.http_proxy || undefined; 15 | } else if (requestURL.protocol === 'https:') { 16 | return process.env.HTTPS_PROXY || process.env.https_proxy || process.env.HTTP_PROXY || process.env.http_proxy || undefined; 17 | } 18 | 19 | return undefined; 20 | } 21 | 22 | export function isBoolean(obj: any): obj is boolean { 23 | return obj === true || obj === false; 24 | } 25 | 26 | /* 27 | * Returns the proxy agent using the proxy url in the parameters or the system proxy. Returns null if no proxy found 28 | */ 29 | export function getProxyAgent(requestURL: Url, proxy?: string, strictSSL?: boolean): any { 30 | const proxyURL = proxy || getSystemProxyURL(requestURL); 31 | 32 | if (!proxyURL) { 33 | return undefined; 34 | } 35 | 36 | const proxyEndpoint = parseUrl(proxyURL); 37 | 38 | if (!/^https?:$/.test(proxyEndpoint.protocol)) { 39 | return undefined; 40 | } 41 | 42 | const opts = { 43 | host: proxyEndpoint.hostname, 44 | port: Number(proxyEndpoint.port), 45 | auth: proxyEndpoint.auth, 46 | rejectUnauthorized: isBoolean(strictSSL) ? strictSSL : true 47 | }; 48 | 49 | return requestURL.protocol === 'http:' ? new HttpProxyAgent(opts) : new HttpsProxyAgent(opts); 50 | } 51 | -------------------------------------------------------------------------------- /src/models/connectionProfile.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | import LocalizedConstants = require('../constants/localizedConstants'); 3 | import { IConnectionProfile } from './interfaces'; 4 | import { ConnectionCredentials } from './connectionCredentials'; 5 | import { QuestionTypes, IQuestion, IPrompter, INameValueChoice } from '../prompts/question'; 6 | import * as utils from './utils'; 7 | 8 | // Concrete implementation of the IConnectionProfile interface 9 | 10 | /** 11 | * A concrete implementation of an IConnectionProfile with support for profile creation and validation 12 | */ 13 | export class ConnectionProfile extends ConnectionCredentials implements IConnectionProfile { 14 | public profileName: string; 15 | public savePassword: boolean; 16 | public emptyPasswordInput: boolean; 17 | 18 | /** 19 | * Creates a new profile by prompting the user for information. 20 | * @param {IPrompter} prompter that asks user the questions needed to complete a profile 21 | * @param {IConnectionProfile} (optional) default profile values that will be prefilled for questions, if any 22 | * @returns Promise - resolves to undefined if profile creation was not completed, or IConnectionProfile if completed 23 | */ 24 | public static createProfile(prompter: IPrompter, defaultProfileValues?: IConnectionProfile): Promise { 25 | let profile: ConnectionProfile = new ConnectionProfile(); 26 | // Ensure all core properties are entered 27 | let authOptions: INameValueChoice[] = ConnectionCredentials.getAuthenticationTypesChoice(); 28 | if (authOptions.length === 1) { 29 | // Set default value as there is only 1 option 30 | profile.authenticationType = authOptions[0].value; 31 | } 32 | 33 | let questions: IQuestion[] = ConnectionCredentials.getRequiredCredentialValuesQuestions(profile, true, false, defaultProfileValues); 34 | // Check if password needs to be saved 35 | questions.push( 36 | { 37 | type: QuestionTypes.input, 38 | name: LocalizedConstants.profileNamePrompt, 39 | message: LocalizedConstants.profileNamePrompt, 40 | placeHolder: LocalizedConstants.profileNamePlaceholder, 41 | default: defaultProfileValues ? defaultProfileValues.profileName : undefined, 42 | onAnswered: (value) => { 43 | // Fall back to a default name if none specified 44 | profile.profileName = value ? value : undefined; 45 | } 46 | }); 47 | 48 | return prompter.prompt(questions, true).then(answers => { 49 | if (answers && profile.isValidProfile()) { 50 | return profile; 51 | } 52 | // returning undefined to indicate failure to create the profile 53 | return undefined; 54 | }); 55 | } 56 | 57 | // Assumption: having connection string or server + profile name indicates all requirements were met 58 | private isValidProfile(): boolean { 59 | return utils.isNotEmpty(this.host) 60 | && utils.isNotEmpty(this.user); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/models/contracts/languageService.ts: -------------------------------------------------------------------------------- 1 | import {NotificationType} from 'vscode-languageclient'; 2 | import {Telemetry} from '../telemetry'; 3 | 4 | // ------------------------------- < IntelliSense Ready Event > ------------------------------------ 5 | 6 | /** 7 | * Event sent when the language service is finished updating after a connection 8 | */ 9 | export namespace IntelliSenseReadyNotification { 10 | export const type = new NotificationType('textDocument/intelliSenseReady'); 11 | } 12 | 13 | /** 14 | * Update event parameters 15 | */ 16 | export class IntelliSenseReadyParams { 17 | /** 18 | * URI identifying the text document 19 | */ 20 | public ownerUri: string; 21 | } 22 | 23 | /** 24 | * Notification sent when the an IntelliSense cache invalidation is requested 25 | */ 26 | export namespace RebuildIntelliSenseNotification { 27 | export const type = new NotificationType('textDocument/rebuildIntelliSense'); 28 | } 29 | 30 | /** 31 | * Rebuild IntelliSense notification parameters 32 | */ 33 | export class RebuildIntelliSenseParams { 34 | /** 35 | * URI identifying the text document 36 | */ 37 | public ownerUri: string; 38 | } 39 | 40 | // ------------------------------- ---------------------------------- 41 | // ------------------------------- < Telemetry Sent Event > ------------------------------------ 42 | 43 | /** 44 | * Event sent when the language service send a telemetry event 45 | */ 46 | export namespace TelemetryNotification { 47 | export const type = new NotificationType('telemetry/sqlevent'); 48 | } 49 | 50 | /** 51 | * Update event parameters 52 | */ 53 | export class TelemetryParams { 54 | public params: { 55 | eventName: string; 56 | properties: Telemetry.ITelemetryEventProperties; 57 | measures: Telemetry.ITelemetryEventMeasures; 58 | }; 59 | } 60 | 61 | // ------------------------------- ---------------------------------- 62 | // ------------------------------- < Status Event > ------------------------------------ 63 | 64 | /** 65 | * Event sent when the language service send a status change event 66 | */ 67 | export namespace StatusChangedNotification { 68 | export const type = new NotificationType('textDocument/statusChanged'); 69 | } 70 | 71 | /** 72 | * Update event parameters 73 | */ 74 | export class StatusChangeParams { 75 | /** 76 | * URI identifying the text document 77 | */ 78 | public ownerUri: string; 79 | 80 | /** 81 | * The new status of the document 82 | */ 83 | public status: string; 84 | } 85 | 86 | 87 | // ------------------------------- ---------------------------------- 88 | 89 | // ------------------------------- < Language Flavor Changed Event > ------------------------------------ 90 | /** 91 | * Language flavor change event parameters 92 | */ 93 | export class DidChangeLanguageFlavorParams { 94 | /** 95 | * URI identifying the text document 96 | */ 97 | public uri: string; 98 | /** 99 | * text document's language 100 | */ 101 | public language: string; 102 | /** 103 | * Sub-flavor for the langauge, e.g. 'PGSQL' for a SQL Server connection or 'Other' for any other SQL flavor 104 | */ 105 | public flavor: string; 106 | } 107 | 108 | /** 109 | * Notification sent when the language flavor is changed 110 | */ 111 | export namespace LanguageFlavorChangedNotification { 112 | export const type = new NotificationType('connection/languageflavorchanged'); 113 | } 114 | 115 | -------------------------------------------------------------------------------- /src/models/contracts/queryCancel.ts: -------------------------------------------------------------------------------- 1 | import {RequestType} from 'vscode-languageclient'; 2 | 3 | // Query Cancellation Request 4 | export namespace QueryCancelRequest { 5 | export const type = new RequestType('query/cancel'); 6 | } 7 | 8 | export class QueryCancelParams { 9 | ownerUri: string; 10 | } 11 | 12 | export class QueryCancelResult { 13 | messages: string; 14 | } 15 | -------------------------------------------------------------------------------- /src/models/contracts/queryDispose.ts: -------------------------------------------------------------------------------- 1 | import { RequestType } from 'vscode-languageclient'; 2 | 3 | export namespace QueryDisposeRequest { 4 | export const type = new RequestType('query/dispose'); 5 | } 6 | 7 | /** 8 | * Parameters to provide when disposing of a query 9 | */ 10 | export class QueryDisposeParams { 11 | ownerUri: string; 12 | } 13 | 14 | /** 15 | * Result received upon successful disposal of a query 16 | */ 17 | export class QueryDisposeResult { 18 | } 19 | -------------------------------------------------------------------------------- /src/models/errors.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the Source EULA. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | 6 | import { ErrorCodes } from './interfaces'; 7 | 8 | export class PlatformNotSupportedError extends Error { 9 | public static readonly message = ''; 10 | public readonly code: ErrorCodes = ErrorCodes.ERR_PLATFORM_NOT_SUPPORTED; 11 | 12 | constructor(message?: string, public platform?: string) { 13 | super(message || PlatformNotSupportedError.message); 14 | } 15 | } 16 | 17 | export class ArchitectureNotSupportedError extends PlatformNotSupportedError { 18 | public static readonly message = ''; 19 | public readonly code: ErrorCodes = ErrorCodes.ERR_ARCHITECTURE_NOT_SUPPORTED; 20 | 21 | constructor(message?: string, platform?: string, public architecture?: string) { 22 | super(message || ArchitectureNotSupportedError.message, platform); 23 | } 24 | } 25 | 26 | export class DistributionNotSupportedError extends PlatformNotSupportedError { 27 | public static readonly message = ''; 28 | public readonly code: ErrorCodes = ErrorCodes.ERR_DISTRIBUTION_NOT_SUPPORTED; 29 | 30 | constructor(message?: string, platform?: string, public distribution?: string) { 31 | super(message || DistributionNotSupportedError.message, platform); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/models/logger.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | import * as os from 'os'; 6 | import {ILogger} from './interfaces'; 7 | import * as Utils from './utils'; 8 | 9 | /* 10 | * Logger class handles logging messages using the Util functions. 11 | */ 12 | export class Logger implements ILogger { 13 | private _writer: (message: string) => void; 14 | private _prefix: string; 15 | 16 | private _indentLevel: number = 0; 17 | private _indentSize: number = 4; 18 | private _atLineStart: boolean = false; 19 | 20 | constructor(writer: (message: string) => void, prefix?: string) { 21 | this._writer = writer; 22 | this._prefix = prefix; 23 | } 24 | 25 | public logDebug(message: string): void { 26 | Utils.logDebug(message); 27 | } 28 | 29 | private _appendCore(message: string): void { 30 | if (this._atLineStart) { 31 | if (this._indentLevel > 0) { 32 | const indent = ' '.repeat(this._indentLevel * this._indentSize); 33 | this._writer(indent); 34 | } 35 | 36 | if (this._prefix) { 37 | this._writer(`[${this._prefix}] `); 38 | } 39 | 40 | this._atLineStart = false; 41 | } 42 | 43 | this._writer(message); 44 | } 45 | 46 | public increaseIndent(): void { 47 | this._indentLevel += 1; 48 | } 49 | 50 | public decreaseIndent(): void { 51 | if (this._indentLevel > 0) { 52 | this._indentLevel -= 1; 53 | } 54 | } 55 | 56 | public append(message?: string): void { 57 | message = message || ''; 58 | this._appendCore(message); 59 | } 60 | 61 | public appendLine(message?: string): void { 62 | message = message || ''; 63 | this._appendCore(message + os.EOL); 64 | this._atLineStart = true; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/models/propertyUpdater.ts: -------------------------------------------------------------------------------- 1 | 'use string'; 2 | import { InputBoxOptions, QuickPickOptions } from 'vscode'; 3 | 4 | // A class that simplifies populating values on an object from the VSCode command palette. 5 | // Provides a wrapper around the necessary options to display, a callback to see if update 6 | // is needed, and the setter to be called on the object 7 | export class PropertyUpdater { 8 | 9 | constructor( 10 | public inputBoxOptions: InputBoxOptions, 11 | public quickPickOptions: QuickPickOptions, 12 | private propertyChecker: (obj: T) => boolean, 13 | private propertySetter: (obj: T, input: string) => void) { 14 | } 15 | 16 | public static CreateQuickPickUpdater( 17 | quickPickOptions: QuickPickOptions, 18 | propertyChecker: (obj: T) => boolean, 19 | propertySetter: (obj: T, input: string) => void): PropertyUpdater { 20 | 21 | return new PropertyUpdater(undefined, quickPickOptions, propertyChecker, propertySetter); 22 | } 23 | 24 | public static CreateInputBoxUpdater( 25 | inputBoxOptions: InputBoxOptions, 26 | propertyChecker: (obj: T) => boolean, 27 | propertySetter: (obj: T, input: string) => void): PropertyUpdater { 28 | 29 | return new PropertyUpdater(inputBoxOptions, undefined, propertyChecker, propertySetter); 30 | } 31 | 32 | public isQuickPickUpdater(): boolean { 33 | if (this.quickPickOptions) { 34 | return true; 35 | } 36 | return false; 37 | } 38 | 39 | public isUpdateRequired(parentObject: T): boolean { 40 | return this.propertyChecker(parentObject); 41 | } 42 | 43 | public updatePropery(parentObject: T, propertyValue: string): void { 44 | this.propertySetter(parentObject, propertyValue); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/prompts/checkbox.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // This code is originally from https://github.com/DonJayamanne/bowerVSCode 4 | // License: https://github.com/DonJayamanne/bowerVSCode/blob/master/LICENSE 5 | 6 | import { window } from 'vscode'; 7 | import Prompt from './prompt'; 8 | import EscapeException from '../utils/EscapeException'; 9 | 10 | const figures = require('figures'); 11 | 12 | export default class CheckboxPrompt extends Prompt { 13 | 14 | constructor(question: any, ignoreFocusOut?: boolean) { 15 | super(question, ignoreFocusOut); 16 | } 17 | 18 | public render(): any { 19 | let choices = this._question.choices.reduce((result, choice) => { 20 | let choiceName = choice.name || choice; 21 | result[`${choice.checked === true ? figures.radioOn : figures.radioOff} ${choiceName}`] = choice; 22 | return result; 23 | }, {}); 24 | 25 | let options = this.defaultQuickPickOptions; 26 | options.placeHolder = this._question.message; 27 | 28 | let quickPickOptions = Object.keys(choices); 29 | quickPickOptions.push(figures.tick); 30 | 31 | return window.showQuickPick(quickPickOptions, options) 32 | .then(result => { 33 | if (result === undefined) { 34 | throw new EscapeException(); 35 | } 36 | 37 | if (result !== figures.tick) { 38 | choices[result].checked = !choices[result].checked; 39 | 40 | return this.render(); 41 | } 42 | 43 | return this._question.choices.reduce((result2, choice) => { 44 | if (choice.checked === true) { 45 | result2.push(choice.value); 46 | } 47 | 48 | return result2; 49 | }, []); 50 | }); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/prompts/confirm.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // This code is originally from https://github.com/DonJayamanne/bowerVSCode 4 | // License: https://github.com/DonJayamanne/bowerVSCode/blob/master/LICENSE 5 | 6 | import { window } from 'vscode'; 7 | import Prompt from './prompt'; 8 | import LocalizedConstants = require('../constants/localizedConstants'); 9 | import EscapeException from '../utils/EscapeException'; 10 | 11 | export default class ConfirmPrompt extends Prompt { 12 | 13 | constructor(question: any, ignoreFocusOut?: boolean) { 14 | super(question, ignoreFocusOut); 15 | } 16 | 17 | public render(): any { 18 | let choices: { [id: string]: boolean } = {}; 19 | choices[LocalizedConstants.msgYes] = true; 20 | choices[LocalizedConstants.msgNo] = false; 21 | 22 | let options = this.defaultQuickPickOptions; 23 | options.placeHolder = this._question.message; 24 | 25 | return window.showQuickPick(Object.keys(choices), options) 26 | .then(result => { 27 | if (result === undefined) { 28 | throw new EscapeException(); 29 | } 30 | 31 | return choices[result] || false; 32 | }); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/prompts/expand.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // This code is originally from https://github.com/DonJayamanne/bowerVSCode 4 | // License: https://github.com/DonJayamanne/bowerVSCode/blob/master/LICENSE 5 | 6 | import vscode = require('vscode'); 7 | import Prompt from './prompt'; 8 | import EscapeException from '../utils/EscapeException'; 9 | import { INameValueChoice } from './question'; 10 | 11 | const figures = require('figures'); 12 | 13 | export default class ExpandPrompt extends Prompt { 14 | 15 | constructor(question: any, ignoreFocusOut?: boolean) { 16 | super(question, ignoreFocusOut); 17 | } 18 | 19 | public render(): any { 20 | // label indicates this is a quickpick item. Otherwise it's a name-value pair 21 | if (this._question.choices[0].label) { 22 | return this.renderQuickPick(this._question.choices); 23 | } else { 24 | return this.renderNameValueChoice(this._question.choices); 25 | } 26 | } 27 | 28 | private renderQuickPick(choices: vscode.QuickPickItem[]): any { 29 | let options = this.defaultQuickPickOptions; 30 | options.placeHolder = this._question.message; 31 | 32 | return vscode.window.showQuickPick(choices, options) 33 | .then(result => { 34 | if (result === undefined) { 35 | throw new EscapeException(); 36 | } 37 | 38 | return this.validateAndReturn(result || false); 39 | }); 40 | } 41 | private renderNameValueChoice(choices: INameValueChoice[]): any { 42 | const choiceMap = this._question.choices.reduce((result, choice) => { 43 | result[choice.name] = choice.value; 44 | return result; 45 | }, {}); 46 | 47 | let options = this.defaultQuickPickOptions; 48 | options.placeHolder = this._question.message; 49 | 50 | return vscode.window.showQuickPick(Object.keys(choiceMap), options) 51 | .then(result => { 52 | if (result === undefined) { 53 | throw new EscapeException(); 54 | } 55 | 56 | // Note: cannot be used with 0 or false responses 57 | let returnVal = choiceMap[result] || false; 58 | return this.validateAndReturn(returnVal); 59 | }); 60 | } 61 | 62 | private validateAndReturn(value: any): any { 63 | if (!this.validate(value)) { 64 | return this.render(); 65 | } 66 | return value; 67 | } 68 | 69 | private validate(value: any): boolean { 70 | const validationError = this._question.validate ? this._question.validate(value || '') : undefined; 71 | 72 | if (validationError) { 73 | this._question.message = `${figures.warning} ${validationError}`; 74 | return false; 75 | } 76 | return true; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/prompts/factory.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // This code is originally from https://github.com/DonJayamanne/bowerVSCode 4 | // License: https://github.com/DonJayamanne/bowerVSCode/blob/master/LICENSE 5 | 6 | import Prompt from './prompt'; 7 | import InputPrompt from './input'; 8 | import PasswordPrompt from './password'; 9 | import ListPrompt from './list'; 10 | import ConfirmPrompt from './confirm'; 11 | import CheckboxPrompt from './checkbox'; 12 | import ExpandPrompt from './expand'; 13 | 14 | export default class PromptFactory { 15 | 16 | public static createPrompt(question: any, ignoreFocusOut?: boolean): Prompt { 17 | /** 18 | * TODO: 19 | * - folder 20 | */ 21 | switch (question.type || 'input') { 22 | case 'string': 23 | case 'input': 24 | return new InputPrompt(question, ignoreFocusOut); 25 | case 'password': 26 | return new PasswordPrompt(question, ignoreFocusOut); 27 | case 'list': 28 | return new ListPrompt(question, ignoreFocusOut); 29 | case 'confirm': 30 | return new ConfirmPrompt(question, ignoreFocusOut); 31 | case 'checkbox': 32 | return new CheckboxPrompt(question, ignoreFocusOut); 33 | case 'expand': 34 | return new ExpandPrompt(question, ignoreFocusOut); 35 | default: 36 | throw new Error(`Could not find a prompt for question type ${question.type}`); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/prompts/input.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // This code is originally from https://github.com/DonJayamanne/bowerVSCode 4 | // License: https://github.com/DonJayamanne/bowerVSCode/blob/master/LICENSE 5 | 6 | import {window, InputBoxOptions} from 'vscode'; 7 | import Prompt from './prompt'; 8 | import EscapeException from '../utils/EscapeException'; 9 | 10 | const figures = require('figures'); 11 | 12 | export default class InputPrompt extends Prompt { 13 | 14 | protected _options: InputBoxOptions; 15 | 16 | constructor(question: any, ignoreFocusOut?: boolean) { 17 | super(question, ignoreFocusOut); 18 | 19 | this._options = this.defaultInputBoxOptions; 20 | this._options.prompt = this._question.message; 21 | } 22 | 23 | // Helper for callers to know the right type to get from the type factory 24 | public static get promptType(): string { return 'input'; } 25 | 26 | public render(): any { 27 | // Prefer default over the placeHolder, if specified 28 | let placeHolder = this._question.default ? this._question.default : this._question.placeHolder; 29 | 30 | if (this._question.default instanceof Error) { 31 | placeHolder = this._question.default.message; 32 | this._question.default = undefined; 33 | } 34 | 35 | this._options.placeHolder = placeHolder; 36 | 37 | return window.showInputBox(this._options) 38 | .then(result => { 39 | if (result === undefined) { 40 | throw new EscapeException(); 41 | } 42 | 43 | if (result === '') { 44 | // Use the default value, if defined 45 | result = this._question.default || ''; 46 | } 47 | 48 | const validationError = this._question.validate ? this._question.validate(result || '') : undefined; 49 | 50 | if (validationError) { 51 | this._question.default = new Error(`${figures.warning} ${validationError}`); 52 | 53 | return this.render(); 54 | } 55 | 56 | return result; 57 | }); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/prompts/list.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // This code is originally from https://github.com/DonJayamanne/bowerVSCode 4 | // License: https://github.com/DonJayamanne/bowerVSCode/blob/master/LICENSE 5 | 6 | import { window } from 'vscode'; 7 | import Prompt from './prompt'; 8 | import EscapeException from '../utils/EscapeException'; 9 | 10 | export default class ListPrompt extends Prompt { 11 | 12 | constructor(question: any, ignoreFocusOut?: boolean) { 13 | super(question, ignoreFocusOut); 14 | } 15 | 16 | public render(): any { 17 | const choices = this._question.choices.reduce((result, choice) => { 18 | result[choice.name || choice] = choice.value || choice; 19 | return result; 20 | }, {}); 21 | 22 | let options = this.defaultQuickPickOptions; 23 | options.placeHolder = this._question.message; 24 | 25 | return window.showQuickPick(Object.keys(choices), options) 26 | .then(result => { 27 | if (result === undefined) { 28 | throw new EscapeException(); 29 | } 30 | 31 | return choices[result]; 32 | }); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/prompts/password.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // This code is originally from https://github.com/DonJayamanne/bowerVSCode 4 | // License: https://github.com/DonJayamanne/bowerVSCode/blob/master/LICENSE 5 | import InputPrompt from './input'; 6 | 7 | export default class PasswordPrompt extends InputPrompt { 8 | 9 | constructor(question: any, ignoreFocusOut?: boolean) { 10 | super(question, ignoreFocusOut); 11 | 12 | this._options.password = true; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/prompts/progressIndicator.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // This code is originally from https://github.com/DonJayamanne/bowerVSCode 4 | // License: https://github.com/DonJayamanne/bowerVSCode/blob/master/LICENSE 5 | 6 | import {window, StatusBarItem, StatusBarAlignment} from 'vscode'; 7 | 8 | export default class ProgressIndicator { 9 | 10 | private _statusBarItem: StatusBarItem; 11 | 12 | constructor() { 13 | this._statusBarItem = window.createStatusBarItem(StatusBarAlignment.Left); 14 | } 15 | 16 | private _tasks: string[] = []; 17 | public beginTask(task: string): void { 18 | this._tasks.push(task); 19 | this.displayProgressIndicator(); 20 | } 21 | 22 | public endTask(task: string): void { 23 | if (this._tasks.length > 0) { 24 | this._tasks.pop(); 25 | } 26 | 27 | this.setMessage(); 28 | } 29 | 30 | private setMessage(): void { 31 | if (this._tasks.length === 0) { 32 | this._statusBarItem.text = ''; 33 | this.hideProgressIndicator(); 34 | return; 35 | } 36 | 37 | this._statusBarItem.text = this._tasks[this._tasks.length - 1]; 38 | this._statusBarItem.show(); 39 | } 40 | 41 | private _interval: any; 42 | private displayProgressIndicator(): void { 43 | this.setMessage(); 44 | this.hideProgressIndicator(); 45 | this._interval = setInterval(() => this.onDisplayProgressIndicator(), 100); 46 | } 47 | private hideProgressIndicator(): void { 48 | if (this._interval) { 49 | clearInterval(this._interval); 50 | this._interval = undefined; 51 | } 52 | this.ProgressCounter = 0; 53 | } 54 | 55 | private ProgressText = ['|', '/', '-', '\\', '|', '/', '-', '\\']; 56 | private ProgressCounter = 0; 57 | private onDisplayProgressIndicator(): void { 58 | if (this._tasks.length === 0) { 59 | return; 60 | } 61 | 62 | let txt = this.ProgressText[this.ProgressCounter]; 63 | this._statusBarItem.text = this._tasks[this._tasks.length - 1] + ' ' + txt; 64 | this.ProgressCounter++; 65 | 66 | if (this.ProgressCounter >= this.ProgressText.length - 1) { 67 | this.ProgressCounter = 0; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/prompts/prompt.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // This code is originally from https://github.com/DonJayamanne/bowerVSCode 4 | // License: https://github.com/DonJayamanne/bowerVSCode/blob/master/LICENSE 5 | 6 | import { InputBoxOptions, QuickPickOptions } from 'vscode'; 7 | 8 | abstract class Prompt { 9 | 10 | protected _question: any; 11 | protected _ignoreFocusOut?: boolean; 12 | 13 | constructor(question: any, ignoreFocusOut?: boolean) { 14 | this._question = question; 15 | this._ignoreFocusOut = ignoreFocusOut ? ignoreFocusOut : false; 16 | } 17 | 18 | public abstract render(): any; 19 | 20 | protected get defaultQuickPickOptions(): QuickPickOptions { 21 | return { 22 | ignoreFocusOut: this._ignoreFocusOut 23 | }; 24 | } 25 | 26 | protected get defaultInputBoxOptions(): InputBoxOptions { 27 | return { 28 | ignoreFocusOut: this._ignoreFocusOut 29 | }; 30 | } 31 | } 32 | 33 | export default Prompt; 34 | -------------------------------------------------------------------------------- /src/prompts/question.ts: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | import vscode = require('vscode'); 5 | 6 | export class QuestionTypes { 7 | public static get input(): string { return 'input'; } 8 | public static get password(): string { return 'password'; } 9 | public static get list(): string { return 'list'; } 10 | public static get confirm(): string { return 'confirm'; } 11 | public static get checkbox(): string { return 'checkbox'; } 12 | public static get expand(): string { return 'expand'; } 13 | } 14 | 15 | // Question interface to clarify how to use the prompt feature 16 | // based on Bower Question format: https://github.com/bower/bower/blob/89069784bb46bfd6639b4a75e98a0d7399a8c2cb/packages/bower-logger/README.md 17 | export interface IQuestion { 18 | // Type of question (see QuestionTypes) 19 | type: string; 20 | // Name of the question for disambiguation 21 | name: string; 22 | // Message to display to the user 23 | message: string; 24 | // Optional placeHolder to give more detailed information to the user 25 | placeHolder?: any; 26 | // Optional default value - this will be used instead of placeHolder 27 | default?: any; 28 | // optional set of choices to be used. Can be QuickPickItems or a simple name-value pair 29 | choices?: Array; 30 | // Optional validation function that returns an error string if validation fails 31 | validate?: (value: any) => string; 32 | // Optional pre-prompt function. Takes in set of answers so far, and returns true if prompt should occur 33 | shouldPrompt?: (answers: {[id: string]: any}) => boolean; 34 | // Optional action to take on the question being answered 35 | onAnswered?: (value: any) => void; 36 | // Optional set of options to support matching choices. 37 | matchOptions?: vscode.QuickPickOptions; 38 | } 39 | 40 | // Pair used to display simple choices to the user 41 | export interface INameValueChoice { 42 | name: string; 43 | value: any; 44 | } 45 | 46 | // Generic object that can be used to define a set of questions and handle the result 47 | export interface IQuestionHandler { 48 | // Set of questions to be answered 49 | questions: IQuestion[]; 50 | // Optional callback, since questions may handle themselves 51 | callback?: IPromptCallback; 52 | } 53 | 54 | export interface IPrompter { 55 | promptSingle(question: IQuestion, ignoreFocusOut?: boolean): Promise; 56 | /** 57 | * Prompts for multiple questions 58 | * 59 | * @returns {[questionId: string]: T} Map of question IDs to results, or undefined if 60 | * the user canceled the question session 61 | */ 62 | prompt(questions: IQuestion[], ignoreFocusOut?: boolean): Promise<{[questionId: string]: T}>; 63 | promptCallback(questions: IQuestion[], callback: IPromptCallback): void; 64 | } 65 | 66 | export interface IPromptCallback { 67 | (answers: {[id: string]: any}): void; 68 | } 69 | -------------------------------------------------------------------------------- /src/utils/EscapeException.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | export default require('error-ex')('EscapeException'); 4 | -------------------------------------------------------------------------------- /src/utils/symbol.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | export const star = '✰'; 4 | -------------------------------------------------------------------------------- /src/utils/validationException.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | export default require('error-ex')('ValidationException'); 4 | -------------------------------------------------------------------------------- /src/views/htmlcontent/gulpfile.js: -------------------------------------------------------------------------------- 1 | require('../../../gulpfile'); -------------------------------------------------------------------------------- /src/views/htmlcontent/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "htmlcontent", 3 | "version": "1.0.0", 4 | "description": "", 5 | "dependencies": { 6 | "@angular/common": "~2.1.2", 7 | "@angular/compiler": "~2.1.2", 8 | "@angular/core": "~2.1.2", 9 | "@angular/forms": "~2.1.2", 10 | "@angular/http": "~2.1.2", 11 | "@angular/platform-browser": "~2.1.2", 12 | "@angular/platform-browser-dynamic": "~2.1.2", 13 | "@angular/router": "~3.1.2", 14 | "@angular/upgrade": "~2.1.2", 15 | "angular-in-memory-web-api": "~0.1.13", 16 | "angular2-slickgrid": "github:microsoft/angular2-slickgrid#1.2.2", 17 | "copy-paste": "^1.3.0", 18 | "core-js": "^2.4.1", 19 | "jasmine-core": "~2.4.1", 20 | "moment": "^2.15.1", 21 | "rangy": "^1.3.0", 22 | "reflect-metadata": "0.1.12", 23 | "rxjs": "5.0.0-beta.12", 24 | "slickgrid": "github:anthonydresser/SlickGrid#2.3.23", 25 | "systemjs": "0.19.40", 26 | "systemjs-plugin-json": "^0.2.0", 27 | "underscore": "^1.8.3", 28 | "zone.js": "^0.6.26" 29 | }, 30 | "devDependencies": { 31 | "assert": "^1.4.1" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/css/flexbox.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | height: 100%; 4 | margin: 0; 5 | } 6 | 7 | .fullsize { 8 | height: 100%; 9 | } 10 | /* vertical box styles */ 11 | .vertBox { 12 | display: flex; 13 | flex-flow: column; 14 | } 15 | 16 | .vertBox .boxRow.header { 17 | flex: 0 0 auto; 18 | } 19 | 20 | .vertBox .boxRow.content { 21 | flex: 1 1 0; 22 | } 23 | 24 | .results { 25 | flex: 100 1 0; 26 | } 27 | 28 | .scrollable { 29 | overflow: auto; 30 | } 31 | 32 | .maxHeight { 33 | max-height: fit-content; 34 | } 35 | 36 | .messages { 37 | flex: 1 100 0; 38 | min-height: 15%; 39 | } 40 | 41 | .minHeight { 42 | min-height: fit-content; 43 | } 44 | 45 | /* horizontal box style */ 46 | .horzBox { 47 | display: flex; 48 | flex-flow: row; 49 | } 50 | 51 | .horzBox .boxCol.content { 52 | flex: 1 1 1%; 53 | overflow: auto; 54 | max-width: fit-content; 55 | } 56 | 57 | .hidden { 58 | display: none !important; 59 | } 60 | 61 | /* testing 62 | 63 | .vertBox { 64 | border: 1px solid green; 65 | } 66 | 67 | .horzBox { 68 | border: 1px solid red; 69 | } 70 | */ -------------------------------------------------------------------------------- /src/views/htmlcontent/src/css/styles.css: -------------------------------------------------------------------------------- 1 | /* context menu */ 2 | .contextMenu { 3 | position: absolute; 4 | padding: 0px; 5 | display: inline-block; 6 | min-width: 100px; 7 | z-index: 99999; 8 | border: 1px; 9 | outline: 0; 10 | color: black; 11 | background-color: white; 12 | border-color: var(--border-color-default); 13 | font-family: var(--font-family); 14 | } 15 | 16 | .contextMenu li { 17 | padding: 4px 14px 4px 14px; 18 | list-style: none; 19 | cursor: default; 20 | } 21 | 22 | .contextMenu li+li { 23 | border-top: 0.5px solid #E4E4E4; 24 | } 25 | 26 | .contextMenu li.disabled { 27 | color: #777; 28 | text-decoration: none; 29 | background-color: transparent; 30 | opacity: 0.4; 31 | } 32 | 33 | /* slick grid */ 34 | 35 | .boxRow.content.horzBox.slickgrid { 36 | margin-bottom: 2px; 37 | } 38 | 39 | .boxRow.content.horzBox.slickgrid:last-child { 40 | margin-bottom: 0px; 41 | } 42 | 43 | .contextMenu li:hover:not(.disabled) { 44 | background-color: #007ACC; 45 | color: white; 46 | } 47 | 48 | .boxRow.content.padded { 49 | padding: 15px 50 | } 51 | 52 | /* icon */ 53 | .icon { 54 | padding: 8px; 55 | background-repeat: no-repeat; 56 | background-position: 0px; 57 | } 58 | 59 | .gridIcon { 60 | margin: 5px 5px; 61 | } 62 | 63 | /* messages */ 64 | table { 65 | font-weight: inherit; 66 | font-size: inherit; 67 | table-layout: fixed; 68 | border-collapse: collapse; 69 | width: 100%; 70 | } 71 | 72 | .wide { 73 | width: 110px; 74 | } 75 | 76 | #messageTable td { 77 | padding-right: 20px; 78 | color: var(--color-content); 79 | } 80 | 81 | #messageTable tbody tr:last-child > td { 82 | padding-bottom: 1em; 83 | } 84 | .messageValue { 85 | white-space: pre-line; 86 | } 87 | 88 | /* headers */ 89 | .header { 90 | height: auto; 91 | overflow: hidden; 92 | height: 22px; 93 | padding-left: 20px; 94 | line-height: 22px; 95 | } 96 | 97 | .header > span { 98 | float: left; 99 | font-size: 11px; 100 | font-weight: 700; 101 | text-transform: uppercase; 102 | } 103 | 104 | .resizableHandle { 105 | font-size: 0.1px; 106 | display: block; 107 | float: right; 108 | position: absolute; 109 | cursor: row-resize; 110 | top: 0; 111 | height: 4px; 112 | width: 100%; 113 | z-index: 1; 114 | } 115 | 116 | #resizeHandle { 117 | font-size: 0.1px; 118 | position: absolute; 119 | cursor: row-resize; 120 | height: 4px; 121 | width: 100%; 122 | z-index: 2; 123 | background-color: var(--color-resize-handle); 124 | } 125 | 126 | .header > span.shortCut { 127 | float: right; 128 | padding-right: 5px; 129 | } -------------------------------------------------------------------------------- /src/views/htmlcontent/src/html/contextmenu.component.html: -------------------------------------------------------------------------------- 1 |
    2 |
  • {{Constants.saveCSVLabel}} 3 | {{keys['event.saveAsCSV']}}
  • 4 |
  • {{Constants.saveJSONLabel}} 5 | {{keys['event.saveAsJSON']}}
  • 6 |
  • {{Constants.saveExcelLabel}} 7 | {{keys['event.saveAsExcel']}}
  • 8 |
  • {{Constants.selectAll}} 9 | {{keys['event.selectAll']}}
  • 10 |
  • {{Constants.copyLabel}} 11 | {{keys['event.copySelection']}}
  • 12 |
  • {{Constants.copyWithHeadersLabel}} 13 | {{keys['event.copyWithHeaders']}}
  • 14 |
-------------------------------------------------------------------------------- /src/views/htmlcontent/src/html/messagescontextmenu.component.html: -------------------------------------------------------------------------------- 1 |
    2 |
  • {{Constants.copyLabel}} 3 | {{keys['event.copySelection']}} 4 |
  • 5 |
-------------------------------------------------------------------------------- /src/views/htmlcontent/src/html/sqlOutput.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | Angular 2 QuickStart 4 | 5 | 6 | 22 | 23 | 24 | 25 | <%if (theme === 'vscode-light') { %> 26 | 27 | <%} else { %> 28 | 29 | <% } %> 30 | 31 | 32 | 33 | 34 | 35 | 36 | <% if (prod) { %> 37 | 38 | <% } else { %> 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | <% } %> 57 | 60 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/ExitFullScreen_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/vscode-postgresql/a3ee951dc73387eff177a4aba702a855930d529d/src/views/htmlcontent/src/images/ExitFullScreen_16x.png -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/ExitFullScreen_16x.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/ExitFullScreen_16x_inverse.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/ExitFullScreen_16x_vscode.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/ExitFullScreen_16x_vscode_inverse.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/ExtendToFullScreen_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/vscode-postgresql/a3ee951dc73387eff177a4aba702a855930d529d/src/views/htmlcontent/src/images/ExtendToFullScreen_16x.png -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/ExtendToFullScreen_16x.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/ExtendToFullScreen_16x_inverse.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/ExtendToFullScreen_16x_vscode.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/ExtendToFullScreen_16x_vscode_inverse.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/ResultToCSV_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/vscode-postgresql/a3ee951dc73387eff177a4aba702a855930d529d/src/views/htmlcontent/src/images/ResultToCSV_16x.png -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/ResultToCSV_16x.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/ResultToCSV_16x_inverse.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/ResultToCSV_16x_vscode.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/ResultToCSV_16x_vscode_inverse.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/ResultToJSON_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/vscode-postgresql/a3ee951dc73387eff177a4aba702a855930d529d/src/views/htmlcontent/src/images/ResultToJSON_16x.png -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/ResultToJSON_16x.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/ResultToJSON_16x_inverse.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/ResultToJSON_16x_vscode.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/ResultToJSON_16x_vscode_inverse.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/ResultToText_16x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/vscode-postgresql/a3ee951dc73387eff177a4aba702a855930d529d/src/views/htmlcontent/src/images/ResultToText_16x.png -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/ResultToText_16x.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/ResultToText_16x_inverse.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/ResultToText_16x_vscode.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/ResultToText_16x_vscode_inverse.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/ResultToXlsx_16x_vscode.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/ResultToXlsx_16x_vscode_inverse.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/add-all.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/app_Icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/vscode-postgresql/a3ee951dc73387eff177a4aba702a855930d529d/src/views/htmlcontent/src/images/app_Icon.icns -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/app_Icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/vscode-postgresql/a3ee951dc73387eff177a4aba702a855930d529d/src/views/htmlcontent/src/images/app_Icon.ico -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/app_Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/vscode-postgresql/a3ee951dc73387eff177a4aba702a855930d529d/src/views/htmlcontent/src/images/app_Icon.png -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/app_Icon.svg: -------------------------------------------------------------------------------- 1 | logo -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/arrow-down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/arrow-left-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/arrow-up-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/arrow-up.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/chevron-down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/circle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/close-red.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/close-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/col-type-boolean.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/col-type-number.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/col-type-string.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 15 | 24 | 31 | 32 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/col-type-timedate.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/create-project.svg: -------------------------------------------------------------------------------- 1 | 2 | new_project -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/data-profile.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/delete.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/edit-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 13 | 14 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/edit.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 13 | 14 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/filter-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/filter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/filteradd.svg: -------------------------------------------------------------------------------- 1 | icon_new -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/filtersubtract.svg: -------------------------------------------------------------------------------- 1 | icon_new -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/input.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/maximize.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 11 | 12 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/minus-all-objects.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/open-datasource.svg: -------------------------------------------------------------------------------- 1 | open_datasource -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/open-project.svg: -------------------------------------------------------------------------------- 1 | open_project -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/output.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/progress_36x_animation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/vscode-postgresql/a3ee951dc73387eff177a4aba702a855930d529d/src/views/htmlcontent/src/images/progress_36x_animation.gif -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/query.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/recent-project.svg: -------------------------------------------------------------------------------- 1 | recent_project -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/refine.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 9 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/sad.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/shift-left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/smiley.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/sort-ascending.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/status-fail.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 14 | 15 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/status-none.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 8 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/status-success.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 13 | 14 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/status_inprogress.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 9 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/table.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/images/tutorial.json: -------------------------------------------------------------------------------- 1 | { 2 | "welcomeText": "We've put together a short tutorial video that will get you started faster. You can also take a quick tour of general interface to see what's new and essential feature of this product.", 3 | "mainVideo": { 4 | "title": "Overview", 5 | "url": "https://onedrive.live.com/embed?cid=A72B50246D328C43&resid=A72B50246D328C43%21118687&authkey=AJ8guXj9wIItsrI", 6 | "ratio": "16:9" 7 | }, 8 | "videos": [{ 9 | "title": "Demo 1", 10 | "url": "https://onedrive.live.com/embed?cid=A72B50246D328C43&resid=A72B50246D328C43%21118687&authkey=AJ8guXj9wIItsrI", 11 | "ratio": "16:9" 12 | }, { 13 | "title": "Demo 2", 14 | "url": "https://onedrive.live.com/embed?cid=A72B50246D328C43&resid=A72B50246D328C43%21118687&authkey=AJ8guXj9wIItsrI", 15 | "ratio": "16:9" 16 | }], 17 | "newFeatures": [{ 18 | "title": "Data quality bar", 19 | "description": "Displaying overview quality for each data column.", 20 | "url": "https://onedrive.live.com/embed?cid=A72B50246D328C43&resid=A72B50246D328C43%21118687&authkey=AJ8guXj9wIItsrI" 21 | }, { 22 | "title": "Inspector", 23 | "description": "Profiling data from different angles.", 24 | "url": "https://onedrive.live.com/embed?cid=A72B50246D328C43&resid=A72B50246D328C43%21118687&authkey=AJ8guXj9wIItsrI" 25 | }, { 26 | "title": "Summarize editor", 27 | "description": "An interactive way to perform summarize transformation.", 28 | "url": "https://onedrive.live.com/embed?cid=A72B50246D328C43&resid=A72B50246D328C43%21118687&authkey=AJ8guXj9wIItsrI" 29 | }], 30 | "tutorials": [{ 31 | "label": "Tutorial 1", 32 | "url": "https://onedrive.live.com/embed?cid=A72B50246D328C43&resid=A72B50246D328C43%21118687&authkey=AJ8guXj9wIItsrI" 33 | }, { 34 | "label": "Tutorial 2", 35 | "url": "https://onedrive.live.com/embed?cid=A72B50246D328C43&resid=A72B50246D328C43%21118687&authkey=AJ8guXj9wIItsrI" 36 | },{ 37 | "label": "Tutorial 3", 38 | "url": "https://onedrive.live.com/embed?cid=A72B50246D328C43&resid=A72B50246D328C43%21118687&authkey=AJ8guXj9wIItsrI" 39 | }, { 40 | "label": "Tutorial 4", 41 | "url": "https://onedrive.live.com/embed?cid=A72B50246D328C43&resid=A72B50246D328C43%21118687&authkey=AJ8guXj9wIItsrI" 42 | }] 43 | } -------------------------------------------------------------------------------- /src/views/htmlcontent/src/js/app.module.ts: -------------------------------------------------------------------------------- 1 | /* -------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | * ------------------------------------------------------------------------------------------ */ 5 | import { NgModule, ValueProvider } from '@angular/core'; 6 | import { BrowserModule } from '@angular/platform-browser'; 7 | import { FormsModule } from '@angular/forms'; 8 | import { HttpModule, JsonpModule } from '@angular/http'; 9 | 10 | import { SlickGrid } from 'angular2-slickgrid'; 11 | 12 | import { AppComponent } from './components/app.component'; 13 | import { ScrollDirective } from './directives/scroll.directive'; 14 | import { MouseDownDirective } from './directives/mousedown.directive'; 15 | import { ContextMenu } from './components/contextmenu.component'; 16 | import { MessagesContextMenu } from './components/messagescontextmenu.component'; 17 | 18 | /** 19 | * Top level angular module, no actual content here 20 | */ 21 | const WINDOW_PROVIDER: ValueProvider = { 22 | provide: Window, 23 | useValue: window 24 | }; 25 | 26 | @NgModule({ 27 | imports: [ 28 | BrowserModule, 29 | HttpModule, 30 | JsonpModule, 31 | FormsModule 32 | ], 33 | providers: [ 34 | WINDOW_PROVIDER 35 | ], 36 | declarations: [ AppComponent, SlickGrid, ScrollDirective, MouseDownDirective, ContextMenu, MessagesContextMenu], 37 | bootstrap: [ AppComponent ] 38 | }) 39 | export class AppModule { } 40 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/js/components/messagescontextmenu.component.ts: -------------------------------------------------------------------------------- 1 | /* -------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | * ------------------------------------------------------------------------------------------ */ 5 | import { Component, Output, EventEmitter, Inject, forwardRef, OnInit } from '@angular/core'; 6 | 7 | import {ShortcutService} from './../services/shortcuts.service'; 8 | 9 | import * as Constants from './../constants'; 10 | import * as Utils from './../utils'; 11 | 12 | 13 | import { IRange } from './../interfaces'; 14 | 15 | /** 16 | * The component that acts as the contextMenu for slick grid 17 | */ 18 | 19 | const template = ` 20 |
    21 |
  • {{Constants.copyLabel}} 22 | {{keys['event.copySelection']}} 23 |
  • 24 |
25 | `; 26 | 27 | @Component({ 28 | selector: 'msg-context-menu', 29 | providers: [ShortcutService], 30 | template: template 31 | }) 32 | 33 | export class MessagesContextMenu implements OnInit { 34 | // tslint:disable-next-line:no-unused-variable 35 | private Utils = Utils; 36 | // tslint:disable-next-line:no-unused-variable 37 | private Constants = Constants; 38 | 39 | @Output() clickEvent: EventEmitter<{type: string, selectedRange: IRange }> 40 | = new EventEmitter<{type: string, selectedRange: IRange}>(); 41 | private selectedRange: IRange; 42 | private isDisabled: boolean; 43 | private position: {x: number, y: number} = {x: 0, y: 0}; 44 | private visible: boolean = false; 45 | private keys = { 46 | 'event.copySelection': '' 47 | }; 48 | 49 | 50 | constructor(@Inject(forwardRef(() => ShortcutService)) private shortcuts: ShortcutService) { 51 | const self = this; 52 | for (let key in this.keys) { 53 | if (this.keys.hasOwnProperty(key)) { 54 | this.shortcuts.stringCodeFor(key).then((result) => { 55 | self.keys[key] = result; 56 | }); 57 | } 58 | } 59 | } 60 | 61 | ngOnInit(): void { 62 | const self = this; 63 | $(document).on('click', () => { 64 | self.hide(); 65 | }); 66 | } 67 | 68 | show(x: number, y: number, selectedRange: IRange): void { 69 | this.selectedRange = selectedRange; 70 | let selectedText = (selectedRange && selectedRange.toString) ? selectedRange.toString() : ''; 71 | this.isDisabled = selectedText.length === 0; 72 | this.position = { x: x, y: y}; 73 | this.visible = true; 74 | } 75 | 76 | 77 | hide(): void { 78 | this.visible = false; 79 | } 80 | 81 | handleContextActionClick( type: string ): void { 82 | if (!this.isDisabled) { 83 | this.clickEvent.emit({'type': type, 'selectedRange': this.selectedRange }); 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/js/constants.ts: -------------------------------------------------------------------------------- 1 | /** Note: The new constants in this file should be added to localization\xliff\constants\localizedConstants.enu.xlf so the localized texts get loaded here */ 2 | 3 | /** Results Pane Labels */ 4 | export let maximizeLabel = 'Maximize'; 5 | export let restoreLabel = 'Restore'; 6 | export let saveCSVLabel = 'Save as CSV'; 7 | export let saveJSONLabel = 'Save as JSON'; 8 | export let saveExcelLabel = 'Save as Excel'; 9 | export let resultPaneLabel = 'Results'; 10 | export let selectAll = 'Select all'; 11 | export let copyLabel = 'Copy'; 12 | export let copyWithHeadersLabel = 'Copy with Headers'; 13 | 14 | /** Messages Pane Labels */ 15 | export let executeQueryLabel = 'Executing query...'; 16 | export let messagePaneLabel = 'Messages'; 17 | export let lineSelectorFormatted = 'Line {0}'; 18 | export let elapsedTimeLabel = 'Total execution time: {0}'; 19 | 20 | /** Warning message for save icons */ 21 | export let msgCannotSaveMultipleSelections = 'Save results command cannot be used with multiple selections.'; 22 | 23 | export let loadLocalizedConstant = (key: string, value: string) => { 24 | // Update the value of the property with the name equal to key in this file 25 | this[key] = value; 26 | }; 27 | 28 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/js/directives/mousedown.directive.ts: -------------------------------------------------------------------------------- 1 | /* -------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | * ------------------------------------------------------------------------------------------ */ 5 | import { Directive, Output, EventEmitter, ElementRef, Inject, forwardRef } from '@angular/core'; 6 | // import { Observable } from 'rxjs/Rx'; 7 | 8 | @Directive({ 9 | selector: '[mousedown]' 10 | }) 11 | export class MouseDownDirective { 12 | @Output('mousedown') onMouseDown: EventEmitter = new EventEmitter(); 13 | 14 | constructor(@Inject(forwardRef(() => ElementRef)) private _el: ElementRef) { 15 | const self = this; 16 | setTimeout(() => { 17 | let $gridCanvas = $(this._el.nativeElement).find('.grid-canvas'); 18 | $gridCanvas.on('mousedown', () => { 19 | self.onMouseDown.emit(); 20 | }); 21 | let mouseDownFuncs: any[] = $._data($gridCanvas[0], 'events')['mousedown']; 22 | // reverse the event array so that our event fires first. 23 | mouseDownFuncs.reverse(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/js/directives/scroll.directive.ts: -------------------------------------------------------------------------------- 1 | /* -------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | * ------------------------------------------------------------------------------------------ */ 5 | import { Directive, Output, EventEmitter, ElementRef, Inject, forwardRef, Input } from '@angular/core'; 6 | import { Observable } from 'rxjs/Rx'; 7 | 8 | @Directive({ 9 | selector: '[onScroll]' 10 | }) 11 | export class ScrollDirective { 12 | @Input() scrollEnabled: boolean = true; 13 | @Output('onScroll') onScroll: EventEmitter = new EventEmitter(); 14 | 15 | constructor(@Inject(forwardRef(() => ElementRef)) private _el: ElementRef) { 16 | const self = this; 17 | Observable.fromEvent(this._el.nativeElement, 'scroll').subscribe((event) => { 18 | if (self.scrollEnabled) { 19 | self.onScroll.emit(self._el.nativeElement.scrollTop); 20 | } 21 | }); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/js/displayCodes.json: -------------------------------------------------------------------------------- 1 | { 2 | "mac": { 3 | "ctrl": "⌘", 4 | "alt": "⌥", 5 | "shift": "⇧" 6 | }, 7 | "windows": { 8 | "ctrl": "Ctrl", 9 | "alt": "Alt", 10 | "shift": "Shift" 11 | }, 12 | "linux": { 13 | "ctrl": "Ctrl", 14 | "alt": "Alt", 15 | "shift": "Shift" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/js/keycodes.json: -------------------------------------------------------------------------------- 1 | { 2 | "37": "left", 3 | "38": "up", 4 | "39": "right", 5 | "40": "down" 6 | } -------------------------------------------------------------------------------- /src/views/htmlcontent/src/js/main.ts: -------------------------------------------------------------------------------- 1 | /* -------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | * ------------------------------------------------------------------------------------------ */ 5 | /** 6 | * Bootstraps the angular module 7 | */ 8 | 9 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 10 | import { AppModule } from './app.module'; 11 | platformBrowserDynamic().bootstrapModule(AppModule); 12 | -------------------------------------------------------------------------------- /src/views/htmlcontent/src/js/utils.ts: -------------------------------------------------------------------------------- 1 | export function formatString(str: string, ...args: any[]): string { 2 | // This is based on code originally from https://github.com/Microsoft/vscode/blob/master/src/vs/nls.js 3 | // License: https://github.com/Microsoft/vscode/blob/master/LICENSE.txt 4 | let result: string; 5 | if (args.length === 0) { 6 | result = str; 7 | } else { 8 | result = str.replace(/\{(\d+)\}/g, (match, rest) => { 9 | let index = rest[0]; 10 | return typeof args[index] !== 'undefined' ? args[index] : match; 11 | }); 12 | } 13 | return result; 14 | } 15 | 16 | export function isNumber(val: any): boolean { 17 | return typeof(val) === 'number'; 18 | } 19 | 20 | /** 21 | * Converts <, >, &, ", ', and any characters that are outside \u00A0 to numeric HTML entity values 22 | * like { 23 | * (Adapted from http://stackoverflow.com/a/18750001) 24 | * @param str String to convert 25 | * @return String with characters replaced. 26 | */ 27 | export function htmlEntities(str: string): string { 28 | return typeof(str) === 'string' 29 | ? str.replace(/[\u00A0-\u9999<>\&"']/gim, (i) => { return `&#${i.charCodeAt(0)};`; }) 30 | : undefined; 31 | } 32 | 33 | /** 34 | * Determines if an object is a DbCellValue based on the properties it exposes 35 | * @param object The object to check 36 | * @returns True if the object is a DbCellValue, false otherwise 37 | */ 38 | export function isDbCellValue(object: any): boolean { 39 | return object !== undefined 40 | && object.displayValue !== undefined 41 | && object.isNull !== undefined; 42 | } 43 | -------------------------------------------------------------------------------- /src/views/htmlcontent/systemjs.config.extras.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Add barrels and stuff 3 | * Adjust as necessary for your application needs. 4 | */ 5 | // (function (global) { 6 | // System.config({ 7 | // packages: { 8 | // // add packages here 9 | // } 10 | // }); 11 | // })(this); 12 | -------------------------------------------------------------------------------- /src/views/htmlcontent/systemjs.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * System configuration for Angular 2 samples 3 | * Adjust as necessary for your application needs. 4 | */ 5 | (function(global) { 6 | var paths = { 7 | 'npm:': 'lib/js/' 8 | } 9 | // map tells the System loader where to look for things 10 | var map = { 11 | 'app': 'dist/js', // 'dist', 12 | '@angular': 'npm:@angular', 13 | 'rxjs': 'npm:rxjs', 14 | 'json': 'npm:json.js', 15 | 'angular2-slickgrid': 'npm:angular2-slickgrid', 16 | '@angular/common': 'npm:@angular/common/bundles/common.umd.js', 17 | '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js', 18 | '@angular/core': 'npm:@angular/core/bundles/core.umd.js', 19 | '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', 20 | '@angular/http': 'npm:@angular/http/bundles/http.umd.js', 21 | '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js', 22 | '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js', 23 | '@angular/router': 'npm:@angular/router/bundles/router.umd.js', 24 | '@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js', 25 | 'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js' 26 | }; 27 | // packages tells the System loader how to load when no filename and/or no extension 28 | var packages = { 29 | 'app': { main: 'main.js', defaultExtension: 'js' }, 30 | '': { main: 'constants.js', defaultExtension: 'js'}, 31 | 'angular2-slickgrid': { main: 'index.js', defaultExtension: 'js'} 32 | }; 33 | var meta = { 34 | '**/*.json' : { 35 | loader: 'json' 36 | } 37 | } 38 | var config = { 39 | paths: paths, 40 | map: map, 41 | packages: packages, 42 | meta: meta 43 | }; 44 | System.config(config); 45 | })(this); 46 | -------------------------------------------------------------------------------- /src/views/htmlcontent/test/contextmenu.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | import { ContextMenu } from './../src/js/components/contextmenu.component'; 3 | import { ShortcutService } from './../src/js/services/shortcuts.service'; 4 | 5 | class MockShortCutService { 6 | private keyToString = { 7 | 'event.saveAsCSV': 'ctrl+s', 8 | 'event.saveAsJSON': 'ctrl+shift+s', 9 | 'event.saveAsExcel': 'ctrl+shift+l', 10 | 'event.selectAll': 'ctrl+a', 11 | 'event.copySelection': 'ctrl+c', 12 | 'event.copyWithHeaders': 'ctrl+shift+c' 13 | }; 14 | public stringCodeFor(value: string): Promise { 15 | return Promise.resolve(this.keyToString[value]); 16 | } 17 | } 18 | 19 | describe('context Menu', () => { 20 | 21 | beforeEach(async(() => { 22 | TestBed.configureTestingModule({ 23 | declarations: [ ContextMenu ] 24 | }).overrideComponent(ContextMenu, { 25 | set: { 26 | providers: [ 27 | { 28 | provide: ShortcutService, 29 | useClass: MockShortCutService 30 | } 31 | ] 32 | } 33 | }); 34 | })); 35 | 36 | describe('initialization', () => { 37 | let fixture: ComponentFixture; 38 | let comp: ContextMenu; 39 | let ele: HTMLElement; 40 | 41 | beforeEach(() => { 42 | fixture = TestBed.createComponent(ContextMenu); 43 | fixture.detectChanges(); 44 | comp = fixture.componentInstance; 45 | ele = fixture.nativeElement; 46 | }); 47 | 48 | it('should be hidden', () => { 49 | expect(ele.firstElementChild.className.indexOf('hidden')).not.toEqual(-1); 50 | }); 51 | }); 52 | 53 | describe('basic behavior', () => { 54 | let fixture: ComponentFixture; 55 | let comp: ContextMenu; 56 | let ele: HTMLElement; 57 | 58 | beforeEach(() => { 59 | fixture = TestBed.createComponent(ContextMenu); 60 | fixture.detectChanges(); 61 | comp = fixture.componentInstance; 62 | ele = fixture.nativeElement; 63 | }); 64 | 65 | it('shows correctly', () => { 66 | comp.show(0, 0, 0, 0, 0, []); 67 | fixture.detectChanges(); 68 | expect(ele.firstElementChild.className.indexOf('hidden')).toEqual(-1); 69 | expect(ele.firstElementChild.childElementCount).toEqual(6, 'expect 6 menu items to be present'); 70 | }); 71 | 72 | it('hides correctly', () => { 73 | ele.click(); 74 | fixture.detectChanges(); 75 | expect(ele.firstElementChild.className.indexOf('hidden')).not.toEqual(-1); 76 | }); 77 | 78 | it('emits correct event', (done) => { 79 | comp.clickEvent.subscribe((result) => { 80 | expect(result.type).toEqual('savecsv'); 81 | expect(result.batchId).toEqual(0); 82 | expect(result.resultId).toEqual(0); 83 | expect(result.index).toEqual(0); 84 | expect(result.selection).toEqual([]); 85 | done(); 86 | }); 87 | comp.show(0, 0, 0, 0, 0, []); 88 | fixture.detectChanges(); 89 | let firstLi = ele.firstElementChild.firstElementChild; 90 | firstLi.click(); 91 | fixture.detectChanges(); 92 | }); 93 | }); 94 | 95 | }); 96 | -------------------------------------------------------------------------------- /src/views/htmlcontent/test/testResources/mockConfig1.spec.ts: -------------------------------------------------------------------------------- 1 | import { IResultsConfig } from './../../src/js/interfaces'; 2 | 3 | const config: IResultsConfig = { 4 | shortcuts: { 5 | 'event.toggleResultPane': 'ctrl+alt+r', 6 | 'event.toggleMessagePane': 'ctrl+alt+y', 7 | 'event.prevGrid': 'ctrl+up', 8 | 'event.nextGrid': 'ctrl+down', 9 | 'event.copySelection': 'ctrl+c', 10 | 'event.toggleMagnify': '', 11 | 'event.selectAll': 'a', 12 | 'event.saveAsJSON': 'ctrl+s', 13 | 'event.saveAsCSV': 'ctrl+alt+s', 14 | 'event.saveAsExcel': 'ctrl+alt+l' 15 | }, 16 | 'messagesDefaultOpen': true 17 | }; 18 | 19 | export default config; 20 | -------------------------------------------------------------------------------- /src/views/htmlcontent/test/testResources/mockGetRows1.spec.ts: -------------------------------------------------------------------------------- 1 | import { ResultSetSubset } from './../../src/js/interfaces'; 2 | 3 | const rows: ResultSetSubset = { 4 | rowCount: 50, 5 | rows: [ 6 | [{displayValue: 'data', isNull: false}] 7 | ] 8 | }; 9 | 10 | export default rows; 11 | -------------------------------------------------------------------------------- /src/views/htmlcontent/test/testResources/mockMessageBatchStart.spec.ts: -------------------------------------------------------------------------------- 1 | import { IMessage, WebSocketEvent } from './../../src/js/interfaces'; 2 | 3 | const message: WebSocketEvent = { 4 | type: 'message', 5 | data: { 6 | batchId: undefined, 7 | isError: false, 8 | link: { 9 | text: 'Line 2', 10 | uri: '/editorSelection?uri=123&startLine=1&endLine=2&startColumn=1&endColumn=3' 11 | }, 12 | message: 'Started query execution at ', 13 | time: '12:01:01 PM' 14 | } 15 | }; 16 | 17 | export default message; 18 | -------------------------------------------------------------------------------- /src/views/htmlcontent/test/testResources/mockMessageError.spec.ts: -------------------------------------------------------------------------------- 1 | import { IMessage, WebSocketEvent } from './../../src/js/interfaces'; 2 | 3 | const message: WebSocketEvent = { 4 | type: 'message', 5 | data: { 6 | batchId: undefined, // Should not be indented 7 | isError: true, // Should have error class 8 | link: undefined, // Should not have link 9 | message: 'Error occurred', 10 | time: '12:01:01' // Should be displayed b/c it does not have a batchId 11 | } 12 | }; 13 | 14 | export default message; 15 | -------------------------------------------------------------------------------- /src/views/htmlcontent/test/testResources/mockMessageResultSet.spec.ts: -------------------------------------------------------------------------------- 1 | import { IMessage, WebSocketEvent } from './../../src/js/interfaces'; 2 | 3 | const message: WebSocketEvent = { 4 | type: 'message', 5 | data: { 6 | batchId: 0, 7 | isError: false, 8 | link: undefined, 9 | message: '(123 Rows Affected)', 10 | time: '12:01:01' 11 | } 12 | }; 13 | 14 | export default message; 15 | -------------------------------------------------------------------------------- /src/views/htmlcontent/test/testResources/mockMessageSimple.spec.ts: -------------------------------------------------------------------------------- 1 | import { IMessage, WebSocketEvent } from './../../src/js/interfaces'; 2 | 3 | const message: WebSocketEvent = { 4 | type: 'message', 5 | data: { 6 | batchId: undefined, // Should not be indented 7 | isError: false, // Should not have error class 8 | link: undefined, // Should not have link 9 | message: '(123 Rows Affected)', 10 | time: '12:01:01' // Should be displayed b/c it does not have a batchId 11 | } 12 | }; 13 | 14 | export default message; 15 | -------------------------------------------------------------------------------- /src/views/htmlcontent/test/testUtils.ts: -------------------------------------------------------------------------------- 1 | export function triggerKeyEvent(key: number, ele: HTMLElement): void { 2 | let keyboardEvent = document.createEvent('KeyboardEvent'); 3 | let initMethod = typeof keyboardEvent.initKeyboardEvent !== 'undefined' ? 'initKeyboardEvent' : 'initKeyEvent'; 4 | 5 | keyboardEvent[initMethod]( 6 | 'keydown', // event type : keydown, keyup, keypress 7 | true, // bubbles 8 | true, // cancelable 9 | window, // viewArg: should be window 10 | false, // ctrlKeyArg 11 | false, // altKeyArg 12 | false, // shiftKeyArg 13 | false, // metaKeyArg 14 | key, // keyCodeArg : unsigned long the virtual key code, else 0 15 | 0 // charCodeArgs : unsigned long the Unicode character associated with the depressed key, else 0 16 | ); 17 | ele.dispatchEvent(keyboardEvent); 18 | } 19 | -------------------------------------------------------------------------------- /src/views/htmlcontent/test/utils.spec.ts: -------------------------------------------------------------------------------- 1 | import * as Utils from './../src/js/utils'; 2 | import { DbCellValue } from './../src/js/interfaces'; 3 | 4 | describe('Utility Tests', () => { 5 | describe('IsNumber', () => { 6 | it('Returns Correct Value', () => { 7 | expect(Utils.isNumber(0)).toBe(true); 8 | expect(Utils.isNumber(1)).toBe(true); 9 | expect(Utils.isNumber(false)).toBe(false); 10 | expect(Utils.isNumber(null)).toBe(false); // tslint:disable-line:no-null-keyword 11 | expect(Utils.isNumber(undefined)).toBe(false); 12 | }); 13 | }); 14 | 15 | describe('htmlEntities', () => { 16 | it('Encodes characters properly', () => { 17 | ['\u00A0', '\u1000', '\u8000', '\u9999', '\'', '"', '<', '>', '&'].forEach((item) => { 18 | let expectedValue = `&#${item.charCodeAt(0)};`; 19 | expect(Utils.htmlEntities(item)).toEqual(expectedValue); 20 | }); 21 | }); 22 | 23 | it('Does not encode characters outside the range', () => { 24 | ['a', 'A', '$', '0', ''].forEach((item) => { 25 | expect(Utils.htmlEntities(item)).toEqual(item); 26 | }); 27 | }); 28 | 29 | it('Does not attempt encoding if the value is null or undefined', () => { 30 | // We're explicitly checking null b/c this is what comes back from the service 31 | [null, undefined].forEach((item) => { // tslint:disable-line:no-null-keyword 32 | expect(Utils.htmlEntities(item)).toEqual(undefined); 33 | }); 34 | }); 35 | }); 36 | 37 | describe('isDbCellValue', () => { 38 | it('Detects undefined properly', () => { 39 | let dbCellValue = undefined; 40 | expect(Utils.isDbCellValue(dbCellValue)).toEqual(false); 41 | }); 42 | 43 | it('Detects a DbCellValue properly', () => { 44 | let dbCellValue: DbCellValue = {displayValue: 'qqq', isNull: false}; 45 | expect(Utils.isDbCellValue(dbCellValue)).toEqual(true); 46 | }); 47 | 48 | it('Detects a non-DbCellValue properly', () => { 49 | let nonDbCellValue: string = 'qqq'; 50 | expect(Utils.isDbCellValue(nonDbCellValue)).toEqual(false); 51 | }); 52 | }); 53 | }); 54 | -------------------------------------------------------------------------------- /src/views/htmlcontent/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "emitDecoratorMetadata": true, 4 | "experimentalDecorators": true, 5 | "module": "commonjs", 6 | "sourceMap": true, 7 | "rootDir": ".", 8 | "target": "ES6", 9 | "types": [] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/views/htmlcontent/tsd.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "v4", 3 | "repo": "borisyankov/DefinitelyTyped", 4 | "ref": "master", 5 | "path": "typings", 6 | "bundle": "typings/tsd.d.ts", 7 | "installed": { 8 | "jquery/jquery.d.ts": { 9 | "commit": "cd94d1e2dd95797ebfbdab1d0e8e4a419d5cfc92" 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/views/htmlcontent/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "align": [ 4 | true, 5 | "parameters", 6 | "statements" 7 | ], 8 | "ban": false, 9 | "class-name": true, 10 | "comment-format": [ 11 | true, 12 | "check-space" 13 | ], 14 | "curly": true, 15 | "eofline": true, 16 | "forin": true, 17 | "indent": [ 18 | true, 19 | "spaces" 20 | ], 21 | "interface-name": true, 22 | "jsdoc-format": true, 23 | "label-position": true, 24 | "label-undefined": true, 25 | "max-line-length": [ 26 | true, 27 | 160 28 | ], 29 | "member-access": false, 30 | "member-ordering": [ 31 | false, 32 | "static-before-instance", 33 | "variables-before-functions" 34 | ], 35 | "no-any": false, 36 | "no-arg": true, 37 | "no-bitwise": true, 38 | "no-conditional-assignment": true, 39 | "no-consecutive-blank-lines": false, 40 | "no-console": [ 41 | true, 42 | "debug", 43 | "info", 44 | "time", 45 | "timeEnd", 46 | "trace" 47 | ], 48 | "no-construct": true, 49 | "no-constructor-vars": false, 50 | "no-debugger": true, 51 | "no-duplicate-key": true, 52 | "no-duplicate-variable": true, 53 | "no-empty": true, 54 | "no-eval": true, 55 | "no-inferrable-types": false, 56 | "no-internal-module": true, 57 | "no-null-keyword": true, 58 | "no-require-imports": false, 59 | "no-shadowed-variable": true, 60 | "no-string-literal": false, 61 | "no-switch-case-fall-through": false, 62 | "no-trailing-whitespace": true, 63 | "no-unreachable": true, 64 | "no-unused-expression": false, 65 | "no-unused-variable": true, 66 | "no-use-before-declare": true, 67 | "no-var-keyword": true, 68 | "no-var-requires": false, 69 | "object-literal-sort-keys": false, 70 | "one-line": [ 71 | true, 72 | "check-open-brace", 73 | "check-catch", 74 | "check-else", 75 | "check-finally", 76 | "check-whitespace" 77 | ], 78 | "quotemark": [ 79 | true, 80 | "single", 81 | "avoid-escape" 82 | ], 83 | "radix": true, 84 | "semicolon": true, 85 | "switch-default": true, 86 | "trailing-comma": [ 87 | true, 88 | { 89 | "multiline": "never", 90 | "singleline": "never" 91 | } 92 | ], 93 | "triple-equals": [ 94 | true, 95 | "allow-null-check" 96 | ], 97 | "typedef": [ 98 | true, 99 | "call-signature", 100 | "property-declaration" 101 | ], 102 | "typedef-whitespace": [ 103 | true, 104 | { 105 | "call-signature": "nospace", 106 | "index-signature": "nospace", 107 | "parameter": "nospace", 108 | "property-declaration": "nospace", 109 | "variable-declaration": "nospace" 110 | } 111 | ], 112 | "use-strict": false, 113 | "variable-name": [ 114 | true, 115 | "allow-leading-underscore", 116 | "ban-keywords" 117 | ], 118 | "whitespace": [ 119 | true, 120 | "check-branch", 121 | "check-decl", 122 | "check-operator", 123 | "check-separator", 124 | "check-type" 125 | ] 126 | } 127 | } -------------------------------------------------------------------------------- /src/views/htmlcontent/typings/globals/jqueryui/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/ead8376ca80553332af7872f9fe723c6fbb4e412/jqueryui/index.d.ts", 5 | "raw": "registry:dt/jqueryui#1.11.0+20161214061125", 6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/ead8376ca80553332af7872f9fe723c6fbb4e412/jqueryui/index.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/views/htmlcontent/typings/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /src/views/htmlcontent/typings/jasmine/README.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | > `npm install --save @types/jasmine` 3 | 4 | # Summary 5 | This package contains type definitions for Jasmine 2.5 (http://jasmine.github.io/). 6 | 7 | # Details 8 | Files were exported from https://www.github.com/DefinitelyTyped/DefinitelyTyped/tree/types-2.0/jasmine 9 | 10 | Additional Details 11 | * Last updated: Tue, 01 Nov 2016 12:57:25 GMT 12 | * File structure: Global 13 | * Library Dependencies: none 14 | * Module Dependencies: none 15 | * Global values: afterAll, afterEach, beforeAll, beforeEach, describe, expect, fail, fdescribe, fit, it, jasmine, pending, runs, spyOn, waits, waitsFor, xdescribe, xit 16 | 17 | # Credits 18 | These definitions were written by Boris Yankov , Theodore Brown , David Pärsson . 19 | -------------------------------------------------------------------------------- /src/views/htmlcontent/typings/jasmine/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_args": [ 3 | [ 4 | { 5 | "raw": "@types/jasmine@^2.5.36", 6 | "scope": "@types", 7 | "escapedName": "@types%2fjasmine", 8 | "name": "@types/jasmine", 9 | "rawSpec": "^2.5.36", 10 | "spec": ">=2.5.36 <3.0.0", 11 | "type": "range" 12 | }, 13 | "/Users/anthonydresser/Documents/vscode-pgsql/src/views/htmlcontent" 14 | ] 15 | ], 16 | "_from": "@types/jasmine@>=2.5.36 <3.0.0", 17 | "_id": "@types/jasmine@2.5.37", 18 | "_inCache": true, 19 | "_installable": true, 20 | "_location": "/@types/jasmine", 21 | "_npmOperationalInternal": { 22 | "host": "packages-12-west.internal.npmjs.com", 23 | "tmp": "tmp/jasmine-2.5.37.tgz_1478005079042_0.7982070264406502" 24 | }, 25 | "_npmUser": { 26 | "name": "types", 27 | "email": "ts-npm-types@microsoft.com" 28 | }, 29 | "_phantomChildren": {}, 30 | "_requested": { 31 | "raw": "@types/jasmine@^2.5.36", 32 | "scope": "@types", 33 | "escapedName": "@types%2fjasmine", 34 | "name": "@types/jasmine", 35 | "rawSpec": "^2.5.36", 36 | "spec": ">=2.5.36 <3.0.0", 37 | "type": "range" 38 | }, 39 | "_requiredBy": [ 40 | "/" 41 | ], 42 | "_resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-2.5.37.tgz", 43 | "_shasum": "15f16040b1106941ec4aeefa3cd9c55342a0dcbb", 44 | "_shrinkwrap": null, 45 | "_spec": "@types/jasmine@^2.5.36", 46 | "_where": "/Users/anthonydresser/Documents/vscode-pgsql/src/views/htmlcontent", 47 | "author": { 48 | "name": "Boris Yankov", 49 | "email": "https://github.com/borisyankov/" 50 | }, 51 | "dependencies": {}, 52 | "description": "TypeScript definitions for Jasmine 2.5", 53 | "devDependencies": {}, 54 | "directories": {}, 55 | "dist": { 56 | "shasum": "15f16040b1106941ec4aeefa3cd9c55342a0dcbb", 57 | "tarball": "https://registry.npmjs.org/@types/jasmine/-/jasmine-2.5.37.tgz" 58 | }, 59 | "license": "MIT", 60 | "main": "", 61 | "maintainers": [ 62 | { 63 | "name": "types", 64 | "email": "ryan.cavanaugh@microsoft.com" 65 | } 66 | ], 67 | "name": "@types/jasmine", 68 | "optionalDependencies": {}, 69 | "peerDependencies": {}, 70 | "readme": "ERROR: No README data found!", 71 | "repository": { 72 | "type": "git", 73 | "url": "https://www.github.com/DefinitelyTyped/DefinitelyTyped.git" 74 | }, 75 | "scripts": {}, 76 | "typesPublisherContentHash": "342ad787ae1d9085f9cb2f352460449c601a7fbda833a19bb87aa2787dbc9ec3", 77 | "typings": "index.d.ts", 78 | "version": "2.5.37" 79 | } 80 | -------------------------------------------------------------------------------- /src/views/htmlcontent/typings/jasmine/types-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": "Boris Yankov , Theodore Brown , David Pärsson ", 3 | "definitionFilename": "index.d.ts", 4 | "libraryDependencies": [], 5 | "moduleDependencies": [], 6 | "libraryMajorVersion": "2", 7 | "libraryMinorVersion": "5", 8 | "libraryName": "Jasmine 2.5", 9 | "typingsPackageName": "jasmine", 10 | "projectName": "http://jasmine.github.io/", 11 | "sourceRepoURL": "https://www.github.com/DefinitelyTyped/DefinitelyTyped", 12 | "sourceBranch": "types-2.0", 13 | "kind": "Global", 14 | "globals": [ 15 | "afterAll", 16 | "afterEach", 17 | "beforeAll", 18 | "beforeEach", 19 | "describe", 20 | "expect", 21 | "fail", 22 | "fdescribe", 23 | "fit", 24 | "it", 25 | "jasmine", 26 | "pending", 27 | "runs", 28 | "spyOn", 29 | "waits", 30 | "waitsFor", 31 | "xdescribe", 32 | "xit" 33 | ], 34 | "declaredModules": [], 35 | "files": [ 36 | "index.d.ts" 37 | ], 38 | "hasPackageJson": false, 39 | "contentHash": "342ad787ae1d9085f9cb2f352460449c601a7fbda833a19bb87aa2787dbc9ec3" 40 | } -------------------------------------------------------------------------------- /src/views/htmlcontent/typings/tsd.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /syntaxes/sql.configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | } -------------------------------------------------------------------------------- /tasks/config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | 3 | var projectRoot = path.resolve(path.dirname(__dirname)); 4 | var srcRoot = path.resolve(projectRoot, 'src'); 5 | var viewsRoot = path.resolve(srcRoot, 'views'); 6 | var htmlcontentRoot = path.resolve(viewsRoot, 'htmlcontent'); 7 | var outRoot = path.resolve(projectRoot, 'out'); 8 | var htmloutroot = path.resolve(outRoot, 'src/views/htmlcontent'); 9 | var localization = path.resolve(projectRoot, 'localization'); 10 | 11 | var config = { 12 | paths: { 13 | project: { 14 | root: projectRoot, 15 | localization: localization 16 | }, 17 | extension: { 18 | root: srcRoot 19 | }, 20 | html: { 21 | root: htmlcontentRoot, 22 | out: htmloutroot 23 | } 24 | } 25 | } 26 | 27 | module.exports = config; -------------------------------------------------------------------------------- /tasks/covertasks.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var del = require('del'); 3 | var jeditor = require("gulp-json-editor"); 4 | var istanbulReport = require('gulp-istanbul-report'); 5 | var cproc = require('child_process'); 6 | 7 | gulp.task('cover:clean', function (done) { 8 | return del('coverage', done); 9 | }); 10 | 11 | gulp.task('cover:enableconfig',() => { 12 | return gulp.src("./coverconfig.json") 13 | .pipe(jeditor(function(json) { 14 | json.enabled = true; 15 | return json; // must return JSON object. 16 | })) 17 | .pipe(gulp.dest("./out", {'overwrite':true})); 18 | }); 19 | 20 | gulp.task('cover:enable', gulp.series('cover:clean', 'html:test', 'cover:enableconfig')); 21 | 22 | gulp.task('cover:disable', () => { 23 | return gulp.src("./coverconfig.json") 24 | .pipe(jeditor(function(json) { 25 | json.enabled = false; 26 | return json; // must return JSON object. 27 | })) 28 | .pipe(gulp.dest("./out", {'overwrite':true})); 29 | }); 30 | 31 | gulp.task('cover:combine', () => { 32 | return gulp.src(['./coverage/coverage-final.json', './coverage/coverage-html.json']) 33 | .pipe(istanbulReport({ 34 | reporterOpts: { 35 | dir: './coverage' 36 | }, 37 | reporters: [ 38 | {'name': 'lcovonly'}, // -> ./coverage/report.txt 39 | {'name': 'cobertura'} // -> ./jsonCov/cov.json 40 | ] 41 | })); 42 | }); 43 | 44 | // for running on the jenkins build system 45 | gulp.task('cover:jenkins', gulp.series('cover:clean', 'cover:enableconfig', 'html:test', 'ext:test', 'cover:combine')); -------------------------------------------------------------------------------- /tasks/packagetasks.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var fs = require('fs'); 3 | var gutil = require('gulp-util'); 4 | var cproc = require('child_process'); 5 | var os = require('os'); 6 | var del = require('del'); 7 | var path = require('path'); 8 | 9 | function installSqlToolsService(platform) { 10 | var install = require('../out/src/languageservice/serviceInstallerUtil'); 11 | return install.installService(platform); 12 | } 13 | 14 | gulp.task('ext:install-service', () => { 15 | return installSqlToolsService(); 16 | }); 17 | 18 | function doPackageSync(packageName) { 19 | var vsceArgs = []; 20 | vsceArgs.push('vsce'); 21 | vsceArgs.push('package'); // package command 22 | 23 | if (packageName !== undefined) { 24 | vsceArgs.push('-o'); 25 | vsceArgs.push(packageName); 26 | } 27 | var command = vsceArgs.join(' '); 28 | console.log(command); 29 | return cproc.execSync(command); 30 | } 31 | 32 | function cleanServiceInstallFolder() { 33 | var install = require('../out/src/languageservice/serviceInstallerUtil'); 34 | var serviceInstallFolder = install.getServiceInstallDirectoryRoot(); 35 | console.log('Deleting Service Install folder: ' + serviceInstallFolder); 36 | return del(serviceInstallFolder + '/*'); 37 | } 38 | 39 | function doOfflinePackage(runtimeId, platform, packageName) { 40 | return installSqlToolsService(platform).then(() => { 41 | return doPackageSync(packageName + '-' + runtimeId + '.vsix'); 42 | }); 43 | } 44 | 45 | //Install vsce to be able to run this task: npm install -g vsce 46 | gulp.task('package:online', () => { 47 | return cleanServiceInstallFolder().then(() => { 48 | doPackageSync(); 49 | return installSqlToolsService(); 50 | }); 51 | }); 52 | 53 | //Install vsce to be able to run this task: npm install -g vsce 54 | gulp.task('package:offline', () => { 55 | const platform = require('../out/src/models/platform'); 56 | const Runtime = platform.Runtime; 57 | var json = JSON.parse(fs.readFileSync('package.json')); 58 | var name = json.name; 59 | var version = json.version; 60 | var packageName = name + '-' + version; 61 | 62 | var packages = []; 63 | packages.push({rid: 'win7-x64', runtime: Runtime.Windows_7_64}); 64 | packages.push({rid: 'osx.10.11-x64', runtime: Runtime.OSX_10_11_64}); 65 | packages.push({rid: 'centos.7-x64', runtime: Runtime.CentOS_7}); 66 | packages.push({rid: 'debian.8-x64', runtime: Runtime.Debian_8}); 67 | packages.push({rid: 'fedora.23-x64', runtime: Runtime.Fedora_23}); 68 | packages.push({rid: 'opensuse.13.2-x64', runtime:Runtime.OpenSUSE_13_2}); 69 | packages.push({rid: 'rhel.7.2-x64', runtime: Runtime.RHEL_7}); 70 | packages.push({rid: 'ubuntu.14.04-x64', runtime: Runtime.Ubuntu_14}); 71 | packages.push({rid: 'ubuntu.16.04-x64', runtime: Runtime.Ubuntu_16}); 72 | 73 | var promise = Promise.resolve(); 74 | cleanServiceInstallFolder().then(() => { 75 | packages.forEach(data => { 76 | promise = promise.then(() => { 77 | return doOfflinePackage(data.rid, data.runtime, packageName).then(() => { 78 | return cleanServiceInstallFolder(); 79 | }); 80 | }); 81 | }); 82 | }); 83 | 84 | return promise; 85 | }); -------------------------------------------------------------------------------- /test/config.test.ts: -------------------------------------------------------------------------------- 1 | import assert = require('assert'); 2 | 3 | import Config from '../src/configurations/config'; 4 | import Telemetry from '../src/models/telemetry'; 5 | 6 | suite('Config Tests', () => { 7 | setup(() => { 8 | // Ensure that telemetry is disabled while testing 9 | Telemetry.disable(); 10 | }); 11 | 12 | test('getSqlToolsServiceDownloadUrl should return valid value', (done) => { 13 | return new Promise((resolve, reject) => { 14 | let config = new Config(); 15 | let serviceDownloawUrl = config.getSqlToolsServiceDownloadUrl; 16 | assert.notEqual(serviceDownloawUrl, undefined); 17 | done(); 18 | }); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /test/index.ts: -------------------------------------------------------------------------------- 1 | // 2 | // PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING 3 | // 4 | // This file is providing the test runner to use when running extension tests. 5 | // By default the test runner in use is Mocha based. 6 | // 7 | // You can provide your own test runner if you want to override it by exporting 8 | // a function run(testRoot: string, clb: (error:Error) => void) that the extension 9 | // host can call to run the tests. The test runner is expected to use console.log 10 | // to report the results back to the caller. When the tests are finished, return 11 | // a possible error to the callback or null if none. 12 | 13 | import * as IstanbulTestRunner from './istanbultestrunner'; 14 | 15 | let testRunner: any = IstanbulTestRunner; 16 | 17 | // You can directly control Mocha options by uncommenting the following lines 18 | // See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info 19 | testRunner.configure( 20 | // Mocha Options 21 | { 22 | ui: 'tdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.) 23 | reporter: 'pm-mocha-jenkins-reporter', 24 |     reporterOptions: { 25 |      junit_report_name: 'Extension Tests', 26 | junit_report_path: __dirname + '/../../test-reports/extension_tests.xml', 27 |         junit_report_stack: 1 28 |     }, 29 | useColors: true // colored output from test results 30 | }, 31 | // Coverage configuration options 32 | { 33 | coverConfig: '../coverconfig.json' 34 | }); 35 | 36 | module.exports = testRunner; 37 | -------------------------------------------------------------------------------- /test/initialization.test.ts: -------------------------------------------------------------------------------- 1 | import assert = require('assert'); 2 | import vscode = require('vscode'); 3 | 4 | import * as Extension from '../src/extension'; 5 | import ConnectionManager from '../src/controllers/connectionManager'; 6 | import MainController from '../src/controllers/mainController'; 7 | import Telemetry from '../src/models/telemetry'; 8 | 9 | function ensureExtensionIsActive(): Promise { 10 | return new Promise((resolve, reject) => { 11 | waitForExtensionToBeActive(resolve); 12 | }); 13 | } 14 | 15 | function waitForExtensionToBeActive(resolve): void { 16 | if (typeof(vscode.extensions.getExtension('Microsoft.vscode-pgsql')) === 'undefined' || 17 | !vscode.extensions.getExtension('Microsoft.vscode-pgsql').isActive) { 18 | setTimeout(waitForExtensionToBeActive.bind(this, resolve), 50); 19 | } else { 20 | resolve(); 21 | } 22 | } 23 | 24 | suite('Initialization Tests', () => { 25 | setup(() => { 26 | // Ensure that telemetry is disabled while testing 27 | Telemetry.disable(); 28 | }); 29 | 30 | test('Connection manager is initialized properly', function(done): void { // Note: this can't be an arrow function (=>), otherwise this.timeout() breaks 31 | this.timeout(10000); // Service installation usually takes a bit longer than the default 2000ms on a fresh install 32 | 33 | // Force the extension to activate by running one of our commands 34 | vscode.commands.executeCommand('extension.pgsql.connect'); 35 | 36 | // Wait for the extension to activate 37 | ensureExtensionIsActive().then(() => { 38 | // Verify that the connection manager was initialized properly 39 | let controller: MainController = Extension.getController(); 40 | let connectionManager: ConnectionManager = controller.connectionManager; 41 | assert.notStrictEqual(undefined, connectionManager.client); 42 | done(); 43 | }); 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /test/localization.test.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import * as LocalizedConstants from '../src/constants/localizedConstants'; 4 | import assert = require('assert'); 5 | 6 | suite('Localization Tests', () => { 7 | 8 | let resetLocalization = () => { 9 | LocalizedConstants.loadLocalizedConstants('en'); 10 | }; 11 | 12 | test('Default Localization Test' , done => { 13 | assert.equal(LocalizedConstants.testLocalizationConstant, 'test'); 14 | done(); 15 | }); 16 | 17 | test('EN Localization Test' , done => { 18 | LocalizedConstants.loadLocalizedConstants('en'); 19 | assert.equal(LocalizedConstants.testLocalizationConstant, 'test'); 20 | done(); 21 | }); 22 | 23 | test('ES Localization Test' , done => { 24 | LocalizedConstants.loadLocalizedConstants('es'); 25 | assert.equal(LocalizedConstants.testLocalizationConstant, 'test'); 26 | resetLocalization(); 27 | done(); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /test/resources/messages.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "messageText": "Command(s) completed successfully." 4 | }, 5 | { 6 | "messageText": "(5 row(s) affected)" 7 | } 8 | ] -------------------------------------------------------------------------------- /test/resources/results.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "columns":[ 4 | { 5 | "cell": "string", 6 | "label": "A", 7 | "name": "A" 8 | }, 9 | { 10 | "cell": "string", 11 | "label": "B", 12 | "name": "C" 13 | }, 14 | { 15 | "cell": "string", 16 | "label": "ROWID", 17 | "name": "ROWID" 18 | } 19 | ], 20 | "rows":[ 21 | { 22 | "A": "5", 23 | "B": "MELON", 24 | "ROWID": "F275635F-D02B-4550-AFD1-39282E8D4DC8" 25 | }, 26 | { 27 | "A": "1", 28 | "B": "APPLE", 29 | "ROWID": "6EC30A12-F6DD-4815-B9D8-833B41B141A6" 30 | }, 31 | { 32 | "A": "3", 33 | "B": "PEAR", 34 | "ROWID": "9A6F9DB2-FAC8-4C8B-9330-9B7485968745" 35 | }, 36 | { 37 | "A": "4", 38 | "B": "APPLE", 39 | "ROWID": "9C87D546-FAF5-405F-A069-A3E5CD2919E3" 40 | }, 41 | { 42 | "A": "2", 43 | "B": "APPLE", 44 | "ROWID": "77CB1B42-4AD7-408E-8881-C7E8E33E7295" 45 | } 46 | ] 47 | } 48 | ] -------------------------------------------------------------------------------- /test/resources/sqlTest.sql: -------------------------------------------------------------------------------- 1 | -- Select rows from a Table or View 'TableOrViewName' in schema 'SchemaName' 2 | GO 3 | SELECT * FROM DB2_ALIAS_NICK.A 4 | GO -------------------------------------------------------------------------------- /test/telemetry.test.ts: -------------------------------------------------------------------------------- 1 | import assert = require('assert'); 2 | import vscode = require('vscode'); 3 | import Telemetry from '../src/models/telemetry'; 4 | 5 | suite('Telemetry Tests', () => { 6 | test('Correct version of applicationInsights is installed', () => { 7 | // Find the path of our extension 8 | let ext = vscode.extensions.getExtension('Microsoft.vscode-pgsql'); 9 | 10 | // Open the applicationInsights node module package.json 11 | const appInsightsPackage: any = require( 12 | ext.extensionPath + '/node_modules/vscode-extension-telemetry/node_modules/applicationinsights/package.json' 13 | ); 14 | assert.ok(appInsightsPackage); 15 | 16 | // Verify that it is at least version 0.15.19 17 | const versionString: string = appInsightsPackage.version; 18 | assert.ok(versionString); 19 | const version: number[] = versionString.split('.').map(str => parseInt(str, 10)); 20 | assert.ok(version); 21 | 22 | let versionOk: boolean = false; 23 | if (version[0] >= 1 || // at least 1.x.x 24 | version[1] >= 16 || // at least 0.16.x 25 | version[2] >= 19) { // at least 0.15.19 26 | versionOk = true; 27 | } 28 | assert.ok(versionOk, 'Version of applicationInsights must be greater than or equal to 0.15.19. Detected version was ' + versionString); 29 | }); 30 | 31 | test('Path before /out/ is stripped', () => { 32 | let errorString = '/User/myuser/vscode/extensions/Microsoft.vscode-pgsql-0.0.1/out/src/controller/mainController.js:216.45'; 33 | let expectedErrorString = 'src/controller/mainController.js:216.45'; 34 | let actualErrorString = Telemetry.FilterErrorPath(errorString); 35 | assert.equal(actualErrorString, expectedErrorString); 36 | }); 37 | 38 | test('Path without /out/ is retained', () => { 39 | let errorString = '/User/should/never/happen/src/controller/mainController.js:216.45'; 40 | let actualErrorString = Telemetry.FilterErrorPath(errorString); 41 | assert.equal(actualErrorString, errorString); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /test/untitledSqlDocumentService.test.ts: -------------------------------------------------------------------------------- 1 | import * as TypeMoq from 'typemoq'; 2 | import vscode = require('vscode'); 3 | import UntitledSqlDocumentService from '../src/controllers/untitledSqlDocumentService'; 4 | import VscodeWrapper from '../src/controllers/vscodeWrapper'; 5 | 6 | interface IFixture { 7 | openDocResult: Promise; 8 | showDocResult: Promise; 9 | vscodeWrapper: TypeMoq.IMock; 10 | service: UntitledSqlDocumentService; 11 | textDocuments: vscode.TextDocument[]; 12 | } 13 | 14 | suite('UntitledSqlDocumentService Tests', () => { 15 | 16 | function createTextDocumentObject(fileName: string = ''): vscode.TextDocument { 17 | return { 18 | uri: undefined, 19 | eol: undefined, 20 | fileName: fileName, 21 | getText: undefined, 22 | getWordRangeAtPosition: undefined, 23 | isClosed: undefined, 24 | isDirty: true, 25 | isUntitled: true, 26 | languageId: 'sql', 27 | lineAt: undefined, 28 | lineCount: undefined, 29 | offsetAt: undefined, 30 | positionAt: undefined, 31 | save: undefined, 32 | validatePosition: undefined, 33 | validateRange: undefined, 34 | version: undefined 35 | }; 36 | } 37 | 38 | function createUntitledSqlDocumentService(fixture: IFixture): IFixture { 39 | let vscodeWrapper: TypeMoq.IMock; 40 | vscodeWrapper = TypeMoq.Mock.ofType(VscodeWrapper); 41 | 42 | vscodeWrapper.setup(x => x.textDocuments).returns(() => { return fixture.textDocuments; }); 43 | vscodeWrapper.setup(x => x.openPgSqlTextDocument()) 44 | .returns(() => { return Promise.resolve(createTextDocumentObject()); }); 45 | vscodeWrapper.setup(x => x.showTextDocument(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())) 46 | .returns(() => { return Promise.resolve(TypeMoq.It.isAny()); }); 47 | fixture.vscodeWrapper = vscodeWrapper; 48 | fixture.service = new UntitledSqlDocumentService(vscodeWrapper.object); 49 | return fixture; 50 | } 51 | 52 | test('newQuery should open a new untitled document and show in new tab' , () => { 53 | let fixture: IFixture = { 54 | openDocResult: Promise.resolve(createTextDocumentObject()), 55 | showDocResult: Promise.resolve(TypeMoq.It.isAny()), 56 | service: undefined, 57 | vscodeWrapper: undefined, 58 | textDocuments: [] 59 | }; 60 | fixture = createUntitledSqlDocumentService(fixture); 61 | 62 | return fixture.service.newQuery().then(result => { 63 | fixture.vscodeWrapper.verify(x => x.openPgSqlTextDocument(), TypeMoq.Times.once()); 64 | fixture.vscodeWrapper.verify(x => x.showTextDocument(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.once()); 65 | }); 66 | }); 67 | }); 68 | 69 | -------------------------------------------------------------------------------- /test/utils.test.ts: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import * as Utils from './../src/models/utils'; 3 | import Constants = require('../src/constants/constants'); 4 | import { ConnectionCredentials } from '../src/models/connectionCredentials'; 5 | 6 | suite('Utility Tests - parseTimeString', () => { 7 | test('should return false if nothing passed', () => { 8 | expect(Utils.parseTimeString(undefined)).to.equal(false); 9 | expect(Utils.parseTimeString('')).to.equal(false); 10 | }); 11 | 12 | test('should return false if input does not have only 1 period', () => { 13 | expect(Utils.parseTimeString('32:13:23.12.1')).to.equal(false); 14 | }); 15 | 16 | test('should return false if input does not have 2 :', () => { 17 | expect(Utils.parseTimeString('32.32')).to.equal(false); 18 | expect(Utils.parseTimeString('32:32:32:32.133')).to.equal(false); 19 | }); 20 | 21 | test('returns the correct value', () => { 22 | expect(Utils.parseTimeString('2:13:30.0')).to.equal(8010000); 23 | expect(Utils.parseTimeString('0:0:0.220')).to.equal(220); 24 | expect(Utils.parseTimeString('0:0:0.0')).to.equal(0); 25 | // Allow time without milliseconds 26 | expect(Utils.parseTimeString('2:13:30')).to.equal(8010000); 27 | }); 28 | }); 29 | 30 | suite('Utility Tests - parseNumAsTimeString', () => { 31 | test('returns the correct value', () => { 32 | expect(Utils.parseNumAsTimeString(8010000)).to.equal('02:13:30'); 33 | expect(Utils.parseNumAsTimeString(220)).to.equal('00:00:00.220'); 34 | expect(Utils.parseNumAsTimeString(0)).to.equal('00:00:00'); 35 | expect(Utils.parseNumAsTimeString(5002)).to.equal('00:00:05.002'); 36 | }); 37 | }); 38 | 39 | suite('Utility Tests - isSameConnection', () => { 40 | let server = 'my-server'; 41 | let database = 'my-db'; 42 | let authType = Constants.sqlAuthentication; 43 | let user = 'my-user'; 44 | let connection1 = Object.assign(new ConnectionCredentials(), { 45 | host: server, 46 | dbname: database, 47 | authenticationType: authType, 48 | user: user 49 | }); 50 | let connection2 = Object.assign(new ConnectionCredentials(), { 51 | host: server, 52 | dbname: database, 53 | authenticationType: authType, 54 | user: user 55 | }); 56 | let connectionString = 'Server=my-server;Database=my-db;Authentication=Sql Password;User ID=my-user'; 57 | let connection3 = Object.assign(new ConnectionCredentials(), { 58 | connectionString: connectionString 59 | }); 60 | let connection4 = Object.assign(new ConnectionCredentials(), { 61 | connectionString: connectionString 62 | }); 63 | 64 | test('should return true for matching non-connectionstring connections', () => { 65 | expect(Utils.isSameConnection(connection1, connection2)).to.equal(true); 66 | }); 67 | 68 | test('should return false for non-matching non-connectionstring connections', () => { 69 | connection2.host = 'some-other-server'; 70 | expect(Utils.isSameConnection(connection1, connection2)).to.equal(false); 71 | }); 72 | 73 | test('should return true for matching connectionstring connections', () => { 74 | expect(Utils.isSameConnection(connection3, connection4)).to.equal(true); 75 | }); 76 | 77 | test('should return false for non-matching connectionstring connections', () => { 78 | connection4.connectionString = 'Server=some-other-server'; 79 | expect(Utils.isSameConnection(connection3, connection4)).to.equal(false); 80 | }); 81 | 82 | test('should return false for connectionstring and non-connectionstring connections', () => { 83 | expect(Utils.isSameConnection(connection1, connection3)).to.equal(false); 84 | }); 85 | }); 86 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": true, 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "target": "ES6", 6 | "lib": [ "es6" ], 7 | "sourceMap": true, 8 | "emitDecoratorMetadata": true, 9 | "experimentalDecorators": true, 10 | "rootDir": ".", 11 | "typeRoots":["./typings"], 12 | "types": ["node"] 13 | }, 14 | "exclude": [ 15 | "node_modules", 16 | "src/views/htmlcontent" 17 | ] 18 | } -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "align": [ 4 | true, 5 | "parameters", 6 | "statements" 7 | ], 8 | "ban": false, 9 | "class-name": true, 10 | "comment-format": [ 11 | true, 12 | "check-space" 13 | ], 14 | "curly": true, 15 | "eofline": true, 16 | "forin": true, 17 | "indent": [ 18 | true, 19 | "spaces" 20 | ], 21 | "interface-name": true, 22 | "jsdoc-format": true, 23 | "label-position": true, 24 | "label-undefined": true, 25 | "max-line-length": [ 26 | true, 27 | 160 28 | ], 29 | "member-access": false, 30 | "member-ordering": [ 31 | false, 32 | "static-before-instance", 33 | "variables-before-functions" 34 | ], 35 | "no-any": false, 36 | "no-arg": true, 37 | "no-bitwise": true, 38 | "no-conditional-assignment": true, 39 | "no-consecutive-blank-lines": false, 40 | "no-console": [ 41 | true, 42 | "debug", 43 | "info", 44 | "time", 45 | "timeEnd", 46 | "trace" 47 | ], 48 | "no-construct": true, 49 | "no-constructor-vars": false, 50 | "no-debugger": true, 51 | "no-duplicate-key": true, 52 | "no-duplicate-variable": true, 53 | "no-empty": true, 54 | "no-eval": true, 55 | "no-inferrable-types": false, 56 | "no-internal-module": true, 57 | "no-null-keyword": true, 58 | "no-require-imports": false, 59 | "no-shadowed-variable": true, 60 | "no-string-literal": false, 61 | "no-switch-case-fall-through": false, 62 | "no-trailing-whitespace": true, 63 | "no-unreachable": true, 64 | "no-unused-expression": false, 65 | "no-unused-variable": true, 66 | "no-use-before-declare": true, 67 | "no-var-keyword": true, 68 | "no-var-requires": false, 69 | "object-literal-sort-keys": false, 70 | "one-line": [ 71 | true, 72 | "check-open-brace", 73 | "check-catch", 74 | "check-else", 75 | "check-finally", 76 | "check-whitespace" 77 | ], 78 | "quotemark": [ 79 | true, 80 | "single", 81 | "avoid-escape" 82 | ], 83 | "radix": true, 84 | "semicolon": true, 85 | "switch-default": true, 86 | "trailing-comma": [ 87 | true, 88 | { 89 | "multiline": "never", 90 | "singleline": "never" 91 | } 92 | ], 93 | "triple-equals": [ 94 | true, 95 | "allow-null-check" 96 | ], 97 | "typedef": [ 98 | true, 99 | "call-signature", 100 | "property-declaration" 101 | ], 102 | "typedef-whitespace": [ 103 | true, 104 | { 105 | "call-signature": "nospace", 106 | "index-signature": "nospace", 107 | "parameter": "nospace", 108 | "property-declaration": "nospace", 109 | "variable-declaration": "nospace" 110 | } 111 | ], 112 | "use-strict": false, 113 | "variable-name": [ 114 | true, 115 | "allow-leading-underscore", 116 | "ban-keywords" 117 | ], 118 | "whitespace": [ 119 | true, 120 | "check-branch", 121 | "check-decl", 122 | "check-operator", 123 | "check-separator", 124 | "check-type" 125 | ] 126 | } 127 | } -------------------------------------------------------------------------------- /typings/getmac.d.ts: -------------------------------------------------------------------------------- 1 | declare module "getmac" { 2 | export function getMac(callback: (err: Error, result: string) => void): void; 3 | } 4 | -------------------------------------------------------------------------------- /typings/globals/istanbul/index.d.ts: -------------------------------------------------------------------------------- 1 | // Generated by typings 2 | // Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/56295f5058cac7ae458540423c50ac2dcf9fc711/istanbul/istanbul.d.ts 3 | declare module 'istanbul' { 4 | namespace istanbul { 5 | interface Istanbul { 6 | new (options?: any): Istanbul; 7 | Collector: Collector; 8 | config: Config; 9 | ContentWriter: ContentWriter; 10 | FileWriter: FileWriter; 11 | hook: Hook; 12 | Instrumenter: Instrumenter; 13 | Report: Report; 14 | Reporter: Reporter; 15 | Store: Store; 16 | utils: ObjectUtils; 17 | VERSION: string; 18 | Writer: Writer; 19 | } 20 | 21 | interface Collector { 22 | new (options?: any): Collector; 23 | add(coverage: any, testName?: string): void; 24 | } 25 | 26 | interface Config { 27 | } 28 | 29 | interface ContentWriter { 30 | } 31 | 32 | interface FileWriter { 33 | } 34 | 35 | interface Hook { 36 | hookRequire(matcher: any, transformer: any, options: any): void; 37 | unhookRequire(): void; 38 | } 39 | 40 | interface Instrumenter { 41 | new (options?: any): Instrumenter; 42 | instrumentSync(code: string, filename: string): string; 43 | } 44 | 45 | interface Report { 46 | } 47 | 48 | interface Configuration { 49 | new (obj: any, overrides: any): Configuration; 50 | } 51 | 52 | interface Reporter { 53 | new (cfg?: Configuration, dir?: string): Reporter; 54 | add(fmt: string): void; 55 | addAll(fmts: Array): void; 56 | write(collector: Collector, sync: boolean, callback: Function): void; 57 | } 58 | 59 | interface Store { 60 | } 61 | 62 | interface ObjectUtils { 63 | } 64 | 65 | interface Writer { 66 | } 67 | } 68 | 69 | var istanbul: istanbul.Istanbul; 70 | 71 | export = istanbul; 72 | } 73 | -------------------------------------------------------------------------------- /typings/globals/istanbul/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/56295f5058cac7ae458540423c50ac2dcf9fc711/istanbul/istanbul.d.ts", 5 | "raw": "registry:dt/istanbul#0.4.0+20160316155526", 6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/56295f5058cac7ae458540423c50ac2dcf9fc711/istanbul/istanbul.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /typings/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /typings/tmp.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for tmp v0.0.28 2 | // Project: https://www.npmjs.com/package/tmp 3 | // Definitions by: Jared Klopper 4 | 5 | declare module "tmp" { 6 | 7 | module tmp { 8 | interface Options extends SimpleOptions { 9 | mode?: number; 10 | } 11 | 12 | interface SimpleOptions { 13 | prefix?: string; 14 | postfix?: string; 15 | template?: string; 16 | dir?: string; 17 | tries?: number; 18 | keep?: boolean; 19 | unsafeCleanup?: boolean; 20 | } 21 | 22 | interface SynchronousResult { 23 | name: string; 24 | fd: number; 25 | removeCallback: () => void; 26 | } 27 | 28 | function file(callback: (err: any, path: string, fd: number, cleanupCallback: () => void) => void): void; 29 | function file(config: Options, callback?: (err: any, path: string, fd: number, cleanupCallback: () => void) => void): void; 30 | 31 | function fileSync(config?: Options): SynchronousResult; 32 | 33 | function dir(callback: (err: any, path: string, cleanupCallback: () => void) => void): void; 34 | function dir(config: Options, callback?: (err: any, path: string, cleanupCallback: () => void) => void): void; 35 | 36 | function dirSync(config?: Options): SynchronousResult; 37 | 38 | function tmpName(callback: (err: any, path: string) => void): void; 39 | function tmpName(config: SimpleOptions, callback?: (err: any, path: string) => void): void; 40 | 41 | function tmpNameSync(config?: SimpleOptions): string; 42 | 43 | function setGracefulCleanup(): void; 44 | } 45 | 46 | export = tmp; 47 | } 48 | -------------------------------------------------------------------------------- /typings/vscode-extension-telemetry.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'vscode-extension-telemetry' { 2 | export default class TelemetryReporter { 3 | constructor(extensionId: string,extensionVersion: string, key: string); 4 | sendTelemetryEvent(eventName: string, properties?: { [key: string]: string }, measures?: { [key: string]: number }): void; 5 | } 6 | } 7 | --------------------------------------------------------------------------------