├── .all-contributorsrc ├── .editorconfig ├── .gitattributes ├── .gitignore ├── .travis.yml ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── .vscodeignore ├── LICENSE ├── README.md ├── images ├── icon.svg ├── icon_16.bmp ├── icon_200.png └── icon_32.png ├── jsconfig.json ├── package.json ├── screenshots ├── context-menu-old.png ├── context-menu.png ├── copy.png ├── install.png ├── open-in-github.png └── pull-req-cmd.png ├── src ├── extension.js └── gitProvider.js ├── test ├── extension.test.js ├── gitProvider.test.js ├── index.js └── sampleTestData │ ├── git │ ├── COMMIT_EDITMSG │ ├── FETCH_HEAD │ ├── HEAD │ ├── ORIG_HEAD │ ├── config │ ├── description │ ├── hooks │ │ ├── applypatch-msg.sample │ │ ├── commit-msg.sample │ │ ├── post-update.sample │ │ ├── pre-applypatch.sample │ │ ├── pre-commit.sample │ │ ├── pre-push.sample │ │ ├── pre-rebase.sample │ │ ├── prepare-commit-msg.sample │ │ └── update.sample │ ├── index │ ├── info │ │ └── exclude │ ├── logs │ │ ├── HEAD │ │ └── refs │ │ │ └── heads │ │ │ ├── master │ │ │ └── testBranch │ ├── objects │ │ ├── 32 │ │ │ └── bd28a61810faf925d58b96aa0c32946b76c271 │ │ ├── 72 │ │ │ └── 4b5664b66d8d8cc8d859accca1050abc7650a2 │ │ ├── 4b │ │ │ └── 825dc642cb6eb9a060e54bf8d69288fbee4904 │ │ ├── a8 │ │ │ └── a663582e191d2572dc5132ad8b971de9acc548 │ │ ├── a9 │ │ │ └── b854f5131a863ad47d3b6c6bbca8cd17a8aff3 │ │ ├── ea │ │ │ └── 5a519e3d2b5bae1075642c436b1eba917d31d8 │ │ └── fd │ │ │ └── d74783a03fa7c83242da104c53221e2982f1b2 │ └── refs │ │ └── heads │ │ ├── master │ │ └── testBranch │ └── sampleDirectory │ └── sampleTestFile.txt ├── testScript.js ├── tsconfig.json ├── typings ├── tsd.d.ts └── vscode-typings.d.ts └── yarn.lock /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "projectName": "vscode-open-in-github", 3 | "projectOwner": "ziyasal", 4 | "files": [ 5 | "README.md" 6 | ], 7 | "imageSize": 75, 8 | "commit": true, 9 | "contributors": [ 10 | { 11 | "login": "bradyholt", 12 | "name": "Brady Holt", 13 | "avatar_url": "https://avatars0.githubusercontent.com/u/759811?v=4", 14 | "profile": "https://www.geekytidbits.com", 15 | "contributions": [ 16 | "code", 17 | "doc", 18 | "test" 19 | ] 20 | }, 21 | { 22 | "login": "gdziadkiewicz", 23 | "name": "Grzegorz Dziadkiewicz", 24 | "avatar_url": "https://avatars3.githubusercontent.com/u/8547855?v=4", 25 | "profile": "https://github.com/gdziadkiewicz", 26 | "contributions": [ 27 | "code", 28 | "doc", 29 | "test" 30 | ] 31 | }, 32 | { 33 | "login": "itiut", 34 | "name": "Yuichi Tanikawa", 35 | "avatar_url": "https://avatars3.githubusercontent.com/u/1145226?v=4", 36 | "profile": "http://itiut.hatenablog.com/", 37 | "contributions": [ 38 | "code", 39 | "doc", 40 | "test" 41 | ] 42 | }, 43 | { 44 | "login": "suan", 45 | "name": "Suan Yeo", 46 | "avatar_url": "https://avatars2.githubusercontent.com/u/192727?v=4", 47 | "profile": "http://suanaikyeo.com", 48 | "contributions": [ 49 | "code" 50 | ] 51 | }, 52 | { 53 | "login": "bpasero", 54 | "name": "Benjamin Pasero", 55 | "avatar_url": "https://avatars3.githubusercontent.com/u/900690?v=4", 56 | "profile": "http://code.visualstudio.com", 57 | "contributions": [ 58 | "code" 59 | ] 60 | }, 61 | { 62 | "login": "stuartleeks", 63 | "name": "Stuart Leeks", 64 | "avatar_url": "https://avatars1.githubusercontent.com/u/1824461?v=4", 65 | "profile": "http://blogs.msdn.com/stuartleeks", 66 | "contributions": [ 67 | "code" 68 | ] 69 | }, 70 | { 71 | "login": "marvinhagemeister", 72 | "name": "Marvin Hagemeister", 73 | "avatar_url": "https://avatars2.githubusercontent.com/u/1062408?v=4", 74 | "profile": "https://marvinhagemeister.github.io", 75 | "contributions": [ 76 | "code" 77 | ] 78 | }, 79 | { 80 | "login": "linarnan", 81 | "name": "linarnan", 82 | "avatar_url": "https://avatars2.githubusercontent.com/u/649067?v=4", 83 | "profile": "https://github.com/linarnan", 84 | "contributions": [ 85 | "code", 86 | "test" 87 | ] 88 | }, 89 | { 90 | "login": "danseethaler", 91 | "name": "Dan Seethaler", 92 | "avatar_url": "https://avatars1.githubusercontent.com/u/11202705?v=4", 93 | "profile": "https://github.com/danseethaler", 94 | "contributions": [ 95 | "code", 96 | "test" 97 | ] 98 | }, 99 | { 100 | "login": "johnpaularthur", 101 | "name": "John Arthur", 102 | "avatar_url": "https://avatars1.githubusercontent.com/u/7483101?v=4", 103 | "profile": "https://github.com/johnpaularthur", 104 | "contributions": [ 105 | "code" 106 | ] 107 | }, 108 | { 109 | "login": "ziluvatar", 110 | "name": "Eduardo Diaz", 111 | "avatar_url": "https://avatars2.githubusercontent.com/u/1424663?v=4", 112 | "profile": "https://github.com/ziluvatar", 113 | "contributions": [ 114 | "code" 115 | ] 116 | }, 117 | { 118 | "login": "testerez", 119 | "name": "Tom Esterez", 120 | "avatar_url": "https://avatars3.githubusercontent.com/u/815236?v=4", 121 | "profile": "https://github.com/testerez", 122 | "contributions": [ 123 | "code" 124 | ] 125 | }, 126 | { 127 | "login": "antxxxx", 128 | "name": "Anthony Brown", 129 | "avatar_url": "https://avatars2.githubusercontent.com/u/2149559?v=4", 130 | "profile": "https://github.com/antxxxx", 131 | "contributions": [ 132 | "code" 133 | ] 134 | } 135 | ] 136 | } 137 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | end_of_line = lf 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | 10 | [{*.json,*.yml}] 11 | indent_style = space 12 | indent_size = 2 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | node_modules 3 | .vscode-test 4 | .vscode 5 | *.log 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: true 2 | language: node_js 3 | node_js: "11" 4 | 5 | os: 6 | - osx 7 | - linux 8 | 9 | before_install: 10 | - if [ $TRAVIS_OS_NAME == "linux" ]; then 11 | export CXX="g++-4.9" CC="gcc-4.9" DISPLAY=:99.0; 12 | sh -e /etc/init.d/xvfb start; 13 | sleep 3; 14 | sudo apt-get install xclip; 15 | fi 16 | 17 | install: 18 | - npm install 19 | - npm run vscode:prepublish 20 | 21 | script: 22 | - npm run test:linuxOSX 23 | -------------------------------------------------------------------------------- /.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 | "name": "Launch Extension", 7 | "type": "extensionHost", 8 | "request": "launch", 9 | "runtimeExecutable": "${execPath}", 10 | "args": [ 11 | "--extensionDevelopmentPath=${workspaceRoot}" 12 | ], 13 | "stopOnEntry": false, 14 | "sourceMaps": true, 15 | "outFiles": ["${workspaceRoot}/src"], 16 | "preLaunchTask": "npm" 17 | }, 18 | { 19 | "name": "Launch Tests", 20 | "type": "extensionHost", 21 | "request": "launch", 22 | "runtimeExecutable": "${execPath}", 23 | "args": [ 24 | "--disable-extensions", 25 | "--extensionDevelopmentPath=${workspaceRoot}", 26 | "--extensionTestsPath=${workspaceRoot}/test", 27 | "${workspaceRoot}/test/sampleTestData" 28 | ], 29 | "stopOnEntry": false, 30 | "sourceMaps": true, 31 | "outFiles": ["${workspaceRoot}/src"], 32 | "preLaunchTask": "npm" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "out": false // set this to true to hide the "out" folder with the compiled JS files 5 | }, 6 | "search.exclude": { 7 | "out": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // Available variables which can be used inside of strings. 2 | // ${workspaceRoot}: the root folder of the team 3 | // ${file}: the current opened file 4 | // ${fileBasename}: the current opened file's basename 5 | // ${fileDirname}: the current opened file's dirname 6 | // ${fileExtname}: the current opened file's extension 7 | // ${cwd}: the current working directory of the spawned process 8 | 9 | // A task runner that calls a custom npm script that compiles the extension. 10 | { 11 | "version": "0.1.0", 12 | 13 | // we want to run npm 14 | "command": "npm", 15 | 16 | // the command is a shell script 17 | "isShellCommand": true, 18 | 19 | // show the output window only if unrecognized errors occur. 20 | "showOutput": "silent", 21 | 22 | // we run the custom script "compile" as defined in package.json 23 | "args": ["run", "compile"], 24 | 25 | // The tsc compiler is started in watching mode 26 | "isWatching": true, 27 | 28 | // use the standard tsc in watch mode problem matcher to find compile problems in the output. 29 | "problemMatcher": "$tsc-watch" 30 | } -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | typings/** 4 | screenshots/** 5 | **/*.ts 6 | **/*.map 7 | .gitignore 8 | tsconfig.json 9 | out/test/** 10 | test/** -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Ziya SARIKAYA 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![vscode-open-in-github](images/icon_200.png?raw=true "Open in GitHub / GitLab / Gitea / Bitbucket / visualstudio.com") 2 | 3 | **Supports :** GitHub, GitLab, Gitea, Bitbucket, and Visualstudio.com. 4 | 5 | > Extension for Visual Studio Code which can be used to jump to a source code line in GitHub, GitLab, Gitea, Bitbucket and Visualstudio.com 6 | 7 | [![Build Status](https://travis-ci.org/ziyasal/vscode-open-in-github.svg?branch=master)](https://travis-ci.org/ziyasal/vscode-open-in-github) [![All Contributors](https://img.shields.io/badge/all_contributors-13-orange.svg?style=flat-square)](#contributors) 8 | 9 | ## Install 10 | 11 | **Tested with VsCode 0.10.1** 12 | 13 | Press F1 and narrow down the list commands by typing `extension`. Pick `Extensions: Install Extension`. 14 | 15 | ![installation](screenshots/install.png?raw=true "installation") 16 | 17 | Simply pick the `Open in GitHub / Bitbucket` extension from the list 18 | 19 | ## Install Manual 20 | 21 | ### Mac & Linux 22 | 23 | ```sh 24 | cd $HOME/.vscode/extensions 25 | git clone https://github.com/ziyasal/vscode-open-in-github.git 26 | cd vscode-open-in-github 27 | npm install 28 | ``` 29 | 30 | ### Windows 31 | 32 | ```sh 33 | cd %USERPROFILE%\.vscode\extensions 34 | git clone https://github.com/ziyasal/vscode-open-in-github.git 35 | cd vscode-open-in-github 36 | npm install 37 | ``` 38 | 39 | ## Usage 40 | 41 | ### Command 42 | 43 | Press F1 and type `Open in GitHub`. 44 | 45 | ![open](screenshots/open-in-github.png?raw=true "Open function") 46 | 47 | Press F1 and type `Copy GitHub link to clipboard`. 48 | 49 | ![copy](screenshots/copy.png?raw=true "Copy function") 50 | 51 | (The URL for GitHub will also include line ranges if there are lines selected in the editor) 52 | 53 | Press F1 and type `Open Pull Request`. 54 | 55 | ![copy](screenshots/pull-req-cmd.png?raw=true "Copy function") 56 | 57 | ### Keybord Shortcut 58 | 59 | Press Ctrl+L G to activate. 60 | Press Ctrl+L C to copy active line link to clipboard. 61 | 62 | ### Context menu 63 | 64 | Right click on explorer item and choose `Open in GitHub` or `Copy GitHub link to clipboard`. 65 | 66 | ![context](screenshots/context-menu.png?raw=true "Context menu options") 67 | 68 | ### Configure custom github domain 69 | 70 | Add following line into workspace settings; 71 | 72 | ```js 73 | { 74 | "openInGitHub.gitHubDomain": "your custom github domain here", 75 | "openInGitHub.requireSelectionForLines": false, // If enabled, the copied or opened URL won't include line number(s) unless there's an active selection 76 | "openInGitHub.useCommitSHAInURL": false, 77 | "openInGitHub.providerType": "gitlab", // github, gitlab, gitea, bitbucket, ... 78 | "openInGitHub.providerProtocol": "https" // https, http. Useful for custom domains that don't support https. Defaults to https. 79 | } 80 | ``` 81 | 82 | Custom Settings 83 | 84 | ```js 85 | { 86 | "openInGitHub.providerType": "custom", // important, otherwise the following settings will not be read 87 | "openInGitHub.customProviderPath": "https://your-git-repo-hosting-domain:port/path-to-the-repo", 88 | "openInGitHub.customBlobPath": "+", // for example, this is `blob` in gitlab 89 | "openInGitHub.customLinePrefix": "#", // for example, this is `#L12` instead of just `#12` in most git hosting service 90 | "openInGitHub.defaultPullRequestBranch": "master", // for example, this could be `development` 91 | // optional 92 | "openInGitHub.alwaysOpenInDefaultBranch": true // if you always work on your local branch, and checking it online will always get 404 93 | } 94 | ``` 95 | 96 | Have fun.. 97 | 98 | ## Debug Travis CI locally 99 | 100 | ```bash 101 | cd $your_vscode_open_in_github_local_directory_path 102 | 103 | BUILD_ID="build-$RANDOM" && \ 104 | LATEST_GARNET_TAG_ID="1515445631-7dfb2e1" && \ 105 | MAPPED_DOCKER_PATH=/home/travis/vscode-open-in-github && \ 106 | docker run \ 107 | -name $BUILD_ID 108 | -v $(pwd):$MAPPED_DOCKER_PATH \ 109 | -dit "travisci/ci-garnet:packer-$LATEST_GARNET_TAG_ID" /sbin/init && \ 110 | docker exec -it $BUILDID bash -l 111 | # to rerun last command: look for the last container with docker ps 112 | 113 | su - travis # to use nvm and npm 114 | 115 | cd /vscode-open-in-github 116 | 117 | # replicate steps in either A) .travis.yml B) worker log in Travis CI 118 | ``` 119 | 120 | Reference: [Stackoverflow](https://stackoverflow.com/questions/21053657/how-to-run-travis-ci-locally) 121 | 122 | ## Known Limitations 123 | - Extension doesn't currently works with Git worktrees 124 | 125 | ## Contributors 126 | 127 | Thanks goes to these wonderful people ([emoji key](https://github.com/kentcdodds/all-contributors#emoji-key)): 128 | 129 | 130 | | [
Brady Holt](https://www.geekytidbits.com)
[💻](https://github.com/ziyasal/vscode-open-in-github/commits?author=bradymholt "Code") [📖](https://github.com/ziyasal/vscode-open-in-github/commits?author=bradymholt "Documentation") [⚠️](https://github.com/ziyasal/vscode-open-in-github/commits?author=bradymholt "Tests") | [
Grzegorz Dziadkiewicz](https://github.com/gdziadkiewicz)
[💻](https://github.com/ziyasal/vscode-open-in-github/commits?author=gdziadkiewicz "Code") [📖](https://github.com/ziyasal/vscode-open-in-github/commits?author=gdziadkiewicz "Documentation") [⚠️](https://github.com/ziyasal/vscode-open-in-github/commits?author=gdziadkiewicz "Tests") | [
Yuichi Tanikawa](http://itiut.hatenablog.com/)
[💻](https://github.com/ziyasal/vscode-open-in-github/commits?author=itiut "Code") [📖](https://github.com/ziyasal/vscode-open-in-github/commits?author=itiut "Documentation") [⚠️](https://github.com/ziyasal/vscode-open-in-github/commits?author=itiut "Tests") | [
Suan Yeo](http://suanaikyeo.com)
[💻](https://github.com/ziyasal/vscode-open-in-github/commits?author=suan "Code") | [
Benjamin Pasero](http://code.visualstudio.com)
[💻](https://github.com/ziyasal/vscode-open-in-github/commits?author=bpasero "Code") | [
Stuart Leeks](http://blogs.msdn.com/stuartleeks)
[💻](https://github.com/ziyasal/vscode-open-in-github/commits?author=stuartleeks "Code") | [
Marvin Hagemeister](https://marvinhagemeister.github.io)
[💻](https://github.com/ziyasal/vscode-open-in-github/commits?author=marvinhagemeister "Code") | 131 | | :---: | :---: | :---: | :---: | :---: | :---: | :---: | 132 | | [
linarnan](https://github.com/linarnan)
[💻](https://github.com/ziyasal/vscode-open-in-github/commits?author=linarnan "Code") [⚠️](https://github.com/ziyasal/vscode-open-in-github/commits?author=linarnan "Tests") | [
Dan Seethaler](https://github.com/danseethaler)
[💻](https://github.com/ziyasal/vscode-open-in-github/commits?author=danseethaler "Code") [⚠️](https://github.com/ziyasal/vscode-open-in-github/commits?author=danseethaler "Tests") | [
John Arthur](https://github.com/johnpaularthur)
[💻](https://github.com/ziyasal/vscode-open-in-github/commits?author=johnpaularthur "Code") | [
Eduardo Diaz](https://github.com/ziluvatar)
[💻](https://github.com/ziyasal/vscode-open-in-github/commits?author=ziluvatar "Code") | [
Tom Esterez](https://github.com/testerez)
[💻](https://github.com/ziyasal/vscode-open-in-github/commits?author=testerez "Code") | [
Anthony Brown](https://github.com/antxxxx)
[💻](https://github.com/ziyasal/vscode-open-in-github/commits?author=antxxxx "Code") | 133 | 134 | 135 | This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome! 136 | 137 | 138 | ## License 139 | 140 | MIT © [Ziya SARIKAYA @ziyasal](https://github.com/ziyasal) & Contributors 141 | -------------------------------------------------------------------------------- /images/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /images/icon_16.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugthesystem/vscode-open-in-github/b9f69fe06c3541d12f0f6d07f852733aa4c0d5e4/images/icon_16.bmp -------------------------------------------------------------------------------- /images/icon_200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugthesystem/vscode-open-in-github/b9f69fe06c3541d12f0f6d07f852733aa4c0d5e4/images/icon_200.png -------------------------------------------------------------------------------- /images/icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugthesystem/vscode-open-in-github/b9f69fe06c3541d12f0f6d07f852733aa4c0d5e4/images/icon_32.png -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES6", 4 | "module": "commonjs" 5 | } 6 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vscode-open-in-github", 3 | "displayName": "Open in GitHub, GitLab, Gitea, Bitbucket, VisualStudio.com !", 4 | "description": "Jump to a source code line in GitHub, GitLab, Gitea, Bitbucket, VisualStudio.com !", 5 | "icon": "images/icon_200.png", 6 | "version": "1.4.1", 7 | "publisher": "ziyasal", 8 | "license": "SEE LICENSE IN LICENSE.md", 9 | "galleryBanner": { 10 | "color": "#E9EBED", 11 | "theme": "light" 12 | }, 13 | "homepage": "https://github.com/ziyasal/vscode-open-in-github/blob/master/README.md", 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/ziyasal/vscode-open-in-github.git" 17 | }, 18 | "bugs": { 19 | "url": "https://github.com/ziyasal/vscode-open-in-github/issues" 20 | }, 21 | "categories": [ 22 | "Other" 23 | ], 24 | "engines": { 25 | "vscode": "^1.30.x" 26 | }, 27 | "activationEvents": [ 28 | "onCommand:extension.openInGitHub", 29 | "onCommand:extension.copyGitHubLinkToClipboard", 30 | "onCommand:extension.openPrGitProvider" 31 | ], 32 | "main": "./src/extension", 33 | "contributes": { 34 | "commands": [ 35 | { 36 | "command": "extension.openInGitHub", 37 | "title": "Open in GitHub" 38 | }, 39 | { 40 | "command": "extension.copyGitHubLinkToClipboard", 41 | "title": "Copy GitHub link to clipboard" 42 | }, 43 | { 44 | "command": "extension.openPrGitProvider", 45 | "title": "Open Pull Request" 46 | } 47 | ], 48 | "configuration": { 49 | "type": "object", 50 | "title": "Open in GitHub extension configuration", 51 | "properties": { 52 | "openInGitHub.gitHubDomain": { 53 | "type": [ 54 | "string" 55 | ], 56 | "default": "github.com", 57 | "description": "Configure a custom GitHub domain. Useful for GitHub Enterprise" 58 | }, 59 | "openInGitHub.giteaDomain": { 60 | "type": [ 61 | "string" 62 | ], 63 | "default": "gitea.io", 64 | "description": "Configure a custom Gitea domain" 65 | }, 66 | "openInGitHub.requireSelectionForLines": { 67 | "type": "boolean", 68 | "default": false, 69 | "description": "If enabled, the copied or opened URL won't include line number(s) unless there's an active selection" 70 | }, 71 | "openInGitHub.useCommitSHAInURL": { 72 | "type": "boolean", 73 | "default": false, 74 | "description": "If enabled, use commit SHA instead of branch" 75 | }, 76 | "openInGitHub.providerType": { 77 | "type": "string", 78 | "default": "unknown", 79 | "enum": [ 80 | "github", 81 | "gitlab", 82 | "gitea", 83 | "bitbucket", 84 | "visualstudio.com", 85 | "custom" 86 | ], 87 | "description": "Specify the provider type in Custom Site" 88 | }, 89 | "openInGitHub.providerProtocol": { 90 | "type": "string", 91 | "default": "https", 92 | "enum": [ 93 | "https", 94 | "http" 95 | ], 96 | "description": "Specify the provider protocol for custom sites or GitHub Enterprise" 97 | }, 98 | "openInGitHub.alwaysOpenInDefaultBranch": { 99 | "type": "boolean", 100 | "default": false, 101 | "description": "If enabled, web url will always point to default branch instead of local commit SHA or local branch" 102 | }, 103 | "openInGitHub.customProviderPath": { 104 | "type": "string", 105 | "default": "https://git-repo-domain:git-path/custom-path/", 106 | "description": "Configure a custom path to the git repo your project is hosted" 107 | }, 108 | "openInGitHub.customBlobPath": { 109 | "type": "string", 110 | "default": "+", 111 | "description": "Configure a custom blob path to connect git path and file path" 112 | }, 113 | "openInGitHub.customLinePrefix": { 114 | "type": "string", 115 | "default": "#", 116 | "description": "Configure a custom line number prefix" 117 | }, 118 | "openInGitHub.defaultPullRequestBranch": { 119 | "type": "string", 120 | "default": "integration", 121 | "description": "Specify the default destination branch for pull requests" 122 | } 123 | } 124 | }, 125 | "keybindings": [ 126 | { 127 | "command": "extension.openInGitHub", 128 | "key": "ctrl+l g", 129 | "mac": "ctrl+l g" 130 | }, 131 | { 132 | "command": "extension.copyGitHubLinkToClipboard", 133 | "key": "ctrl+l c", 134 | "mac": "ctrl+l c" 135 | }, 136 | { 137 | "command": "extension.openPrGitProvider", 138 | "key": "ctrl+l p", 139 | "mac": "ctrl+l p" 140 | } 141 | ], 142 | "menus": { 143 | "editor/context": [ 144 | { 145 | "command": "extension.openInGitHub" 146 | } 147 | ], 148 | "explorer/context": [ 149 | { 150 | "command": "extension.openInGitHub" 151 | }, 152 | { 153 | "command": "extension.copyGitHubLinkToClipboard" 154 | }, 155 | { 156 | "command": "extension.openPrGitProvider" 157 | } 158 | ] 159 | } 160 | }, 161 | "scripts": { 162 | "vscode:prepublish": "tsc -p ./", 163 | "compile": "tsc -watch -p ./", 164 | "test:linuxOSX": "CODE_TESTS_WORKSPACE=$(pwd)/test/sampleTestData CODE_EXTENSIONS_PATH=$(pwd) node ./node_modules/vscode/bin/test", 165 | "test:windows": "cd && code -n %CD%/test/sampleTestData --extensionDevelopmentPath=%CD% --extensionTestsPath=%CD%/test --verbose", 166 | "test": "node ./testScript", 167 | "postinstall": "node ./node_modules/vscode/bin/install" 168 | }, 169 | "devDependencies": { 170 | "@types/chai": "^4.1.7", 171 | "@types/node": "^10.12.5", 172 | "@types/proxyquire": "^1.3.28", 173 | "chai": "^4.2.0", 174 | "proxyquire": "^2.1.0", 175 | "typescript": "^3.1.6", 176 | "vscode": "^1.1.21" 177 | }, 178 | "dependencies": { 179 | "copy-paste": "^1.3.0", 180 | "find-parent-dir": "^0.3.0", 181 | "git-rev-2": "^0.1.0", 182 | "git-url-parse": "^11.1.1", 183 | "open": "6.0.0", 184 | "parse-git-config": "^0.3.1" 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /screenshots/context-menu-old.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugthesystem/vscode-open-in-github/b9f69fe06c3541d12f0f6d07f852733aa4c0d5e4/screenshots/context-menu-old.png -------------------------------------------------------------------------------- /screenshots/context-menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugthesystem/vscode-open-in-github/b9f69fe06c3541d12f0f6d07f852733aa4c0d5e4/screenshots/context-menu.png -------------------------------------------------------------------------------- /screenshots/copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugthesystem/vscode-open-in-github/b9f69fe06c3541d12f0f6d07f852733aa4c0d5e4/screenshots/copy.png -------------------------------------------------------------------------------- /screenshots/install.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugthesystem/vscode-open-in-github/b9f69fe06c3541d12f0f6d07f852733aa4c0d5e4/screenshots/install.png -------------------------------------------------------------------------------- /screenshots/open-in-github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugthesystem/vscode-open-in-github/b9f69fe06c3541d12f0f6d07f852733aa4c0d5e4/screenshots/open-in-github.png -------------------------------------------------------------------------------- /screenshots/pull-req-cmd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugthesystem/vscode-open-in-github/b9f69fe06c3541d12f0f6d07f852733aa4c0d5e4/screenshots/pull-req-cmd.png -------------------------------------------------------------------------------- /src/extension.js: -------------------------------------------------------------------------------- 1 | // The module 'vscode' contains the VS Code extensibility API 2 | // Import the module and reference it with the alias vscode in your code below 3 | 4 | var VsCode = require('vscode'); 5 | var Window = VsCode.window; 6 | var commands = VsCode.commands; 7 | var workspace = VsCode.workspace; 8 | var Position = VsCode.Position; 9 | 10 | var path = require('path'); 11 | var fs = require('fs'); 12 | var open = require('open'); 13 | var gitRev = require('git-rev-2'); 14 | var findParentDir = require('find-parent-dir'); 15 | var ini = require('ini'); 16 | 17 | const gitProvider = require('./gitProvider'); 18 | const requireSelectionForLines = workspace.getConfiguration('openInGitHub').get('requireSelectionForLines'); 19 | 20 | function getGitProviderLink(cb, fileFsPath, lines, pr) { 21 | var repoDir = findParentDir.sync(fileFsPath, '.git'); 22 | if (!repoDir) { 23 | throw 'Cant locate .git repository for this file'; 24 | } 25 | 26 | locateGitConfig(repoDir) 27 | .then(readConfigFile) 28 | .then(config => { 29 | 30 | gitRev.long(repoDir, function (branchErr, sha) { 31 | var rawUri, 32 | configuredBranch, 33 | provider = null, 34 | remoteName; 35 | 36 | gitRev.branch(repoDir, function (branchErr, branch) { 37 | // Check to see if the branch has a configured remote 38 | configuredBranch = config[`remote "${branch}"`]; 39 | 40 | if (configuredBranch) { 41 | // Use the current branch's configured remote 42 | remoteName = configuredBranch.remote; 43 | rawUri = config[`remote "${remoteName}"`].url; 44 | } else { 45 | const remotes = Object.keys(config).filter(k => k.startsWith('remote ')); 46 | if (remotes.length > 0) { 47 | rawUri = config[remotes[0]].url; 48 | } 49 | } 50 | 51 | if (!rawUri) { 52 | Window.showWarningMessage(`No remote found on branch.`); 53 | return; 54 | } 55 | 56 | try { 57 | provider = gitProvider(rawUri, sha); 58 | } catch (e) { 59 | let errmsg = e.toString(); 60 | Window.showWarningMessage(`Unknown Git provider. ${errmsg}`); 61 | return; 62 | } 63 | 64 | let formattedFilePath = path.relative(repoDir, fileFsPath).replace(/\\/g, '/'); 65 | formattedFilePath = formattedFilePath.replace(/\s{1}/g, '%20'); 66 | 67 | let subdir = repoDir !== fileFsPath ? '/' + formattedFilePath : ''; 68 | 69 | if (pr) { 70 | try { 71 | cb(provider.prUrl(branch)); 72 | } catch (e) { 73 | Window.showWarningMessage(e.toString()); 74 | return; 75 | } 76 | } else { 77 | if (lines) { 78 | if (lines[0] == lines[1]) { 79 | cb(provider.webUrl(sha, subdir, lines[0])); 80 | } else { 81 | cb(provider.webUrl(sha, subdir, lines[0], lines[1])); 82 | } 83 | } else { 84 | cb(provider.webUrl(sha, subdir)); 85 | } 86 | } 87 | }); 88 | }); 89 | }); 90 | } 91 | 92 | function locateGitConfig(repoDir) { 93 | return new Promise((resolve, reject) => { 94 | fs.lstat(path.join(repoDir, '.git'), (err, stat) => { 95 | if (err) { 96 | reject(err); 97 | return; 98 | } 99 | 100 | if (stat.isFile()) { 101 | // .git may be a file, similar to symbolic link, containing "gitdir: "" 102 | // this happens in gitsubmodules 103 | fs.readFile(path.join(repoDir, '.git'), 'utf-8', (err, data) => { 104 | if (err) { 105 | reject(err); 106 | return; 107 | } 108 | 109 | var match = data.match(/gitdir: (.*)/)[1]; 110 | if (!match) { 111 | reject('Unable to find gitdir in .git file'); 112 | return; 113 | } 114 | 115 | // set a fallback path 116 | var configPath = path.isAbsolute(match) ? path.join(match, 'config') : path.join(repoDir, match, 'config'); 117 | 118 | // for worktrees traverse up to the main .git folder 119 | var standardWorkTreeMatch = match.match(/\/\.git\/worktrees\//); 120 | if(standardWorkTreeMatch) { 121 | var mainGitFolder = match.slice(0, standardWorkTreeMatch.index); 122 | 123 | resolve(path.join(mainGitFolder, '.git', 'config')); 124 | return; 125 | } 126 | 127 | // for worktrees in a bare repository check every worktrees folder 128 | var bareWorkTreeMatches = match.matchAll(/\/worktrees\//g); 129 | if(bareWorkTreeMatches) { 130 | // generate promises to look for a file named config beside each matched worktrees folder 131 | var fileCheckPromises = [...bareWorkTreeMatches] 132 | .map((bareWorkTreeMatch) => 133 | new Promise((innerResolve, innerReject) => { 134 | var mainGitFolder = match.slice(0, bareWorkTreeMatch.index); 135 | 136 | fs.lstat(path.join(mainGitFolder, 'HEAD'), (err, stat) => { 137 | if (!err && stat.isFile()) { 138 | fs.lstat(path.join(mainGitFolder, 'config'), (err, stat) => { 139 | if (!err && stat.isFile()) { 140 | innerResolve(path.join(mainGitFolder, 'config')); 141 | } 142 | else { 143 | innerReject(); 144 | } 145 | }); 146 | } 147 | else { 148 | innerReject(); 149 | } 150 | }); 151 | }) 152 | ); 153 | 154 | return Promise 155 | .allSettled(fileCheckPromises) 156 | .then((results) => { 157 | var lastConfigPath = results 158 | .filter((result) => result.status === 'fulfilled') 159 | .pop(); 160 | 161 | // prefer the most deeply nested 'config' file that is beside a 'worktrees' folder 162 | if (lastConfigPath) { 163 | resolve(lastConfigPath.value); 164 | } 165 | else { 166 | resolve(configPath); 167 | } 168 | }); 169 | } 170 | else { 171 | resolve(configPath); 172 | } 173 | }); 174 | } else { 175 | resolve(path.join(repoDir, '.git', 'config')); 176 | } 177 | }); 178 | }); 179 | } 180 | 181 | function readConfigFile(path) { 182 | return new Promise((resolve, reject) => { 183 | fs.readFile(path, 'utf-8', (err, data) => { 184 | if (err) { 185 | console.error(err); 186 | reject(err); 187 | } 188 | resolve(ini.parse(data)); 189 | }); 190 | }); 191 | } 192 | 193 | function getGitProviderLinkForFile(fileFsPath, cb) { 194 | getGitProviderLink(cb, fileFsPath); 195 | } 196 | 197 | function getGitProviderLinkForCurrentEditorLines(cb) { 198 | var editor = Window.activeTextEditor; 199 | var fileFsPath = editor.document.uri.fsPath; 200 | 201 | if (includeLines(editor)) { 202 | getGitProviderLink(cb, fileFsPath, getSelectedLines(editor)); 203 | } else { 204 | getGitProviderLinkForFile(fileFsPath, cb); 205 | } 206 | } 207 | 208 | function includeLines(editor) { 209 | return !requireSelectionForLines || !editor.selection.isEmpty; 210 | } 211 | 212 | function getSelectedLines(editor) { 213 | var anchorLineIndex = editor.selection.anchor.line + 1; 214 | var activeLineIndex = editor.selection.active.line + 1; 215 | 216 | return [anchorLineIndex, activeLineIndex].sort(function (a, b) { 217 | return a - b 218 | }); 219 | } 220 | 221 | function getGitProviderLinkForRepo(cb) { 222 | getGitProviderLink(cb, workspace.rootPath); 223 | } 224 | 225 | function getGitProviderPullRequest(args, cb) { 226 | let fsPath; 227 | 228 | if (args && args.fsPath) { 229 | fsPath = args.fsPath; 230 | } else if (Window.activeTextEditor) { 231 | fsPath = Window.activeTextEditor.document.uri.fsPath; 232 | } 233 | 234 | getGitProviderLink(cb, fsPath, undefined, true); 235 | } 236 | 237 | function branchOnCallingContext(args, cb, pr) { 238 | if (pr) { 239 | return getGitProviderPullRequest(args, cb); 240 | } 241 | 242 | if (Window.activeTextEditor) { 243 | getGitProviderLinkForCurrentEditorLines(cb); 244 | } else if (args && args.fsPath) { 245 | getGitProviderLinkForFile(args.fsPath, cb); 246 | } else { 247 | // TODO: This missed in code review so should be refactored, it is broken. 248 | getGitProviderLinkForRepo(cb); 249 | } 250 | } 251 | 252 | 253 | function openInGitProvider(args) { 254 | branchOnCallingContext(args, open); 255 | } 256 | 257 | function copyGitProviderLinkToClipboard(args) { 258 | branchOnCallingContext(args, (content) => { VsCode.env.clipboard.writeText(content); }); 259 | } 260 | 261 | function openPrGitProvider(args) { 262 | branchOnCallingContext(args, open, true); 263 | } 264 | 265 | function activate(context) { 266 | commands.registerCommand('extension.openInGitHub', openInGitProvider); 267 | commands.registerCommand('extension.copyGitHubLinkToClipboard', copyGitProviderLinkToClipboard); 268 | commands.registerCommand('extension.openPrGitProvider', openPrGitProvider); 269 | } 270 | 271 | exports.activate = activate; 272 | -------------------------------------------------------------------------------- /src/gitProvider.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const workspace = require('vscode').workspace 4 | const querystring = require('querystring'); 5 | const gitUrlParse = require('git-url-parse'); 6 | const path = require('path'); 7 | const useCommitSHAInURL = workspace.getConfiguration('openInGitHub').get('useCommitSHAInURL', false); 8 | 9 | class BaseProvider { 10 | constructor(gitUrl, sha) { 11 | this.gitUrl = gitUrl; 12 | this.sha = sha; 13 | } 14 | 15 | get baseUrl() { 16 | return this.gitUrl.toString(providerProtocol).replace(/(\.git)$/, ''); 17 | } 18 | 19 | /** 20 | * Get the Web URL. 21 | * 22 | * @param {string} branch 23 | * @param {string} filePath The file path relative to repository root, beginning with '/'. 24 | * @param {number} line 25 | * @param {number} endLine The last line in a multi-line selection 26 | * @return {string} The URL to be opened with the browser. 27 | */ 28 | webUrl(branch, filePath, line, endLine) { 29 | return ''; 30 | } 31 | prUrl(branch) { 32 | return ''; 33 | } 34 | } 35 | 36 | class GitHub extends BaseProvider { 37 | webUrl(branch, filePath, line, endLine) { 38 | let blob = branch; 39 | if (useCommitSHAInURL) { 40 | blob = this.sha; 41 | } 42 | if (filePath) { 43 | return `${this.baseUrl}/blob/${blob}${filePath}` + (line ? '#L' + line : '') + (endLine ? '-L' + endLine : ''); 44 | } 45 | return `${this.baseUrl}/tree/${blob}`; 46 | } 47 | prUrl(branch) { 48 | return `${this.baseUrl}/pull/new/${branch}`; 49 | } 50 | } 51 | 52 | class GitLab extends BaseProvider { 53 | webUrl(branch, filePath, line, endLine) { 54 | if (filePath) { 55 | return `${this.baseUrl}/blob/${branch}` + (filePath ? `${filePath}` : '') + (line ? `#L${line}` : ''); 56 | } 57 | return `${this.baseUrl}/tree/${branch}`; 58 | } 59 | prUrl(branch) { 60 | //https://docs.gitlab.com/ee/api/merge_requests.html#create-mr 61 | //`${this.baseUrl}/pull-requests/new?source_branch=${branch}&target_branch=${????}&title=${????}` 62 | throw new Error(`Doesn't support Merge Request from URL in GitLab yet`); 63 | } 64 | } 65 | 66 | class Gitea extends BaseProvider { 67 | webUrl(branch, filePath, line, endLine) { 68 | let blobPath = `branch/${branch}`; 69 | if (useCommitSHAInURL) { 70 | blobPath = `commit/${this.sha}`; 71 | } 72 | if (filePath) { 73 | return `${this.baseUrl}/src/${blobPath}` + (filePath ? `${filePath}` : '') + (line ? `#L${line}` : ''); 74 | } 75 | return `${this.baseUrl}/src/${blobPath}`; 76 | } 77 | prUrl(branch) { 78 | throw new Error(`Doesn't support Merge Request from URL in Gitea yet`); 79 | } 80 | } 81 | 82 | class Bitbucket extends BaseProvider { 83 | webUrl(branch, filePath, line, endLine) { 84 | const fileName = path.basename(filePath) 85 | return `${this.baseUrl}/src/${this.sha}` + (filePath ? `${filePath}` : '') + (line ? `#${fileName}-${line}` : ''); 86 | } 87 | prUrl(branch) { 88 | const repo = this.baseUrl.replace(`${providerProtocol}://bitbucket.org/`, '') 89 | return `${this.baseUrl}/pull-requests/new?source=${repo}%3A%3A${branch}&dest=${repo}%3A%3Aintegration`; 90 | // looks like this: 91 | // https://bitbucket.org/${org/repo}/pull-requests/new?source=${org/repo}%3A%3A${branch}&dest=${org/repo}%3A%3A${destBranch} 92 | } 93 | } 94 | 95 | class VisualStudio extends BaseProvider { 96 | get baseUrl() { 97 | return `https://${this.gitUrl.resource}${this.gitUrl.pathname}`.replace(/\.git/, ''); 98 | } 99 | 100 | webUrl(branch, filePath, line, endLine) { 101 | let query = { 102 | version: `GB${branch}`, 103 | }; 104 | if (filePath) { 105 | query['path'] = filePath; 106 | } 107 | if (line) { 108 | query['line'] = line; 109 | } 110 | return `${this.baseUrl}?${querystring.stringify(query)}`; 111 | } 112 | 113 | prUrl(branch) { 114 | throw new Error(`Doesn't support Merge Request from URL in VisualStudio.com yet`); 115 | } 116 | } 117 | 118 | class CustomProvider extends BaseProvider { 119 | constructor(gitUrl, sha) { 120 | super(gitUrl, sha); 121 | this.customProviderPath = workspace.getConfiguration('openInGitHub').get('customProviderPath', ''); 122 | this.customBlobPath = workspace.getConfiguration('openInGitHub').get('customBlobPath', '+'); 123 | this.customLinePrefix = workspace.getConfiguration('openInGitHub').get('customLinePrefix', '#'); 124 | } 125 | get baseUrl() { 126 | return `${this.customProviderPath}${this.gitUrl.pathname}`.replace(/\.git/, ''); 127 | } 128 | webUrl(branch, filePath, line, endLine) { 129 | if (filePath) { 130 | const lineURL = line ? `${this.customLinePrefix}${line}` : ''; 131 | const branchPath = alwaysOpenInDefaultBranch ? defaultPrBranch : branch; 132 | return `${this.baseUrl}/${this.customBlobPath}/${branchPath}${filePath}${lineURL}`; 133 | } 134 | return `${this.baseUrl}/tree/${branch}`; 135 | } 136 | prUrl(branch) { 137 | throw new Error(`Doesn't support Merge Request from URL in custom git repo yet`); 138 | } 139 | } 140 | 141 | const gitHubDomain = workspace.getConfiguration('openInGitHub').get('gitHubDomain', 'github.com'); 142 | const giteaDomain = workspace.getConfiguration('openInGitHub').get('giteaDomain', 'gitea.io'); 143 | const providerType = workspace.getConfiguration('openInGitHub').get('providerType', 'unknown'); 144 | const providerProtocol = workspace.getConfiguration('openInGitHub').get('providerProtocol', 'https'); 145 | const defaultPrBranch = workspace.getConfiguration('openInGitHub').get('defaultPullRequestBranch', 'integration') 146 | const alwaysOpenInDefaultBranch = workspace.getConfiguration('openInGitHub').get('alwaysOpenInDefaultBranch', false); 147 | 148 | const providers = { 149 | [gitHubDomain]: GitHub, 150 | 'gitlab.com': GitLab, 151 | [giteaDomain]: Gitea, 152 | 'bitbucket.org': Bitbucket, 153 | 'visualstudio.com': VisualStudio, 154 | 'custom': CustomProvider 155 | }; 156 | 157 | /** 158 | * Get the Git provider of the remote URL. 159 | * 160 | * @param {string} remoteUrl 161 | * @return {BaseProvider|null} 162 | */ 163 | function gitProvider(remoteUrl, sha) { 164 | const gitUrl = gitUrlParse(remoteUrl); 165 | for (const domain of Object.keys(providers)) { 166 | if (domain === gitUrl.resource || domain === gitUrl.source) { 167 | return new providers[domain](gitUrl, sha); 168 | } else if (domain.indexOf(providerType) > -1) { 169 | return new providers[domain](gitUrl, sha); 170 | } 171 | } 172 | throw new Error('unknown Provider'); 173 | } 174 | 175 | module.exports = gitProvider; 176 | -------------------------------------------------------------------------------- /test/extension.test.js: -------------------------------------------------------------------------------- 1 | // 2 | // Note: This example test is leveraging the Mocha test framework. 3 | // Please refer to their documentation on https://mochajs.org/ for help. 4 | // 5 | var VsCode = require('vscode'); 6 | var Window = VsCode.window; 7 | var commands = VsCode.commands; 8 | var workspace = VsCode.workspace; 9 | var Position = VsCode.Position; 10 | var selection = VsCode.Selection; 11 | var extensions = VsCode.extensions; 12 | 13 | var expect = require("chai").expect; 14 | var copy = require('copy-paste').copy; 15 | var paste = require('copy-paste').paste; 16 | var fs = require("fs"); 17 | 18 | var extensionID = 'ziyasal.vscode-open-in-github'; 19 | var extension = extensions.getExtension(extensionID); 20 | var testsPath = extension.extensionPath + '/test/'; 21 | var fakeRepoPath = testsPath + 'sampleTestData/'; 22 | var relativeSampleFilePath = 'sampleDirectory/sampleTestFile.txt'; 23 | var absoluteSampleFilePath = fakeRepoPath + relativeSampleFilePath; 24 | 25 | var fakeUserName = "testUser"; 26 | var fakeRepoName = "testRepo"; 27 | var fakeSHA = "a9b854f5131a863ad47d3b6c6bbca8cd17a8aff3"; 28 | 29 | function testClipboard(expectedClipboardContent) { 30 | expect(paste()).to.be.equal(expectedClipboardContent, "Clipboard content doest not match."); 31 | } 32 | 33 | function timeOut() { 34 | return new Promise(function (done) { setTimeout(done, 600) }); 35 | } 36 | 37 | function setClipboardTo(content) { 38 | return function (done) { 39 | copy(content, done); 40 | }; 41 | } 42 | 43 | suite('GitHub Tests', function () { 44 | var originalClipboardContent; 45 | 46 | suiteSetup(function () { 47 | fs.renameSync(`${fakeRepoPath}git`, `${fakeRepoPath}.git`); 48 | setClipboardTo(""); 49 | return extension.activate() 50 | }); 51 | 52 | suiteTeardown(function () { 53 | fs.renameSync(`${fakeRepoPath}.git`, `${fakeRepoPath}git`); 54 | }); 55 | 56 | test('Line', function () { 57 | var expectedLineResult = `https://github.com/${fakeUserName}/${fakeRepoName}/blob/${fakeSHA}/${relativeSampleFilePath}#L2`; 58 | 59 | return workspace.openTextDocument(absoluteSampleFilePath).then(function (workingDocument) { 60 | return Window.showTextDocument(workingDocument); 61 | }) 62 | .then(function (editor) { 63 | editor.selection = new selection(new Position(1, 0), new Position(1, 0)); 64 | }) 65 | .then(function () { 66 | return commands.executeCommand("extension.copyGitHubLinkToClipboard"); 67 | }) 68 | .then(timeOut) 69 | .then(function () { 70 | testClipboard(expectedLineResult); 71 | }); 72 | }); 73 | 74 | test('File', function () { 75 | var expectedFileResult = `https://github.com/${fakeUserName}/${fakeRepoName}/blob/master/${relativeSampleFilePath}`; 76 | //"workbench.files.action.focusFileExplorer" 77 | // How to get focus on file in explorer and call the command from context menu? 78 | this.skip(); 79 | }); 80 | 81 | test('Repo', function () { 82 | var expectedRepoResult = `https://github.com/${fakeUserName}/${fakeRepoName}/tree/${fakeSHA}`; 83 | 84 | return commands.executeCommand("workbench.action.closeAllEditors") 85 | .then(timeOut) 86 | .then(function () { 87 | return commands.executeCommand("extension.copyGitHubLinkToClipboard"); 88 | }) 89 | .then(timeOut) 90 | .then(function () { 91 | testClipboard(expectedRepoResult); 92 | }); 93 | }); 94 | 95 | test('Directory', function () { 96 | var expectedDirResult = `https://github.com/${fakeUserName}/${fakeRepoName}/blob/master/sampleDirectory`; 97 | // How to get focus on directory in explorer and call the command from context menu? 98 | this.skip(); 99 | }); 100 | }); 101 | -------------------------------------------------------------------------------- /test/gitProvider.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const querystring = require('querystring'); 5 | const expect = require('chai').expect; 6 | const proxyquire = require('proxyquire'); 7 | 8 | const gitProvider = require('../src/gitProvider'); 9 | 10 | const userName = 'testUser'; 11 | const repoName = 'testRepo'; 12 | const filePath = '/sampleDirectory/sampleTestFile.txt'; 13 | const fileName = path.basename(filePath); 14 | const branch = 'master'; 15 | const line = 123; 16 | 17 | suite('gitProvider', function () { 18 | suite('GitHub', function () { 19 | const remoteUrl = `https://github.com/${userName}/${repoName}.git`; 20 | const provider = gitProvider(remoteUrl); 21 | 22 | suite('#webUrl(branch, filePath)', function () { 23 | test('should returns file URL', function () { 24 | const expectedUrl = `https://github.com/${userName}/${repoName}/blob/${branch}${filePath}`; 25 | const webUrl = provider.webUrl(branch, filePath); 26 | expect(webUrl).to.equal(expectedUrl); 27 | }); 28 | }); 29 | 30 | suite('#webUrl(branch, filePath, line)', function () { 31 | test('should returns file URL with line hash', function () { 32 | const expectedUrl = `https://github.com/${userName}/${repoName}/blob/${branch}${filePath}#L${line}`; 33 | const webUrl = provider.webUrl(branch, filePath, line); 34 | expect(webUrl).to.equal(expectedUrl); 35 | }); 36 | }); 37 | 38 | suite('#webUrl(branch)', function () { 39 | test('should returns repository root URL', function () { 40 | const expectedUrl = `https://github.com/${userName}/${repoName}/tree/${branch}`; 41 | const webUrl = provider.webUrl(branch); 42 | expect(webUrl).to.equal(expectedUrl); 43 | }); 44 | }); 45 | 46 | suite('with ssh remote URL', function () { 47 | const remoteUrl = `git@github.com:${userName}/${repoName}.git`; 48 | const provider = gitProvider(remoteUrl); 49 | 50 | suite('#webUrl(branch, filePath)', function () { 51 | test('should returns HTTPS URL', function () { 52 | const expectedUrl = `https://github.com/${userName}/${repoName}/blob/${branch}${filePath}`; 53 | const webUrl = provider.webUrl(branch, filePath); 54 | expect(webUrl).to.equal(expectedUrl); 55 | }); 56 | }); 57 | }); 58 | 59 | suite('with custom domain', function () { 60 | const testDomain = 'github.testdomain.com'; 61 | const remoteUrl = `https://${testDomain}/${userName}/${repoName}.git`; 62 | 63 | const fakeVscode = { 64 | workspace: { 65 | getConfiguration: function () { 66 | return { 67 | get: function (configKey) { 68 | if (configKey === 'gitHubDomain') { 69 | return testDomain; 70 | } else if (configKey === 'useCommitSHAInURL') { 71 | return false; 72 | } 73 | }, 74 | }; 75 | }, 76 | }, 77 | }; 78 | const gitProvider = proxyquire('../src/gitProvider.js', { vscode: fakeVscode }); 79 | const provider = gitProvider(remoteUrl); 80 | 81 | suite('#webUrl(branch, filePath)', function () { 82 | test('should return custom domain URL', function () { 83 | const expectedUrl = `https://${testDomain}/${userName}/${repoName}/blob/${branch}${filePath}`; 84 | const webUrl = provider.webUrl(branch, filePath); 85 | expect(webUrl).to.equal(expectedUrl); 86 | }); 87 | }); 88 | }); 89 | 90 | suite('with custom domain and protocol', function () { 91 | const testDomain = 'github.testdomain.com'; 92 | const testProtocol = 'http'; 93 | const remoteUrl = `https://${testDomain}/${userName}/${repoName}.git`; 94 | 95 | const fakeVscode = { 96 | workspace: { 97 | getConfiguration: function () { 98 | return { 99 | get: function (configKey) { 100 | if (configKey === 'gitHubDomain') { 101 | return testDomain; 102 | } else if (configKey === 'providerProtocol') { 103 | return testProtocol; 104 | } 105 | }, 106 | }; 107 | }, 108 | }, 109 | }; 110 | const gitProvider = proxyquire('../src/gitProvider.js', { vscode: fakeVscode }); 111 | const provider = gitProvider(remoteUrl); 112 | 113 | suite('#webUrl(branch, filePath)', function () { 114 | test('should return custom domain URL', function () { 115 | const expectedUrl = `http://${testDomain}/${userName}/${repoName}/blob/${branch}${filePath}`; 116 | const webUrl = provider.webUrl(branch, filePath); 117 | expect(webUrl).to.equal(expectedUrl); 118 | }); 119 | }); 120 | }); 121 | }); 122 | 123 | suite('Bitbucket', function () { 124 | const remoteUrl = `https://bitbucket.org/${userName}/${repoName}.git`; 125 | const sha = 'f9f2dcbf56e88ee3612c9890a6df1cfd4dde8c5e'; 126 | const provider = gitProvider(remoteUrl, sha); 127 | 128 | suite('#webUrl(branch, filePath)', function () { 129 | test('should returns file URL', function () { 130 | const expectedUrl = `https://bitbucket.org/${userName}/${repoName}/src/${sha}${filePath}`; 131 | const webUrl = provider.webUrl(branch, filePath); 132 | expect(webUrl).to.equal(expectedUrl); 133 | }); 134 | }); 135 | 136 | suite('#webUrl(branch, filePath, line)', function () { 137 | test('should returns file URL with line hash', function () { 138 | const expectedUrl = `https://bitbucket.org/${userName}/${repoName}/src/${sha}${filePath}#${fileName}-${line}`; 139 | const webUrl = provider.webUrl(branch, filePath, line); 140 | expect(webUrl).to.equal(expectedUrl); 141 | }); 142 | }); 143 | 144 | suite('#webUrl(branch)', function () { 145 | test('should returns repository root URL', function () { 146 | const expectedUrl = `https://bitbucket.org/${userName}/${repoName}/src/${sha}`; 147 | const webUrl = provider.webUrl(branch, ''); 148 | expect(webUrl).to.equal(expectedUrl); 149 | }); 150 | }); 151 | 152 | suite('with ssh remote URL', function () { 153 | const remoteUrl = `git@bitbucket.org:${userName}/${repoName}.git`; 154 | const provider = gitProvider(remoteUrl, sha); 155 | 156 | suite('#webUrl(branch, filePath)', function () { 157 | test('should returns HTTPS URL', function () { 158 | const expectedUrl = `https://bitbucket.org/${userName}/${repoName}/src/${sha}${filePath}`; 159 | const webUrl = provider.webUrl(branch, filePath); 160 | expect(webUrl).to.equal(expectedUrl); 161 | }); 162 | }); 163 | }); 164 | }); 165 | 166 | suite('GitLab', function () { 167 | const remoteUrl = `https://gitlab.com/${userName}/${repoName}.git`; 168 | const provider = gitProvider(remoteUrl); 169 | 170 | suite('#webUrl(branch, filePath)', function () { 171 | test('should returns file URL', function () { 172 | const expectedUrl = `https://gitlab.com/${userName}/${repoName}/blob/${branch}${filePath}`; 173 | const webUrl = provider.webUrl(branch, filePath); 174 | expect(webUrl).to.equal(expectedUrl); 175 | }); 176 | }); 177 | 178 | suite('#webUrl(branch, filePath, line)', function () { 179 | test('should returns file URL with line hash', function () { 180 | const expectedUrl = `https://gitlab.com/${userName}/${repoName}/blob/${branch}${filePath}#L${line}`; 181 | const webUrl = provider.webUrl(branch, filePath, line); 182 | expect(webUrl).to.equal(expectedUrl); 183 | }); 184 | }); 185 | 186 | suite('#webUrl(branch)', function () { 187 | test('should returns repository root URL', function () { 188 | const expectedUrl = `https://gitlab.com/${userName}/${repoName}/tree/${branch}`; 189 | const webUrl = provider.webUrl(branch); 190 | expect(webUrl).to.equal(expectedUrl); 191 | }); 192 | }); 193 | 194 | suite('with ssh remote URL', function () { 195 | const remoteUrl = `git@gitlab.com:${userName}/${repoName}.git`; 196 | const provider = gitProvider(remoteUrl); 197 | 198 | suite('#webUrl(branch, filePath)', function () { 199 | test('should returns HTTPS URL', function () { 200 | const expectedUrl = `https://gitlab.com/${userName}/${repoName}/blob/${branch}${filePath}`; 201 | const webUrl = provider.webUrl(branch, filePath); 202 | expect(webUrl).to.equal(expectedUrl); 203 | }); 204 | }); 205 | }); 206 | }); 207 | 208 | suite('VisualStudio', function () { 209 | const projectName = 'testProject'; 210 | const remoteUrl = `https://test-account.visualstudio.com/${projectName}/_git/${repoName}.git`; 211 | const provider = gitProvider(remoteUrl); 212 | 213 | suite('#webUrl(branch, filePath)', function () { 214 | test('should returns file URL', function () { 215 | const expectedUrl = `https://test-account.visualstudio.com/${projectName}/_git/${repoName}`; 216 | const expectedQuery = { 217 | path: filePath, 218 | version: `GB${branch}`, 219 | }; 220 | const webUrl = provider.webUrl(branch, filePath); 221 | const [url, query] = webUrl.split('?'); 222 | expect(url).to.equal(expectedUrl); 223 | expect(querystring.parse(query)).to.deep.equal(expectedQuery); 224 | }); 225 | }); 226 | 227 | suite('#webUrl(branch, filePath, line)', function () { 228 | test('should returns file URL with line query', function () { 229 | const expectedUrl = `https://test-account.visualstudio.com/${projectName}/_git/${repoName}`; 230 | const expectedQuery = { 231 | path: filePath, 232 | version: `GB${branch}`, 233 | line: String(line), 234 | }; 235 | const webUrl = provider.webUrl(branch, filePath, line); 236 | const [url, query] = webUrl.split('?'); 237 | expect(url).to.equal(expectedUrl); 238 | expect(querystring.parse(query)).to.deep.equal(expectedQuery); 239 | }); 240 | }); 241 | 242 | suite('#webUrl(branch)', function () { 243 | test('should returns repository root URL', function () { 244 | const expectedUrl = `https://test-account.visualstudio.com/${projectName}/_git/${repoName}`; 245 | const expectedQuery = { 246 | version: `GB${branch}`, 247 | }; 248 | const webUrl = provider.webUrl(branch); 249 | const [url, query] = webUrl.split('?'); 250 | expect(url).to.equal(expectedUrl); 251 | expect(querystring.parse(query)).to.deep.equal(expectedQuery); 252 | }); 253 | }); 254 | 255 | suite('with ssh remote URL', function () { 256 | const remoteUrl = `ssh://test-account@test-account.visualstudio.com:22/${projectName}/_git/${repoName}.git`; 257 | const provider = gitProvider(remoteUrl); 258 | 259 | suite('#webUrl(branch, filePath)', function () { 260 | test('should returns HTTPS URL', function () { 261 | const expectedUrl = `https://test-account.visualstudio.com/${projectName}/_git/${repoName}`; 262 | const expectedQuery = { 263 | path: filePath, 264 | version: `GB${branch}`, 265 | }; 266 | const webUrl = provider.webUrl(branch, filePath); 267 | const [url, query] = webUrl.split('?'); 268 | expect(url).to.equal(expectedUrl); 269 | expect(querystring.parse(query)).to.deep.equal(expectedQuery); 270 | }); 271 | }); 272 | }); 273 | }); 274 | }); 275 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 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 | var testRunner = require('vscode/lib/testrunner'); 14 | 15 | // You can directly control Mocha options by uncommenting the following lines 16 | // See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info 17 | testRunner.configure({ 18 | ui: 'tdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.) 19 | useColors: true, // colored output from test results 20 | timeout: 10000 21 | }); 22 | 23 | module.exports = testRunner; -------------------------------------------------------------------------------- /test/sampleTestData/git/COMMIT_EDITMSG: -------------------------------------------------------------------------------- 1 | Add dir 2 | -------------------------------------------------------------------------------- /test/sampleTestData/git/FETCH_HEAD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugthesystem/vscode-open-in-github/b9f69fe06c3541d12f0f6d07f852733aa4c0d5e4/test/sampleTestData/git/FETCH_HEAD -------------------------------------------------------------------------------- /test/sampleTestData/git/HEAD: -------------------------------------------------------------------------------- 1 | ref: refs/heads/master 2 | -------------------------------------------------------------------------------- /test/sampleTestData/git/ORIG_HEAD: -------------------------------------------------------------------------------- 1 | a8a663582e191d2572dc5132ad8b971de9acc548 2 | -------------------------------------------------------------------------------- /test/sampleTestData/git/config: -------------------------------------------------------------------------------- 1 | [core] 2 | repositoryformatversion = 0 3 | filemode = false 4 | bare = false 5 | logallrefupdates = true 6 | symlinks = false 7 | ignorecase = true 8 | hideDotFiles = dotGitOnly 9 | [remote "origin"] 10 | url = https://github.com/testUser/testRepo.git 11 | fetch = +refs/heads/*:refs/remotes/origin/* 12 | -------------------------------------------------------------------------------- /test/sampleTestData/git/description: -------------------------------------------------------------------------------- 1 | Unnamed repository; edit this file 'description' to name the repository. 2 | -------------------------------------------------------------------------------- /test/sampleTestData/git/hooks/applypatch-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message taken by 4 | # applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. The hook is 8 | # allowed to edit the commit message file. 9 | # 10 | # To enable this hook, rename this file to "applypatch-msg". 11 | 12 | . git-sh-setup 13 | commitmsg="$(git rev-parse --git-path hooks/commit-msg)" 14 | test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} 15 | : 16 | -------------------------------------------------------------------------------- /test/sampleTestData/git/hooks/commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to check the commit log message. 4 | # Called by "git commit" with one argument, the name of the file 5 | # that has the commit message. The hook should exit with non-zero 6 | # status after issuing an appropriate message if it wants to stop the 7 | # commit. The hook is allowed to edit the commit message file. 8 | # 9 | # To enable this hook, rename this file to "commit-msg". 10 | 11 | # Uncomment the below to add a Signed-off-by line to the message. 12 | # Doing this in a hook is a bad idea in general, but the prepare-commit-msg 13 | # hook is more suited to it. 14 | # 15 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 16 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 17 | 18 | # This example catches duplicate Signed-off-by lines. 19 | 20 | test "" = "$(grep '^Signed-off-by: ' "$1" | 21 | sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { 22 | echo >&2 Duplicate Signed-off-by lines. 23 | exit 1 24 | } 25 | -------------------------------------------------------------------------------- /test/sampleTestData/git/hooks/post-update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare a packed repository for use over 4 | # dumb transports. 5 | # 6 | # To enable this hook, rename this file to "post-update". 7 | 8 | exec git update-server-info 9 | -------------------------------------------------------------------------------- /test/sampleTestData/git/hooks/pre-applypatch.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed 4 | # by applypatch from an e-mail message. 5 | # 6 | # The hook should exit with non-zero status after issuing an 7 | # appropriate message if it wants to stop the commit. 8 | # 9 | # To enable this hook, rename this file to "pre-applypatch". 10 | 11 | . git-sh-setup 12 | precommit="$(git rev-parse --git-path hooks/pre-commit)" 13 | test -x "$precommit" && exec "$precommit" ${1+"$@"} 14 | : 15 | -------------------------------------------------------------------------------- /test/sampleTestData/git/hooks/pre-commit.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to verify what is about to be committed. 4 | # Called by "git commit" with no arguments. The hook should 5 | # exit with non-zero status after issuing an appropriate message if 6 | # it wants to stop the commit. 7 | # 8 | # To enable this hook, rename this file to "pre-commit". 9 | 10 | if git rev-parse --verify HEAD >/dev/null 2>&1 11 | then 12 | against=HEAD 13 | else 14 | # Initial commit: diff against an empty tree object 15 | against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 16 | fi 17 | 18 | # If you want to allow non-ASCII filenames set this variable to true. 19 | allownonascii=$(git config --bool hooks.allownonascii) 20 | 21 | # Redirect output to stderr. 22 | exec 1>&2 23 | 24 | # Cross platform projects tend to avoid non-ASCII filenames; prevent 25 | # them from being added to the repository. We exploit the fact that the 26 | # printable range starts at the space character and ends with tilde. 27 | if [ "$allownonascii" != "true" ] && 28 | # Note that the use of brackets around a tr range is ok here, (it's 29 | # even required, for portability to Solaris 10's /usr/bin/tr), since 30 | # the square bracket bytes happen to fall in the designated range. 31 | test $(git diff --cached --name-only --diff-filter=A -z $against | 32 | LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 33 | then 34 | cat <<\EOF 35 | Error: Attempt to add a non-ASCII file name. 36 | 37 | This can cause problems if you want to work with people on other platforms. 38 | 39 | To be portable it is advisable to rename the file. 40 | 41 | If you know what you are doing you can disable this check using: 42 | 43 | git config hooks.allownonascii true 44 | EOF 45 | exit 1 46 | fi 47 | 48 | # If there are whitespace errors, print the offending file names and fail. 49 | exec git diff-index --check --cached $against -- 50 | -------------------------------------------------------------------------------- /test/sampleTestData/git/hooks/pre-push.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # An example hook script to verify what is about to be pushed. Called by "git 4 | # push" after it has checked the remote status, but before anything has been 5 | # pushed. If this script exits with a non-zero status nothing will be pushed. 6 | # 7 | # This hook is called with the following parameters: 8 | # 9 | # $1 -- Name of the remote to which the push is being done 10 | # $2 -- URL to which the push is being done 11 | # 12 | # If pushing without using a named remote those arguments will be equal. 13 | # 14 | # Information about the commits which are being pushed is supplied as lines to 15 | # the standard input in the form: 16 | # 17 | # 18 | # 19 | # This sample shows how to prevent push of commits where the log message starts 20 | # with "WIP" (work in progress). 21 | 22 | remote="$1" 23 | url="$2" 24 | 25 | z40=0000000000000000000000000000000000000000 26 | 27 | while read local_ref local_sha remote_ref remote_sha 28 | do 29 | if [ "$local_sha" = $z40 ] 30 | then 31 | # Handle delete 32 | : 33 | else 34 | if [ "$remote_sha" = $z40 ] 35 | then 36 | # New branch, examine all commits 37 | range="$local_sha" 38 | else 39 | # Update to existing branch, examine new commits 40 | range="$remote_sha..$local_sha" 41 | fi 42 | 43 | # Check for WIP commit 44 | commit=`git rev-list -n 1 --grep '^WIP' "$range"` 45 | if [ -n "$commit" ] 46 | then 47 | echo >&2 "Found WIP commit in $local_ref, not pushing" 48 | exit 1 49 | fi 50 | fi 51 | done 52 | 53 | exit 0 54 | -------------------------------------------------------------------------------- /test/sampleTestData/git/hooks/pre-rebase.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright (c) 2006, 2008 Junio C Hamano 4 | # 5 | # The "pre-rebase" hook is run just before "git rebase" starts doing 6 | # its job, and can prevent the command from running by exiting with 7 | # non-zero status. 8 | # 9 | # The hook is called with the following parameters: 10 | # 11 | # $1 -- the upstream the series was forked from. 12 | # $2 -- the branch being rebased (or empty when rebasing the current branch). 13 | # 14 | # This sample shows how to prevent topic branches that are already 15 | # merged to 'next' branch from getting rebased, because allowing it 16 | # would result in rebasing already published history. 17 | 18 | publish=next 19 | basebranch="$1" 20 | if test "$#" = 2 21 | then 22 | topic="refs/heads/$2" 23 | else 24 | topic=`git symbolic-ref HEAD` || 25 | exit 0 ;# we do not interrupt rebasing detached HEAD 26 | fi 27 | 28 | case "$topic" in 29 | refs/heads/??/*) 30 | ;; 31 | *) 32 | exit 0 ;# we do not interrupt others. 33 | ;; 34 | esac 35 | 36 | # Now we are dealing with a topic branch being rebased 37 | # on top of master. Is it OK to rebase it? 38 | 39 | # Does the topic really exist? 40 | git show-ref -q "$topic" || { 41 | echo >&2 "No such branch $topic" 42 | exit 1 43 | } 44 | 45 | # Is topic fully merged to master? 46 | not_in_master=`git rev-list --pretty=oneline ^master "$topic"` 47 | if test -z "$not_in_master" 48 | then 49 | echo >&2 "$topic is fully merged to master; better remove it." 50 | exit 1 ;# we could allow it, but there is no point. 51 | fi 52 | 53 | # Is topic ever merged to next? If so you should not be rebasing it. 54 | only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` 55 | only_next_2=`git rev-list ^master ${publish} | sort` 56 | if test "$only_next_1" = "$only_next_2" 57 | then 58 | not_in_topic=`git rev-list "^$topic" master` 59 | if test -z "$not_in_topic" 60 | then 61 | echo >&2 "$topic is already up-to-date with master" 62 | exit 1 ;# we could allow it, but there is no point. 63 | else 64 | exit 0 65 | fi 66 | else 67 | not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` 68 | /usr/bin/perl -e ' 69 | my $topic = $ARGV[0]; 70 | my $msg = "* $topic has commits already merged to public branch:\n"; 71 | my (%not_in_next) = map { 72 | /^([0-9a-f]+) /; 73 | ($1 => 1); 74 | } split(/\n/, $ARGV[1]); 75 | for my $elem (map { 76 | /^([0-9a-f]+) (.*)$/; 77 | [$1 => $2]; 78 | } split(/\n/, $ARGV[2])) { 79 | if (!exists $not_in_next{$elem->[0]}) { 80 | if ($msg) { 81 | print STDERR $msg; 82 | undef $msg; 83 | } 84 | print STDERR " $elem->[1]\n"; 85 | } 86 | } 87 | ' "$topic" "$not_in_next" "$not_in_master" 88 | exit 1 89 | fi 90 | 91 | exit 0 92 | 93 | ################################################################ 94 | 95 | This sample hook safeguards topic branches that have been 96 | published from being rewound. 97 | 98 | The workflow assumed here is: 99 | 100 | * Once a topic branch forks from "master", "master" is never 101 | merged into it again (either directly or indirectly). 102 | 103 | * Once a topic branch is fully cooked and merged into "master", 104 | it is deleted. If you need to build on top of it to correct 105 | earlier mistakes, a new topic branch is created by forking at 106 | the tip of the "master". This is not strictly necessary, but 107 | it makes it easier to keep your history simple. 108 | 109 | * Whenever you need to test or publish your changes to topic 110 | branches, merge them into "next" branch. 111 | 112 | The script, being an example, hardcodes the publish branch name 113 | to be "next", but it is trivial to make it configurable via 114 | $GIT_DIR/config mechanism. 115 | 116 | With this workflow, you would want to know: 117 | 118 | (1) ... if a topic branch has ever been merged to "next". Young 119 | topic branches can have stupid mistakes you would rather 120 | clean up before publishing, and things that have not been 121 | merged into other branches can be easily rebased without 122 | affecting other people. But once it is published, you would 123 | not want to rewind it. 124 | 125 | (2) ... if a topic branch has been fully merged to "master". 126 | Then you can delete it. More importantly, you should not 127 | build on top of it -- other people may already want to 128 | change things related to the topic as patches against your 129 | "master", so if you need further changes, it is better to 130 | fork the topic (perhaps with the same name) afresh from the 131 | tip of "master". 132 | 133 | Let's look at this example: 134 | 135 | o---o---o---o---o---o---o---o---o---o "next" 136 | / / / / 137 | / a---a---b A / / 138 | / / / / 139 | / / c---c---c---c B / 140 | / / / \ / 141 | / / / b---b C \ / 142 | / / / / \ / 143 | ---o---o---o---o---o---o---o---o---o---o---o "master" 144 | 145 | 146 | A, B and C are topic branches. 147 | 148 | * A has one fix since it was merged up to "next". 149 | 150 | * B has finished. It has been fully merged up to "master" and "next", 151 | and is ready to be deleted. 152 | 153 | * C has not merged to "next" at all. 154 | 155 | We would want to allow C to be rebased, refuse A, and encourage 156 | B to be deleted. 157 | 158 | To compute (1): 159 | 160 | git rev-list ^master ^topic next 161 | git rev-list ^master next 162 | 163 | if these match, topic has not merged in next at all. 164 | 165 | To compute (2): 166 | 167 | git rev-list master..topic 168 | 169 | if this is empty, it is fully merged to "master". 170 | -------------------------------------------------------------------------------- /test/sampleTestData/git/hooks/prepare-commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to prepare the commit log message. 4 | # Called by "git commit" with the name of the file that has the 5 | # commit message, followed by the description of the commit 6 | # message's source. The hook's purpose is to edit the commit 7 | # message file. If the hook fails with a non-zero status, 8 | # the commit is aborted. 9 | # 10 | # To enable this hook, rename this file to "prepare-commit-msg". 11 | 12 | # This hook includes three examples. The first comments out the 13 | # "Conflicts:" part of a merge commit. 14 | # 15 | # The second includes the output of "git diff --name-status -r" 16 | # into the message, just before the "git status" output. It is 17 | # commented because it doesn't cope with --amend or with squashed 18 | # commits. 19 | # 20 | # The third example adds a Signed-off-by line to the message, that can 21 | # still be edited. This is rarely a good idea. 22 | 23 | case "$2,$3" in 24 | merge,) 25 | /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; 26 | 27 | # ,|template,) 28 | # /usr/bin/perl -i.bak -pe ' 29 | # print "\n" . `git diff --cached --name-status -r` 30 | # if /^#/ && $first++ == 0' "$1" ;; 31 | 32 | *) ;; 33 | esac 34 | 35 | # SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') 36 | # grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" 37 | -------------------------------------------------------------------------------- /test/sampleTestData/git/hooks/update.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # An example hook script to block unannotated tags from entering. 4 | # Called by "git receive-pack" with arguments: refname sha1-old sha1-new 5 | # 6 | # To enable this hook, rename this file to "update". 7 | # 8 | # Config 9 | # ------ 10 | # hooks.allowunannotated 11 | # This boolean sets whether unannotated tags will be allowed into the 12 | # repository. By default they won't be. 13 | # hooks.allowdeletetag 14 | # This boolean sets whether deleting tags will be allowed in the 15 | # repository. By default they won't be. 16 | # hooks.allowmodifytag 17 | # This boolean sets whether a tag may be modified after creation. By default 18 | # it won't be. 19 | # hooks.allowdeletebranch 20 | # This boolean sets whether deleting branches will be allowed in the 21 | # repository. By default they won't be. 22 | # hooks.denycreatebranch 23 | # This boolean sets whether remotely creating branches will be denied 24 | # in the repository. By default this is allowed. 25 | # 26 | 27 | # --- Command line 28 | refname="$1" 29 | oldrev="$2" 30 | newrev="$3" 31 | 32 | # --- Safety check 33 | if [ -z "$GIT_DIR" ]; then 34 | echo "Don't run this script from the command line." >&2 35 | echo " (if you want, you could supply GIT_DIR then run" >&2 36 | echo " $0 )" >&2 37 | exit 1 38 | fi 39 | 40 | if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then 41 | echo "usage: $0 " >&2 42 | exit 1 43 | fi 44 | 45 | # --- Config 46 | allowunannotated=$(git config --bool hooks.allowunannotated) 47 | allowdeletebranch=$(git config --bool hooks.allowdeletebranch) 48 | denycreatebranch=$(git config --bool hooks.denycreatebranch) 49 | allowdeletetag=$(git config --bool hooks.allowdeletetag) 50 | allowmodifytag=$(git config --bool hooks.allowmodifytag) 51 | 52 | # check for no description 53 | projectdesc=$(sed -e '1q' "$GIT_DIR/description") 54 | case "$projectdesc" in 55 | "Unnamed repository"* | "") 56 | echo "*** Project description file hasn't been set" >&2 57 | exit 1 58 | ;; 59 | esac 60 | 61 | # --- Check types 62 | # if $newrev is 0000...0000, it's a commit to delete a ref. 63 | zero="0000000000000000000000000000000000000000" 64 | if [ "$newrev" = "$zero" ]; then 65 | newrev_type=delete 66 | else 67 | newrev_type=$(git cat-file -t $newrev) 68 | fi 69 | 70 | case "$refname","$newrev_type" in 71 | refs/tags/*,commit) 72 | # un-annotated tag 73 | short_refname=${refname##refs/tags/} 74 | if [ "$allowunannotated" != "true" ]; then 75 | echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 76 | echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 77 | exit 1 78 | fi 79 | ;; 80 | refs/tags/*,delete) 81 | # delete tag 82 | if [ "$allowdeletetag" != "true" ]; then 83 | echo "*** Deleting a tag is not allowed in this repository" >&2 84 | exit 1 85 | fi 86 | ;; 87 | refs/tags/*,tag) 88 | # annotated tag 89 | if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 90 | then 91 | echo "*** Tag '$refname' already exists." >&2 92 | echo "*** Modifying a tag is not allowed in this repository." >&2 93 | exit 1 94 | fi 95 | ;; 96 | refs/heads/*,commit) 97 | # branch 98 | if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then 99 | echo "*** Creating a branch is not allowed in this repository" >&2 100 | exit 1 101 | fi 102 | ;; 103 | refs/heads/*,delete) 104 | # delete branch 105 | if [ "$allowdeletebranch" != "true" ]; then 106 | echo "*** Deleting a branch is not allowed in this repository" >&2 107 | exit 1 108 | fi 109 | ;; 110 | refs/remotes/*,commit) 111 | # tracking branch 112 | ;; 113 | refs/remotes/*,delete) 114 | # delete tracking branch 115 | if [ "$allowdeletebranch" != "true" ]; then 116 | echo "*** Deleting a tracking branch is not allowed in this repository" >&2 117 | exit 1 118 | fi 119 | ;; 120 | *) 121 | # Anything else (is there anything else?) 122 | echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 123 | exit 1 124 | ;; 125 | esac 126 | 127 | # --- Finished 128 | exit 0 129 | -------------------------------------------------------------------------------- /test/sampleTestData/git/index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugthesystem/vscode-open-in-github/b9f69fe06c3541d12f0f6d07f852733aa4c0d5e4/test/sampleTestData/git/index -------------------------------------------------------------------------------- /test/sampleTestData/git/info/exclude: -------------------------------------------------------------------------------- 1 | # git ls-files --others --exclude-from=.git/info/exclude 2 | # Lines that start with '#' are comments. 3 | # For a project mostly in C, the following would be a good set of 4 | # exclude patterns (uncomment them if you want to use them): 5 | # *.[oa] 6 | # *~ 7 | -------------------------------------------------------------------------------- /test/sampleTestData/git/logs/HEAD: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 fdd74783a03fa7c83242da104c53221e2982f1b2 Grzegorz Dziadkiewicz 1471518020 +0200 commit (initial): Initial commit 2 | fdd74783a03fa7c83242da104c53221e2982f1b2 a8a663582e191d2572dc5132ad8b971de9acc548 Grzegorz Dziadkiewicz 1471518950 +0200 commit: a 3 | a8a663582e191d2572dc5132ad8b971de9acc548 fdd74783a03fa7c83242da104c53221e2982f1b2 Grzegorz Dziadkiewicz 1471518963 +0200 reset: moving to fdd74783a03fa7c83242da104c53221e2982f1b2 4 | fdd74783a03fa7c83242da104c53221e2982f1b2 a9b854f5131a863ad47d3b6c6bbca8cd17a8aff3 Grzegorz Dziadkiewicz 1471518984 +0200 commit: Add dir 5 | -------------------------------------------------------------------------------- /test/sampleTestData/git/logs/refs/heads/master: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 fdd74783a03fa7c83242da104c53221e2982f1b2 Grzegorz Dziadkiewicz 1471518020 +0200 commit (initial): Initial commit 2 | fdd74783a03fa7c83242da104c53221e2982f1b2 a8a663582e191d2572dc5132ad8b971de9acc548 Grzegorz Dziadkiewicz 1471518950 +0200 commit: a 3 | a8a663582e191d2572dc5132ad8b971de9acc548 fdd74783a03fa7c83242da104c53221e2982f1b2 Grzegorz Dziadkiewicz 1471518963 +0200 reset: moving to fdd74783a03fa7c83242da104c53221e2982f1b2 4 | fdd74783a03fa7c83242da104c53221e2982f1b2 a9b854f5131a863ad47d3b6c6bbca8cd17a8aff3 Grzegorz Dziadkiewicz 1471518984 +0200 commit: Add dir 5 | -------------------------------------------------------------------------------- /test/sampleTestData/git/logs/refs/heads/testBranch: -------------------------------------------------------------------------------- 1 | 0000000000000000000000000000000000000000 a9b854f5131a863ad47d3b6c6bbca8cd17a8aff3 Grzegorz Dziadkiewicz 1471518991 +0200 branch: Created from master 2 | -------------------------------------------------------------------------------- /test/sampleTestData/git/objects/32/bd28a61810faf925d58b96aa0c32946b76c271: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugthesystem/vscode-open-in-github/b9f69fe06c3541d12f0f6d07f852733aa4c0d5e4/test/sampleTestData/git/objects/32/bd28a61810faf925d58b96aa0c32946b76c271 -------------------------------------------------------------------------------- /test/sampleTestData/git/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904: -------------------------------------------------------------------------------- 1 | x+)JMU0` 2 | , -------------------------------------------------------------------------------- /test/sampleTestData/git/objects/72/4b5664b66d8d8cc8d859accca1050abc7650a2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugthesystem/vscode-open-in-github/b9f69fe06c3541d12f0f6d07f852733aa4c0d5e4/test/sampleTestData/git/objects/72/4b5664b66d8d8cc8d859accca1050abc7650a2 -------------------------------------------------------------------------------- /test/sampleTestData/git/objects/a8/a663582e191d2572dc5132ad8b971de9acc548: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugthesystem/vscode-open-in-github/b9f69fe06c3541d12f0f6d07f852733aa4c0d5e4/test/sampleTestData/git/objects/a8/a663582e191d2572dc5132ad8b971de9acc548 -------------------------------------------------------------------------------- /test/sampleTestData/git/objects/a9/b854f5131a863ad47d3b6c6bbca8cd17a8aff3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugthesystem/vscode-open-in-github/b9f69fe06c3541d12f0f6d07f852733aa4c0d5e4/test/sampleTestData/git/objects/a9/b854f5131a863ad47d3b6c6bbca8cd17a8aff3 -------------------------------------------------------------------------------- /test/sampleTestData/git/objects/ea/5a519e3d2b5bae1075642c436b1eba917d31d8: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugthesystem/vscode-open-in-github/b9f69fe06c3541d12f0f6d07f852733aa4c0d5e4/test/sampleTestData/git/objects/ea/5a519e3d2b5bae1075642c436b1eba917d31d8 -------------------------------------------------------------------------------- /test/sampleTestData/git/objects/fd/d74783a03fa7c83242da104c53221e2982f1b2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugthesystem/vscode-open-in-github/b9f69fe06c3541d12f0f6d07f852733aa4c0d5e4/test/sampleTestData/git/objects/fd/d74783a03fa7c83242da104c53221e2982f1b2 -------------------------------------------------------------------------------- /test/sampleTestData/git/refs/heads/master: -------------------------------------------------------------------------------- 1 | a9b854f5131a863ad47d3b6c6bbca8cd17a8aff3 2 | -------------------------------------------------------------------------------- /test/sampleTestData/git/refs/heads/testBranch: -------------------------------------------------------------------------------- 1 | a9b854f5131a863ad47d3b6c6bbca8cd17a8aff3 2 | -------------------------------------------------------------------------------- /test/sampleTestData/sampleDirectory/sampleTestFile.txt: -------------------------------------------------------------------------------- 1 | AAA 2 | BBB 3 | CCC -------------------------------------------------------------------------------- /testScript.js: -------------------------------------------------------------------------------- 1 | function call(command, args) { 2 | var util = require('util'), 3 | spawn = require('child_process').spawn, 4 | cp = spawn(command, args); 5 | 6 | cp.stdout.on('data', function (data) { 7 | console.log(data.toString()); 8 | }); 9 | 10 | cp.stderr.on('data', function (data) { 11 | console.log(data.toString()); 12 | }); 13 | 14 | cp.on('exit', function (code) { 15 | return process.exit(code); 16 | }); 17 | } 18 | 19 | if(process.platform === "win32") { 20 | call("npm.cmd", ["run", "test:windows"]); 21 | } 22 | else { 23 | call("npm", ["run", "test:linuxOSX"]); 24 | } 25 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "outDir": "out", 6 | "lib": [ 7 | "es6" 8 | ], 9 | "sourceMap": true 10 | }, 11 | "exclude": [ 12 | "node_modules", 13 | ".vscode-test" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /typings/tsd.d.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bugthesystem/vscode-open-in-github/b9f69fe06c3541d12f0f6d07f852733aa4c0d5e4/typings/tsd.d.ts -------------------------------------------------------------------------------- /typings/vscode-typings.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@types/chai@^4.1.7": 6 | version "4.1.7" 7 | resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.1.7.tgz#1b8e33b61a8c09cbe1f85133071baa0dbf9fa71a" 8 | integrity sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA== 9 | 10 | "@types/node@^10.12.5": 11 | version "10.12.5" 12 | resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.5.tgz#7e7ea1a9b34d2c8d704cb0b755dffbcda34741ad" 13 | integrity sha512-GzdHjq3t3eGLMv92Al90Iq+EoLL+86mPfQhuglbBFO7HiLdC/rkt+zrzJJumAiBF6nsrBWhou22rPW663AAyFw== 14 | 15 | "@types/proxyquire@^1.3.28": 16 | version "1.3.28" 17 | resolved "https://registry.yarnpkg.com/@types/proxyquire/-/proxyquire-1.3.28.tgz#05a647bb0d8fe48fc8edcc193e43cc79310faa7d" 18 | integrity sha512-SQaNzWQ2YZSr7FqAyPPiA3FYpux2Lqh3HWMZQk47x3xbMCqgC/w0dY3dw9rGqlweDDkrySQBcaScXWeR+Yb11Q== 19 | 20 | agent-base@4, agent-base@^4.3.0: 21 | version "4.3.0" 22 | resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" 23 | integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== 24 | dependencies: 25 | es6-promisify "^5.0.0" 26 | 27 | ajv@^6.5.5: 28 | version "6.12.6" 29 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" 30 | integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== 31 | dependencies: 32 | fast-deep-equal "^3.1.1" 33 | fast-json-stable-stringify "^2.0.0" 34 | json-schema-traverse "^0.4.1" 35 | uri-js "^4.2.2" 36 | 37 | asn1@~0.2.3: 38 | version "0.2.4" 39 | resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" 40 | integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== 41 | dependencies: 42 | safer-buffer "~2.1.0" 43 | 44 | assert-plus@1.0.0, assert-plus@^1.0.0: 45 | version "1.0.0" 46 | resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" 47 | integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= 48 | 49 | assertion-error@^1.1.0: 50 | version "1.1.0" 51 | resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" 52 | integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== 53 | 54 | asynckit@^0.4.0: 55 | version "0.4.0" 56 | resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" 57 | integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= 58 | 59 | aws-sign2@~0.7.0: 60 | version "0.7.0" 61 | resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" 62 | integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= 63 | 64 | aws4@^1.8.0: 65 | version "1.8.0" 66 | resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" 67 | integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== 68 | 69 | balanced-match@^1.0.0: 70 | version "1.0.0" 71 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 72 | integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= 73 | 74 | bcrypt-pbkdf@^1.0.0: 75 | version "1.0.2" 76 | resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" 77 | integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= 78 | dependencies: 79 | tweetnacl "^0.14.3" 80 | 81 | brace-expansion@^1.1.7: 82 | version "1.1.11" 83 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 84 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 85 | dependencies: 86 | balanced-match "^1.0.0" 87 | concat-map "0.0.1" 88 | 89 | browser-stdout@1.3.1: 90 | version "1.3.1" 91 | resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" 92 | integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== 93 | 94 | buffer-from@^1.0.0: 95 | version "1.1.1" 96 | resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" 97 | integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== 98 | 99 | caseless@~0.12.0: 100 | version "0.12.0" 101 | resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" 102 | integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= 103 | 104 | chai@^4.2.0: 105 | version "4.2.0" 106 | resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5" 107 | integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw== 108 | dependencies: 109 | assertion-error "^1.1.0" 110 | check-error "^1.0.2" 111 | deep-eql "^3.0.1" 112 | get-func-name "^2.0.0" 113 | pathval "^1.1.0" 114 | type-detect "^4.0.5" 115 | 116 | check-error@^1.0.2: 117 | version "1.0.2" 118 | resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" 119 | integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= 120 | 121 | combined-stream@^1.0.6, combined-stream@~1.0.6: 122 | version "1.0.8" 123 | resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" 124 | integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== 125 | dependencies: 126 | delayed-stream "~1.0.0" 127 | 128 | commander@2.15.1: 129 | version "2.15.1" 130 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" 131 | integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== 132 | 133 | concat-map@0.0.1: 134 | version "0.0.1" 135 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 136 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 137 | 138 | copy-paste@^1.3.0: 139 | version "1.3.0" 140 | resolved "https://registry.yarnpkg.com/copy-paste/-/copy-paste-1.3.0.tgz#a7e6c4a1c28fdedf2b081e72b97df2ef95f471ed" 141 | integrity sha1-p+bEocKP3t8rCB5yuX3y75X0ce0= 142 | dependencies: 143 | iconv-lite "^0.4.8" 144 | optionalDependencies: 145 | sync-exec "~0.6.x" 146 | 147 | core-util-is@1.0.2: 148 | version "1.0.2" 149 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 150 | integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= 151 | 152 | dashdash@^1.12.0: 153 | version "1.14.1" 154 | resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" 155 | integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= 156 | dependencies: 157 | assert-plus "^1.0.0" 158 | 159 | debug@3.1.0: 160 | version "3.1.0" 161 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" 162 | integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== 163 | dependencies: 164 | ms "2.0.0" 165 | 166 | debug@^3.1.0: 167 | version "3.2.6" 168 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" 169 | integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== 170 | dependencies: 171 | ms "^2.1.1" 172 | 173 | deep-eql@^3.0.1: 174 | version "3.0.1" 175 | resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" 176 | integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== 177 | dependencies: 178 | type-detect "^4.0.0" 179 | 180 | delayed-stream@~1.0.0: 181 | version "1.0.0" 182 | resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" 183 | integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= 184 | 185 | diff@3.5.0: 186 | version "3.5.0" 187 | resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" 188 | integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== 189 | 190 | ecc-jsbn@~0.1.1: 191 | version "0.1.2" 192 | resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" 193 | integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= 194 | dependencies: 195 | jsbn "~0.1.0" 196 | safer-buffer "^2.1.0" 197 | 198 | es6-promise@^4.0.3: 199 | version "4.2.8" 200 | resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" 201 | integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== 202 | 203 | es6-promisify@^5.0.0: 204 | version "5.0.0" 205 | resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" 206 | integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= 207 | dependencies: 208 | es6-promise "^4.0.3" 209 | 210 | escape-string-regexp@1.0.5: 211 | version "1.0.5" 212 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 213 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= 214 | 215 | extend@~3.0.2: 216 | version "3.0.2" 217 | resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" 218 | integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== 219 | 220 | extsprintf@1.3.0: 221 | version "1.3.0" 222 | resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" 223 | integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= 224 | 225 | extsprintf@^1.2.0: 226 | version "1.4.0" 227 | resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" 228 | integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= 229 | 230 | fast-deep-equal@^3.1.1: 231 | version "3.1.3" 232 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" 233 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== 234 | 235 | fast-json-stable-stringify@^2.0.0: 236 | version "2.1.0" 237 | resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" 238 | integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== 239 | 240 | fill-keys@^1.0.2: 241 | version "1.0.2" 242 | resolved "https://registry.yarnpkg.com/fill-keys/-/fill-keys-1.0.2.tgz#9a8fa36f4e8ad634e3bf6b4f3c8882551452eb20" 243 | dependencies: 244 | is-object "~1.0.1" 245 | merge-descriptors "~1.0.0" 246 | 247 | find-parent-dir@^0.3.0: 248 | version "0.3.0" 249 | resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54" 250 | integrity sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ= 251 | 252 | forever-agent@~0.6.1: 253 | version "0.6.1" 254 | resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" 255 | integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= 256 | 257 | form-data@~2.3.2: 258 | version "2.3.3" 259 | resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" 260 | integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== 261 | dependencies: 262 | asynckit "^0.4.0" 263 | combined-stream "^1.0.6" 264 | mime-types "^2.1.12" 265 | 266 | fs.realpath@^1.0.0: 267 | version "1.0.0" 268 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 269 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 270 | 271 | get-func-name@^2.0.0: 272 | version "2.0.2" 273 | resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41" 274 | integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== 275 | 276 | getpass@^0.1.1: 277 | version "0.1.7" 278 | resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" 279 | integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= 280 | dependencies: 281 | assert-plus "^1.0.0" 282 | 283 | git-rev-2@^0.1.0: 284 | version "0.1.0" 285 | resolved "https://registry.yarnpkg.com/git-rev-2/-/git-rev-2-0.1.0.tgz#748165a8c84fb01ea67467ff15ab3e37ace4064c" 286 | integrity sha1-dIFlqMhPsB6mdGf/Fas+N6zkBkw= 287 | 288 | git-up@^4.0.0: 289 | version "4.0.1" 290 | resolved "https://registry.yarnpkg.com/git-up/-/git-up-4.0.1.tgz#cb2ef086653640e721d2042fe3104857d89007c0" 291 | integrity sha512-LFTZZrBlrCrGCG07/dm1aCjjpL1z9L3+5aEeI9SBhAqSc+kiA9Or1bgZhQFNppJX6h/f5McrvJt1mQXTFm6Qrw== 292 | dependencies: 293 | is-ssh "^1.3.0" 294 | parse-url "^5.0.0" 295 | 296 | git-url-parse@^11.1.1: 297 | version "11.1.2" 298 | resolved "https://registry.yarnpkg.com/git-url-parse/-/git-url-parse-11.1.2.tgz#aff1a897c36cc93699270587bea3dbcbbb95de67" 299 | integrity sha512-gZeLVGY8QVKMIkckncX+iCq2/L8PlwncvDFKiWkBn9EtCfYDbliRTTp6qzyQ1VMdITUfq7293zDzfpjdiGASSQ== 300 | dependencies: 301 | git-up "^4.0.0" 302 | 303 | glob@7.1.2: 304 | version "7.1.2" 305 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" 306 | integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== 307 | dependencies: 308 | fs.realpath "^1.0.0" 309 | inflight "^1.0.4" 310 | inherits "2" 311 | minimatch "^3.0.4" 312 | once "^1.3.0" 313 | path-is-absolute "^1.0.0" 314 | 315 | glob@^7.1.2: 316 | version "7.1.4" 317 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" 318 | integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== 319 | dependencies: 320 | fs.realpath "^1.0.0" 321 | inflight "^1.0.4" 322 | inherits "2" 323 | minimatch "^3.0.4" 324 | once "^1.3.0" 325 | path-is-absolute "^1.0.0" 326 | 327 | growl@1.10.5: 328 | version "1.10.5" 329 | resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" 330 | integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== 331 | 332 | har-schema@^2.0.0: 333 | version "2.0.0" 334 | resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" 335 | integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= 336 | 337 | har-validator@~5.1.0: 338 | version "5.1.3" 339 | resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" 340 | integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== 341 | dependencies: 342 | ajv "^6.5.5" 343 | har-schema "^2.0.0" 344 | 345 | has-flag@^3.0.0: 346 | version "3.0.0" 347 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 348 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= 349 | 350 | he@1.1.1: 351 | version "1.1.1" 352 | resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" 353 | integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= 354 | 355 | http-proxy-agent@^2.1.0: 356 | version "2.1.0" 357 | resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" 358 | integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg== 359 | dependencies: 360 | agent-base "4" 361 | debug "3.1.0" 362 | 363 | http-signature@~1.2.0: 364 | version "1.2.0" 365 | resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" 366 | integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= 367 | dependencies: 368 | assert-plus "^1.0.0" 369 | jsprim "^1.2.2" 370 | sshpk "^1.7.0" 371 | 372 | https-proxy-agent@^2.2.1: 373 | version "2.2.4" 374 | resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b" 375 | integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg== 376 | dependencies: 377 | agent-base "^4.3.0" 378 | debug "^3.1.0" 379 | 380 | iconv-lite@^0.4.8: 381 | version "0.4.15" 382 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb" 383 | 384 | inflight@^1.0.4: 385 | version "1.0.6" 386 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 387 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 388 | dependencies: 389 | once "^1.3.0" 390 | wrappy "1" 391 | 392 | inherits@2: 393 | version "2.0.4" 394 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 395 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 396 | 397 | ini@^1.3.3: 398 | version "1.3.7" 399 | resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.7.tgz#a09363e1911972ea16d7a8851005d84cf09a9a84" 400 | integrity sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ== 401 | 402 | is-object@~1.0.1: 403 | version "1.0.1" 404 | resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" 405 | 406 | is-ssh@^1.3.0: 407 | version "1.3.0" 408 | resolved "https://registry.yarnpkg.com/is-ssh/-/is-ssh-1.3.0.tgz#ebea1169a2614da392a63740366c3ce049d8dff6" 409 | dependencies: 410 | protocols "^1.1.0" 411 | 412 | is-typedarray@~1.0.0: 413 | version "1.0.0" 414 | resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" 415 | integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= 416 | 417 | is-wsl@^1.1.0: 418 | version "1.1.0" 419 | resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" 420 | integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= 421 | 422 | isstream@~0.1.2: 423 | version "0.1.2" 424 | resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" 425 | integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= 426 | 427 | jsbn@~0.1.0: 428 | version "0.1.1" 429 | resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" 430 | integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= 431 | 432 | json-schema-traverse@^0.4.1: 433 | version "0.4.1" 434 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" 435 | integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== 436 | 437 | json-schema@0.2.3: 438 | version "0.2.3" 439 | resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" 440 | integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= 441 | 442 | json-stringify-safe@~5.0.1: 443 | version "5.0.1" 444 | resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" 445 | integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= 446 | 447 | jsprim@^1.2.2: 448 | version "1.4.1" 449 | resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" 450 | integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= 451 | dependencies: 452 | assert-plus "1.0.0" 453 | extsprintf "1.3.0" 454 | json-schema "0.2.3" 455 | verror "1.10.0" 456 | 457 | merge-descriptors@~1.0.0: 458 | version "1.0.1" 459 | resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" 460 | 461 | mime-db@1.40.0: 462 | version "1.40.0" 463 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" 464 | integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA== 465 | 466 | mime-types@^2.1.12, mime-types@~2.1.19: 467 | version "2.1.24" 468 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81" 469 | integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ== 470 | dependencies: 471 | mime-db "1.40.0" 472 | 473 | minimatch@3.0.4, minimatch@^3.0.4: 474 | version "3.0.4" 475 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 476 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 477 | dependencies: 478 | brace-expansion "^1.1.7" 479 | 480 | minimist@0.0.8: 481 | version "0.0.8" 482 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" 483 | integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= 484 | 485 | mkdirp@0.5.1: 486 | version "0.5.1" 487 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" 488 | integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= 489 | dependencies: 490 | minimist "0.0.8" 491 | 492 | mocha@^5.2.0: 493 | version "5.2.0" 494 | resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" 495 | integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ== 496 | dependencies: 497 | browser-stdout "1.3.1" 498 | commander "2.15.1" 499 | debug "3.1.0" 500 | diff "3.5.0" 501 | escape-string-regexp "1.0.5" 502 | glob "7.1.2" 503 | growl "1.10.5" 504 | he "1.1.1" 505 | minimatch "3.0.4" 506 | mkdirp "0.5.1" 507 | supports-color "5.4.0" 508 | 509 | module-not-found-error@^1.0.0: 510 | version "1.0.1" 511 | resolved "https://registry.yarnpkg.com/module-not-found-error/-/module-not-found-error-1.0.1.tgz#cf8b4ff4f29640674d6cdd02b0e3bc523c2bbdc0" 512 | 513 | ms@2.0.0: 514 | version "2.0.0" 515 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 516 | integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= 517 | 518 | ms@^2.1.1: 519 | version "2.1.2" 520 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 521 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 522 | 523 | normalize-url@^3.3.0: 524 | version "3.3.0" 525 | resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" 526 | integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== 527 | 528 | oauth-sign@~0.9.0: 529 | version "0.9.0" 530 | resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" 531 | integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== 532 | 533 | once@^1.3.0: 534 | version "1.4.0" 535 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 536 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 537 | dependencies: 538 | wrappy "1" 539 | 540 | open@6.0.0: 541 | version "6.0.0" 542 | resolved "https://registry.yarnpkg.com/open/-/open-6.0.0.tgz#cae5e2c1a3a1bfaee0d0acc8c4b7609374750346" 543 | integrity sha512-/yb5mVZBz7mHLySMiSj2DcLtMBbFPJk5JBKEkHVZFxZAPzeg3L026O0T+lbdz1B2nyDnkClRSwRQJdeVUIF7zw== 544 | dependencies: 545 | is-wsl "^1.1.0" 546 | 547 | parse-git-config@^0.3.1: 548 | version "0.3.2" 549 | resolved "https://registry.yarnpkg.com/parse-git-config/-/parse-git-config-0.3.2.tgz#47373337e0afcffce4ecdd7b6888511af11fb60b" 550 | dependencies: 551 | ini "^1.3.3" 552 | 553 | parse-path@^4.0.0: 554 | version "4.0.1" 555 | resolved "https://registry.yarnpkg.com/parse-path/-/parse-path-4.0.1.tgz#0ec769704949778cb3b8eda5e994c32073a1adff" 556 | integrity sha512-d7yhga0Oc+PwNXDvQ0Jv1BuWkLVPXcAoQ/WREgd6vNNoKYaW52KI+RdOFjI63wjkmps9yUE8VS4veP+AgpQ/hA== 557 | dependencies: 558 | is-ssh "^1.3.0" 559 | protocols "^1.4.0" 560 | 561 | parse-url@^5.0.0: 562 | version "5.0.1" 563 | resolved "https://registry.yarnpkg.com/parse-url/-/parse-url-5.0.1.tgz#99c4084fc11be14141efa41b3d117a96fcb9527f" 564 | integrity sha512-flNUPP27r3vJpROi0/R3/2efgKkyXqnXwyP1KQ2U0SfFRgdizOdWfvrrvJg1LuOoxs7GQhmxJlq23IpQ/BkByg== 565 | dependencies: 566 | is-ssh "^1.3.0" 567 | normalize-url "^3.3.0" 568 | parse-path "^4.0.0" 569 | protocols "^1.4.0" 570 | 571 | path-is-absolute@^1.0.0: 572 | version "1.0.1" 573 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 574 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 575 | 576 | path-parse@^1.0.5: 577 | version "1.0.7" 578 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" 579 | integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== 580 | 581 | pathval@^1.1.0: 582 | version "1.1.1" 583 | resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" 584 | integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== 585 | 586 | performance-now@^2.1.0: 587 | version "2.1.0" 588 | resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" 589 | integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= 590 | 591 | protocols@^1.1.0, protocols@^1.4.0: 592 | version "1.4.5" 593 | resolved "https://registry.yarnpkg.com/protocols/-/protocols-1.4.5.tgz#21de1f441c4ef7094408ed9f1c94f7a114b87557" 594 | 595 | proxyquire@^2.1.0: 596 | version "2.1.0" 597 | resolved "https://registry.yarnpkg.com/proxyquire/-/proxyquire-2.1.0.tgz#c2263a38bf0725f2ae950facc130e27510edce8d" 598 | integrity sha512-kptdFArCfGRtQFv3Qwjr10lwbEV0TBJYvfqzhwucyfEXqVgmnAkyEw/S3FYzR5HI9i5QOq4rcqQjZ6AlknlCDQ== 599 | dependencies: 600 | fill-keys "^1.0.2" 601 | module-not-found-error "^1.0.0" 602 | resolve "~1.8.1" 603 | 604 | psl@^1.1.24: 605 | version "1.3.0" 606 | resolved "https://registry.yarnpkg.com/psl/-/psl-1.3.0.tgz#e1ebf6a3b5564fa8376f3da2275da76d875ca1bd" 607 | integrity sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag== 608 | 609 | punycode@^1.4.1: 610 | version "1.4.1" 611 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" 612 | integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= 613 | 614 | punycode@^2.1.0: 615 | version "2.1.1" 616 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" 617 | integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== 618 | 619 | qs@~6.5.2: 620 | version "6.5.3" 621 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" 622 | integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== 623 | 624 | querystringify@^2.1.1: 625 | version "2.2.0" 626 | resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" 627 | integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== 628 | 629 | request@^2.88.0: 630 | version "2.88.0" 631 | resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" 632 | integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== 633 | dependencies: 634 | aws-sign2 "~0.7.0" 635 | aws4 "^1.8.0" 636 | caseless "~0.12.0" 637 | combined-stream "~1.0.6" 638 | extend "~3.0.2" 639 | forever-agent "~0.6.1" 640 | form-data "~2.3.2" 641 | har-validator "~5.1.0" 642 | http-signature "~1.2.0" 643 | is-typedarray "~1.0.0" 644 | isstream "~0.1.2" 645 | json-stringify-safe "~5.0.1" 646 | mime-types "~2.1.19" 647 | oauth-sign "~0.9.0" 648 | performance-now "^2.1.0" 649 | qs "~6.5.2" 650 | safe-buffer "^5.1.2" 651 | tough-cookie "~2.4.3" 652 | tunnel-agent "^0.6.0" 653 | uuid "^3.3.2" 654 | 655 | requires-port@^1.0.0: 656 | version "1.0.0" 657 | resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" 658 | integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= 659 | 660 | resolve@~1.8.1: 661 | version "1.8.1" 662 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" 663 | integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA== 664 | dependencies: 665 | path-parse "^1.0.5" 666 | 667 | safe-buffer@^5.0.1, safe-buffer@^5.1.2: 668 | version "5.2.0" 669 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" 670 | integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== 671 | 672 | safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: 673 | version "2.1.2" 674 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 675 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== 676 | 677 | semver@^5.4.1: 678 | version "5.7.2" 679 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" 680 | integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== 681 | 682 | source-map-support@^0.5.0: 683 | version "0.5.13" 684 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" 685 | integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== 686 | dependencies: 687 | buffer-from "^1.0.0" 688 | source-map "^0.6.0" 689 | 690 | source-map@^0.6.0: 691 | version "0.6.1" 692 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 693 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== 694 | 695 | sshpk@^1.7.0: 696 | version "1.16.1" 697 | resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" 698 | integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== 699 | dependencies: 700 | asn1 "~0.2.3" 701 | assert-plus "^1.0.0" 702 | bcrypt-pbkdf "^1.0.0" 703 | dashdash "^1.12.0" 704 | ecc-jsbn "~0.1.1" 705 | getpass "^0.1.1" 706 | jsbn "~0.1.0" 707 | safer-buffer "^2.0.2" 708 | tweetnacl "~0.14.0" 709 | 710 | supports-color@5.4.0: 711 | version "5.4.0" 712 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" 713 | integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w== 714 | dependencies: 715 | has-flag "^3.0.0" 716 | 717 | sync-exec@~0.6.x: 718 | version "0.6.2" 719 | resolved "https://registry.yarnpkg.com/sync-exec/-/sync-exec-0.6.2.tgz#717d22cc53f0ce1def5594362f3a89a2ebb91105" 720 | 721 | tough-cookie@~2.4.3: 722 | version "2.4.3" 723 | resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" 724 | integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== 725 | dependencies: 726 | psl "^1.1.24" 727 | punycode "^1.4.1" 728 | 729 | tunnel-agent@^0.6.0: 730 | version "0.6.0" 731 | resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" 732 | integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= 733 | dependencies: 734 | safe-buffer "^5.0.1" 735 | 736 | tweetnacl@^0.14.3, tweetnacl@~0.14.0: 737 | version "0.14.5" 738 | resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" 739 | integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= 740 | 741 | type-detect@^4.0.0, type-detect@^4.0.5: 742 | version "4.0.8" 743 | resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" 744 | integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== 745 | 746 | typescript@^3.1.6: 747 | version "3.1.6" 748 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.6.tgz#b6543a83cfc8c2befb3f4c8fba6896f5b0c9be68" 749 | integrity sha512-tDMYfVtvpb96msS1lDX9MEdHrW4yOuZ4Kdc4Him9oU796XldPYF/t2+uKoX0BBa0hXXwDlqYQbXY5Rzjzc5hBA== 750 | 751 | uri-js@^4.2.2: 752 | version "4.4.1" 753 | resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" 754 | integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== 755 | dependencies: 756 | punycode "^2.1.0" 757 | 758 | url-parse@^1.4.4: 759 | version "1.5.10" 760 | resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" 761 | integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== 762 | dependencies: 763 | querystringify "^2.1.1" 764 | requires-port "^1.0.0" 765 | 766 | uuid@^3.3.2: 767 | version "3.3.2" 768 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" 769 | integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== 770 | 771 | verror@1.10.0: 772 | version "1.10.0" 773 | resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" 774 | integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= 775 | dependencies: 776 | assert-plus "^1.0.0" 777 | core-util-is "1.0.2" 778 | extsprintf "^1.2.0" 779 | 780 | vscode-test@^0.4.1: 781 | version "0.4.3" 782 | resolved "https://registry.yarnpkg.com/vscode-test/-/vscode-test-0.4.3.tgz#461ebf25fc4bc93d77d982aed556658a2e2b90b8" 783 | integrity sha512-EkMGqBSefZH2MgW65nY05rdRSko15uvzq4VAPM5jVmwYuFQKE7eikKXNJDRxL+OITXHB6pI+a3XqqD32Y3KC5w== 784 | dependencies: 785 | http-proxy-agent "^2.1.0" 786 | https-proxy-agent "^2.2.1" 787 | 788 | vscode@^1.1.21: 789 | version "1.1.36" 790 | resolved "https://registry.yarnpkg.com/vscode/-/vscode-1.1.36.tgz#5e1a0d1bf4977d0c7bc5159a9a13d5b104d4b1b6" 791 | integrity sha512-cGFh9jmGLcTapCpPCKvn8aG/j9zVQ+0x5hzYJq5h5YyUXVGa1iamOaB2M2PZXoumQPES4qeAP1FwkI0b6tL4bQ== 792 | dependencies: 793 | glob "^7.1.2" 794 | mocha "^5.2.0" 795 | request "^2.88.0" 796 | semver "^5.4.1" 797 | source-map-support "^0.5.0" 798 | url-parse "^1.4.4" 799 | vscode-test "^0.4.1" 800 | 801 | wrappy@1: 802 | version "1.0.2" 803 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 804 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 805 | --------------------------------------------------------------------------------