├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE.md ├── .gitignore ├── .vscode ├── .deploy │ ├── embedded_resources.js │ └── resources.js ├── launch.json ├── settings.json └── tasks.json ├── .vscodeignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── _res ├── css │ ├── hl.railscasts.css │ └── style.css ├── html │ ├── footer.html │ └── header.html ├── javascript │ ├── highlight.pack.js │ ├── jquery-2.2.4.min.js │ └── script.js └── rest │ ├── get.api.commands.http │ ├── get.api.editors.http │ ├── get.api.editors.index.content.http │ ├── get.api.editors.index.http │ ├── get.api.http │ ├── get.api.languages.http │ ├── get.extensions.http │ ├── post.api.commands.http │ ├── post.api.editors.http │ ├── post.api.markdown.http │ ├── post.api.messages.http │ └── put.api.output.http ├── copyright.txt ├── icon.png ├── img ├── demo1.gif ├── demo10.gif ├── demo11.gif ├── demo12.gif ├── demo13.gif ├── demo14.gif ├── demo15.gif ├── demo16.gif ├── demo17.gif ├── demo18.gif ├── demo19.gif ├── demo2.gif ├── demo20.gif ├── demo21.gif ├── demo22.gif ├── demo23.gif ├── demo24.gif ├── demo25.gif ├── demo26.gif ├── demo27.gif ├── demo28.gif ├── demo29.gif ├── demo3.gif ├── demo30.gif ├── demo4.gif ├── demo5.gif ├── demo6.gif ├── demo7.gif ├── demo8.gif ├── demo9.gif ├── screenshot1.png └── share │ ├── Email.png │ ├── Facebook.png │ ├── Google+.png │ ├── LinkedIn.png │ ├── Pinboard.png │ ├── Pinterest.png │ ├── Pocket.png │ ├── Reddit.png │ ├── Tumblr.png │ ├── Twitter.png │ └── Wordpress.png ├── package-lock.json ├── package.json ├── src ├── api.ts ├── buttons.ts ├── clients.ts ├── clients │ ├── azureblob.ts │ ├── dropbox.ts │ ├── ftp.ts │ ├── s3bucket.ts │ ├── sftp.ts │ └── slack.ts ├── code.ts ├── commands.ts ├── compare.ts ├── compilers.ts ├── compilers │ ├── coffeescript.ts │ ├── htmlminifier.ts │ ├── less.ts │ ├── pug.ts │ └── uglifyjs.ts ├── contracts.ts ├── delete.ts ├── deploy.ts ├── download.ts ├── extension.ts ├── files.ts ├── git.ts ├── gui.ts ├── helpers.ts ├── html.ts ├── http.ts ├── i18.ts ├── lang │ ├── de-de.ts │ ├── de.ts │ ├── en-gb.ts │ ├── en-us.ts │ └── en.ts ├── list.ts ├── log.ts ├── mappings.ts ├── notifications.ts ├── output.ts ├── packages.ts ├── plugins.ts ├── plugins │ ├── app.ts │ ├── azureblob.ts │ ├── batch.ts │ ├── compiler.ts │ ├── dropbox.ts │ ├── each.ts │ ├── ftp.ts │ ├── list.ts │ ├── local.ts │ ├── mail.ts │ ├── map.ts │ ├── prompt.ts │ ├── s3bucket.ts │ ├── script.ts │ ├── sftp.ts │ ├── slack.ts │ ├── switch.ts │ ├── test.ts │ └── zip.ts ├── proxies.ts ├── pull.ts ├── resources.ts ├── resources │ ├── css.ts │ ├── html.ts │ └── javascript.ts ├── scm.ts ├── sql.ts ├── sql │ ├── mssql.ts │ └── mysql.ts ├── switch.ts ├── sync.ts ├── targets.ts ├── targets │ └── operations │ │ ├── cleanup.ts │ │ ├── command.ts │ │ ├── devtools.ts │ │ ├── exec.ts │ │ ├── http.ts │ │ ├── open.ts │ │ ├── script.ts │ │ ├── slack.ts │ │ ├── sql.ts │ │ └── wait.ts ├── tasks.ts ├── test │ ├── extension.test.ts │ └── index.ts ├── tools.ts ├── tools │ ├── bower.ts │ ├── composer.ts │ ├── npm.ts │ ├── quickexecution.ts │ ├── sendfile.ts │ └── yarn.ts ├── transformers.ts ├── values.ts └── workspaces.ts ├── tsconfig.json └── tslint.json /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: ['https://paypal.me/MarcelKloubert'] 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | ### Description 3 | 4 | {Please write here} 5 | 6 | ### Actual behavior 7 | 8 | {Please write here} 9 | 10 | ### Expected behavior 11 | 12 | {Please write here} 13 | 14 | ### Steps to reproduce 15 | 16 | {Please write here, including precondition and an example config, if possible} 17 | 18 | #### Example config 19 | 20 | ```json 21 | { 22 | "deploy.reloaded": { 23 | // your config 24 | } 25 | } 26 | ``` 27 | 28 | #### Logs 29 | 30 | ``` 31 | // write log messages here, if possible 32 | 33 | // maybe one or more log files are available 34 | // in sub folder '.vscode-deploy-reloaded/.logs' 35 | // inside your home directory 36 | ``` 37 | 38 | #### Screenshot 39 | 40 | {Please write here, if possible} 41 | 42 | ### Your environment 43 | 44 | - Operating system: {Please write here} 45 | - Visual Studio Code version: {Please write here} 46 | - Extension version: {Please write here} 47 | 48 | ### Additional comments 49 | 50 | {Please write here, if there is something more to tell} 51 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | node_modules 3 | .vs 4 | .vscode-test/ 5 | .vsix 6 | /pushall.sh 7 | /typedoc.cmd 8 | /tsdoc 9 | /.vscode/vscode-kanban.json 10 | /.vscode/vscode-kanban.filter 11 | -------------------------------------------------------------------------------- /.vscode/.deploy/resources.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | 19 | exports.LICENSE_HEADER = `/** 20 | * This file is part of the vscode-deploy-reloaded distribution. 21 | * Copyright (c) Marcel Joachim Kloubert. 22 | * 23 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 24 | * it under the terms of the GNU Lesser General Public License as 25 | * published by the Free Software Foundation, version 3. 26 | * 27 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 28 | * WITHOUT ANY WARRANTY; without even the implied warranty of 29 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 30 | * Lesser General Public License for more details. 31 | * 32 | * You should have received a copy of the GNU Lesser General Public License 33 | * along with this program. If not, see . 34 | */ 35 | ` 36 | -------------------------------------------------------------------------------- /.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": "Extension", 7 | "type": "extensionHost", 8 | "request": "launch", 9 | "runtimeExecutable": "${execPath}", 10 | "args": ["--extensionDevelopmentPath=${workspaceRoot}" ], 11 | "stopOnEntry": false, 12 | "sourceMaps": true, 13 | "outFiles": [ "${workspaceRoot}/out/**/*.js" ], 14 | "preLaunchTask": "npm: watch" 15 | }, 16 | { 17 | "name": "Extension Tests", 18 | "type": "extensionHost", 19 | "request": "launch", 20 | "runtimeExecutable": "${execPath}", 21 | "args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test" ], 22 | "stopOnEntry": false, 23 | "sourceMaps": true, 24 | "outFiles": [ "${workspaceRoot}/out/test/**/*.js" ], 25 | "preLaunchTask": "npm: watch" 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /.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 // set this to false to include "out" folder in search results 8 | }, 9 | 10 | "deploy.reloaded": { 11 | "packages": [ 12 | { 13 | "name": "Embedded CSS", 14 | "files": [ 15 | "/_res/css/*.css" 16 | ], 17 | 18 | "targets": [ "Embedded_CSS" ] 19 | }, 20 | { 21 | "name": "Embedded HTML", 22 | "files": [ 23 | "/_res/html/*.html" 24 | ], 25 | 26 | "targets": [ "Embedded_HTML" ] 27 | }, 28 | { 29 | "name": "Embedded JavaScript", 30 | "files": [ 31 | "/_res/javascript/*.js" 32 | ], 33 | 34 | "targets": [ "Embedded_JS" ] 35 | } 36 | ], 37 | 38 | "targets": [ 39 | { 40 | "name": "Embedded_CSS", 41 | 42 | "type": "script", 43 | "script": "./.deploy/embedded_resources.js", 44 | "options": "css" 45 | }, 46 | { 47 | "name": "Embedded_HTML", 48 | 49 | "type": "script", 50 | "script": "./.deploy/embedded_resources.js", 51 | "options": "html" 52 | }, 53 | { 54 | "name": "Embedded_JS", 55 | 56 | "type": "script", 57 | "script": "./.deploy/embedded_resources.js", 58 | "options": "js" 59 | } 60 | ] 61 | }, 62 | 63 | "kanban": { 64 | "openOnStartup": true 65 | } 66 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558 2 | // for the documentation about the tasks.json format 3 | { 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "watch", 9 | "problemMatcher": "$tsc-watch", 10 | "isBackground": true, 11 | "presentation": { 12 | "reveal": "never" 13 | }, 14 | "group": { 15 | "kind": "build", 16 | "isDefault": true 17 | } 18 | }, 19 | { 20 | "type": "npm", 21 | "script": "tslint", 22 | "problemMatcher": { 23 | "base": "$tslint5", 24 | "fileLocation": "relative" 25 | } 26 | } 27 | ] 28 | } -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .github/** 2 | .vscode/** 3 | .vscode-test/** 4 | img/** 5 | out/test/** 6 | out/**/*.map 7 | src/** 8 | tsdoc/** 9 | _res/** 10 | .gitignore 11 | package-lock.json 12 | tsconfig.json 13 | pushall.sh 14 | typedoc.cmd 15 | tslint.json 16 | -------------------------------------------------------------------------------- /_res/css/hl.railscasts.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Railscasts-like style (c) Visoft, Inc. (Damien White) 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | background: #232323; 12 | color: #e6e1dc; 13 | } 14 | 15 | .hljs-comment, 16 | .hljs-quote { 17 | color: #bc9458; 18 | font-style: italic; 19 | } 20 | 21 | .hljs-keyword, 22 | .hljs-selector-tag { 23 | color: #c26230; 24 | } 25 | 26 | .hljs-string, 27 | .hljs-number, 28 | .hljs-regexp, 29 | .hljs-variable, 30 | .hljs-template-variable { 31 | color: #a5c261; 32 | } 33 | 34 | .hljs-subst { 35 | color: #519f50; 36 | } 37 | 38 | .hljs-tag, 39 | .hljs-name { 40 | color: #e8bf6a; 41 | } 42 | 43 | .hljs-type { 44 | color: #da4939; 45 | } 46 | 47 | 48 | .hljs-symbol, 49 | .hljs-bullet, 50 | .hljs-built_in, 51 | .hljs-builtin-name, 52 | .hljs-attr, 53 | .hljs-link { 54 | color: #6d9cbe; 55 | } 56 | 57 | .hljs-params { 58 | color: #d0d0ff; 59 | } 60 | 61 | .hljs-attribute { 62 | color: #cda869; 63 | } 64 | 65 | .hljs-meta { 66 | color: #9b859d; 67 | } 68 | 69 | .hljs-title, 70 | .hljs-section { 71 | color: #ffc66d; 72 | } 73 | 74 | .hljs-addition { 75 | background-color: #144212; 76 | color: #e6e1dc; 77 | display: inline-block; 78 | width: 100%; 79 | } 80 | 81 | .hljs-deletion { 82 | background-color: #600; 83 | color: #e6e1dc; 84 | display: inline-block; 85 | width: 100%; 86 | } 87 | 88 | .hljs-selector-class { 89 | color: #9b703f; 90 | } 91 | 92 | .hljs-selector-id { 93 | color: #8b98ab; 94 | } 95 | 96 | .hljs-emphasis { 97 | font-style: italic; 98 | } 99 | 100 | .hljs-strong { 101 | font-weight: bold; 102 | } 103 | 104 | .hljs-link { 105 | text-decoration: underline; 106 | } 107 | -------------------------------------------------------------------------------- /_res/css/style.css: -------------------------------------------------------------------------------- 1 | 2 | h1, h2, h3, h4, h5, h6 { 3 | clear: both; 4 | display: block; 5 | margin-bottom: 12px; 6 | width: 100%; 7 | } 8 | 9 | a { 10 | color: red; 11 | text-decoration: none; 12 | } 13 | 14 | a:hover { 15 | text-decoration: underline; 16 | } 17 | 18 | table { 19 | border: 1px #777 solid; 20 | border-spacing: 0; 21 | border-collapse: separate; 22 | } 23 | 24 | table td, table th { 25 | border: 1px #777 solid; 26 | padding: 6px 10px; 27 | } 28 | -------------------------------------------------------------------------------- /_res/html/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /_res/html/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 11 | 12 | 17 | 18 | 27 | 28 | 29 | 36 | 37 | 38 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /_res/javascript/script.js: -------------------------------------------------------------------------------- 1 | 2 | jQuery(function() { 3 | jQuery('pre code').each(function(i, block) { 4 | hljs.highlightBlock(block); 5 | }); 6 | }); 7 | -------------------------------------------------------------------------------- /_res/rest/get.api.commands.http: -------------------------------------------------------------------------------- 1 | GET http://localhost/api/commands HTTP/1.1 2 | -------------------------------------------------------------------------------- /_res/rest/get.api.editors.http: -------------------------------------------------------------------------------- 1 | GET http://localhost/api/editors HTTP/1.1 2 | -------------------------------------------------------------------------------- /_res/rest/get.api.editors.index.content.http: -------------------------------------------------------------------------------- 1 | GET http://localhost/api/editors/0/content HTTP/1.1 2 | -------------------------------------------------------------------------------- /_res/rest/get.api.editors.index.http: -------------------------------------------------------------------------------- 1 | GET http://localhost/api/editors/0 HTTP/1.1 2 | -------------------------------------------------------------------------------- /_res/rest/get.api.http: -------------------------------------------------------------------------------- 1 | GET http://localhost/api HTTP/1.1 -------------------------------------------------------------------------------- /_res/rest/get.api.languages.http: -------------------------------------------------------------------------------- 1 | GET http://localhost/api/languages HTTP/1.1 2 | -------------------------------------------------------------------------------- /_res/rest/get.extensions.http: -------------------------------------------------------------------------------- 1 | GET http://localhost/api/extensions HTTP/1.1 2 | -------------------------------------------------------------------------------- /_res/rest/post.api.commands.http: -------------------------------------------------------------------------------- 1 | POST http://localhost/api/commands/editor.action.selectAll HTTP/1.1 2 | -------------------------------------------------------------------------------- /_res/rest/post.api.editors.http: -------------------------------------------------------------------------------- 1 | POST http://localhost/api/editors HTTP/1.1 2 | x-Vscode-Deploy-Reloaded-Lang: json 3 | 4 | { 5 | "message": "Test message", 6 | "type": "error" 7 | } -------------------------------------------------------------------------------- /_res/rest/post.api.markdown.http: -------------------------------------------------------------------------------- 1 | POST http://localhost/api/markdown HTTP/1.1 2 | 3 | { 4 | "title": "A title", 5 | "content": "# Header 1\n\n## Header 2\n\n```javascript\nvar s = 'JavaScript syntax highlighting';\nalert(s);\n```", 6 | "options": { 7 | "css": "body { background-color: white; color: black; }" 8 | } 9 | } -------------------------------------------------------------------------------- /_res/rest/post.api.messages.http: -------------------------------------------------------------------------------- 1 | POST http://localhost/api/messages HTTP/1.1 2 | Content-type: text/plain 3 | 4 | { 5 | "message": "Test message", 6 | "type": "error" 7 | } -------------------------------------------------------------------------------- /_res/rest/put.api.output.http: -------------------------------------------------------------------------------- 1 | PUT http://localhost/api/output HTTP/1.1 2 | 3 | Lorem ipsum -------------------------------------------------------------------------------- /copyright.txt: -------------------------------------------------------------------------------- 1 | 2 | Icons: 3 | - /icon.png (DinosoftLabs; https://www.iconfinder.com/dinosoftlabs) 4 | - /img/share/* (https://simplesharingbuttons.com) 5 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/icon.png -------------------------------------------------------------------------------- /img/demo1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo1.gif -------------------------------------------------------------------------------- /img/demo10.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo10.gif -------------------------------------------------------------------------------- /img/demo11.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo11.gif -------------------------------------------------------------------------------- /img/demo12.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo12.gif -------------------------------------------------------------------------------- /img/demo13.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo13.gif -------------------------------------------------------------------------------- /img/demo14.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo14.gif -------------------------------------------------------------------------------- /img/demo15.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo15.gif -------------------------------------------------------------------------------- /img/demo16.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo16.gif -------------------------------------------------------------------------------- /img/demo17.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo17.gif -------------------------------------------------------------------------------- /img/demo18.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo18.gif -------------------------------------------------------------------------------- /img/demo19.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo19.gif -------------------------------------------------------------------------------- /img/demo2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo2.gif -------------------------------------------------------------------------------- /img/demo20.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo20.gif -------------------------------------------------------------------------------- /img/demo21.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo21.gif -------------------------------------------------------------------------------- /img/demo22.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo22.gif -------------------------------------------------------------------------------- /img/demo23.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo23.gif -------------------------------------------------------------------------------- /img/demo24.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo24.gif -------------------------------------------------------------------------------- /img/demo25.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo25.gif -------------------------------------------------------------------------------- /img/demo26.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo26.gif -------------------------------------------------------------------------------- /img/demo27.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo27.gif -------------------------------------------------------------------------------- /img/demo28.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo28.gif -------------------------------------------------------------------------------- /img/demo29.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo29.gif -------------------------------------------------------------------------------- /img/demo3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo3.gif -------------------------------------------------------------------------------- /img/demo30.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo30.gif -------------------------------------------------------------------------------- /img/demo4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo4.gif -------------------------------------------------------------------------------- /img/demo5.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo5.gif -------------------------------------------------------------------------------- /img/demo6.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo6.gif -------------------------------------------------------------------------------- /img/demo7.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo7.gif -------------------------------------------------------------------------------- /img/demo8.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo8.gif -------------------------------------------------------------------------------- /img/demo9.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/demo9.gif -------------------------------------------------------------------------------- /img/screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/screenshot1.png -------------------------------------------------------------------------------- /img/share/Email.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/share/Email.png -------------------------------------------------------------------------------- /img/share/Facebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/share/Facebook.png -------------------------------------------------------------------------------- /img/share/Google+.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/share/Google+.png -------------------------------------------------------------------------------- /img/share/LinkedIn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/share/LinkedIn.png -------------------------------------------------------------------------------- /img/share/Pinboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/share/Pinboard.png -------------------------------------------------------------------------------- /img/share/Pinterest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/share/Pinterest.png -------------------------------------------------------------------------------- /img/share/Pocket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/share/Pocket.png -------------------------------------------------------------------------------- /img/share/Reddit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/share/Reddit.png -------------------------------------------------------------------------------- /img/share/Tumblr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/share/Tumblr.png -------------------------------------------------------------------------------- /img/share/Twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/share/Twitter.png -------------------------------------------------------------------------------- /img/share/Wordpress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mkloubert/vscode-deploy-reloaded/5bc78980aee0765b045b35921d0d3da7add7a935/img/share/Wordpress.png -------------------------------------------------------------------------------- /src/clients.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as _ from 'lodash'; 19 | import * as deploy_contracts from './contracts'; 20 | import * as deploy_helpers from './helpers'; 21 | import * as deploy_files from './files'; 22 | import * as deploy_values from './values'; 23 | import * as vscode from 'vscode'; 24 | 25 | 26 | /** 27 | * An async file client. 28 | */ 29 | export interface IAsyncFileClient extends NodeJS.EventEmitter, vscode.Disposable { 30 | /** 31 | * Deletes a file. 32 | * 33 | * @param {string} path The path of the file on the remote. 34 | * 35 | * @return {PromiseLike} A promise that indicates if operation was successful or not. 36 | */ 37 | readonly deleteFile: (path: string) => PromiseLike; 38 | 39 | /** 40 | * Downloads a file. 41 | * 42 | * @param {string} path The path of the file to download. 43 | * 44 | * @return {PromiseLike} The promise with the downloaded data. 45 | */ 46 | readonly downloadFile: (path: string) => PromiseLike; 47 | 48 | /** 49 | * Lists a directory. 50 | * 51 | * @param {string} path The path of the remote directory. 52 | * 53 | * @return {PromiseLike} The promise with the file and folder list. 54 | */ 55 | readonly listDirectory: (path: string) => PromiseLike; 56 | 57 | /** 58 | * Deletes a folder. 59 | * 60 | * @param {string} path The path of the folder on the remote. 61 | * 62 | * @return {PromiseLike} A promise that indicates if operation was successful or not. 63 | */ 64 | readonly removeFolder: (path: string) => PromiseLike; 65 | 66 | /** 67 | * The type. 68 | */ 69 | readonly type: string; 70 | 71 | /** 72 | * Uploads a file. 73 | * 74 | * @param {string} path The path of the file on the remote. 75 | * @param {Buffer} data The data for the remote file. 76 | */ 77 | readonly uploadFile: (path: string, data: Buffer) => PromiseLike; 78 | 79 | /** 80 | * Stores the list of connection values. 81 | */ 82 | readonly values: deploy_values.Value[]; 83 | } 84 | 85 | 86 | /** 87 | * A basic async file client. 88 | */ 89 | export abstract class AsyncFileListBase extends deploy_helpers.DisposableBase implements IAsyncFileClient { 90 | private readonly _CONNECTION_VALUES: deploy_contracts.KeyValuePairs = {}; 91 | 92 | /** @inheritdoc */ 93 | public abstract async deleteFile(path: string): Promise; 94 | 95 | /** @inheritdoc */ 96 | public abstract async downloadFile(path: string): Promise; 97 | 98 | /** @inheritdoc */ 99 | public abstract async listDirectory(path: string): Promise; 100 | 101 | /** 102 | * Normalizes a name for a value. 103 | * 104 | * @param {any} name The input value. 105 | * 106 | * @return {string} The output value. 107 | */ 108 | protected normalizeValueName(name: any): string { 109 | return deploy_helpers.normalizeString( name ); 110 | } 111 | 112 | /** @inheritdoc */ 113 | public async removeFolder(path: string) { 114 | path = deploy_helpers.toStringSafe(path); 115 | if ('' === normalizePath(path)) { 116 | return false; // NOT the roor folder! 117 | } 118 | 119 | try { 120 | const FILES_AND_FOLDERS = deploy_helpers.asArray(await this.listDirectory(path)); 121 | 122 | const OTHERS = FILES_AND_FOLDERS.filter(ff => { 123 | switch (ff.type) { 124 | case deploy_files.FileSystemType.Directory: 125 | case deploy_files.FileSystemType.File: 126 | return true; 127 | } 128 | 129 | return false; 130 | }); 131 | if (OTHERS.length > 0) { 132 | return false; 133 | } 134 | 135 | const TO_PATH = (wnp: deploy_contracts.WithNameAndPath) => { 136 | return '/' + deploy_helpers.normalizePath( 137 | deploy_helpers.normalizePath(wnp.path) + 138 | '/' + 139 | deploy_helpers.normalizePath(wnp.name), 140 | ); 141 | }; 142 | 143 | const FOLDERS = FILES_AND_FOLDERS.filter(ff => { 144 | return ff.type == deploy_files.FileSystemType.Directory; 145 | }).map(ff => TO_PATH(ff)); 146 | const FILES = FILES_AND_FOLDERS.filter(ff => { 147 | return ff.type == deploy_files.FileSystemType.File; 148 | }).map(ff => TO_PATH(ff)); 149 | 150 | // first delete the sub folders 151 | for (const F of FOLDERS) { 152 | if (!(await this.removeFolder(F))) { 153 | return false; 154 | } 155 | } 156 | 157 | // then the files 158 | for (const F of FILES) { 159 | await this.deleteFile(F); 160 | } 161 | 162 | return true; 163 | } 164 | catch (e) { 165 | return false; 166 | } 167 | } 168 | 169 | /** 170 | * Sets a connection value. 171 | * 172 | * @param {string} name The name of the value. 173 | * @param {any} val The value to set. 174 | * 175 | * @return this 176 | * 177 | * @chainable 178 | */ 179 | public setValue(name: string, val: any): this { 180 | name = this.normalizeValueName( name ); 181 | 182 | let existingValue = deploy_helpers.from( 183 | this.values 184 | ).singleOrDefault(v => v.name === name); 185 | if (_.isSymbol(existingValue)) { 186 | existingValue = new deploy_values.FunctionValue(() => { 187 | return this._CONNECTION_VALUES[ name ]; 188 | }, name); 189 | 190 | this.values 191 | .push( existingValue ); 192 | } 193 | 194 | this._CONNECTION_VALUES[ name ] = val; 195 | 196 | return this; 197 | } 198 | 199 | /** @inheritdoc */ 200 | public abstract get type(): string; 201 | 202 | /** @inheritdoc */ 203 | public abstract async uploadFile(path: string, data: Buffer): Promise; 204 | 205 | /** @inheritdoc */ 206 | public readonly values: deploy_values.Value[] = []; 207 | } 208 | 209 | function normalizePath(p: string) { 210 | p = deploy_helpers.normalizePath(p); 211 | if ('.' === p) { 212 | p = ''; 213 | } 214 | 215 | return p; 216 | } 217 | -------------------------------------------------------------------------------- /src/clients/dropbox.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_clients from '../clients'; 19 | import * as deploy_files from '../files'; 20 | import * as deploy_helpers from '../helpers'; 21 | import * as deploy_log from '../log'; 22 | const Dropbox = require('dropbox'); 23 | import * as Moment from 'moment'; 24 | 25 | 26 | /** 27 | * Options for a FTP connection. 28 | */ 29 | export interface DropboxOptions { 30 | /** 31 | * The access token to use. 32 | */ 33 | readonly accessToken?: string; 34 | } 35 | 36 | 37 | /** 38 | * A Dropbox file client. 39 | */ 40 | export class DropBoxClient extends deploy_clients.AsyncFileListBase { 41 | /** 42 | * Initializes a new instance of that class. 43 | * 44 | * @param {DropboxOptions} options The options for the client. 45 | */ 46 | constructor(public readonly options: DropboxOptions) { 47 | super(); 48 | 49 | let accessToken = deploy_helpers.toStringSafe(options.accessToken).trim(); 50 | if ('' === accessToken) { 51 | accessToken = undefined; 52 | } 53 | 54 | this.connection = new Dropbox({ 55 | accessToken: accessToken 56 | }); 57 | } 58 | 59 | /** 60 | * Gets the underlying Dropbox instance. 61 | */ 62 | public readonly connection: any; 63 | 64 | /** @inheritdoc */ 65 | public async deleteFile(path: string): Promise { 66 | path = toDropBoxPath(path); 67 | 68 | try { 69 | await this.connection.filesDeleteV2({ 70 | path: path, 71 | }); 72 | 73 | return true; 74 | } 75 | catch (e) { 76 | deploy_log.CONSOLE 77 | .trace(e, 'clients.dropbox.DropBoxClient.deleteFile(1)'); 78 | 79 | return false; 80 | } 81 | } 82 | 83 | /** @inheritdoc */ 84 | public async downloadFile(path: string): Promise { 85 | path = toDropBoxPath(path); 86 | 87 | const META_DATA = await this.connection.filesDownload({ 88 | path: path, 89 | }); 90 | 91 | return new Buffer(META_DATA.fileBinary, 'binary'); 92 | } 93 | 94 | /** @inheritdoc */ 95 | public async listDirectory(path: string) { 96 | const ME = this; 97 | 98 | path = toDropBoxPath(path); 99 | 100 | const RESULT: deploy_files.FileSystemInfo[] = []; 101 | 102 | const LIST = await this.connection.filesListFolder({ 103 | include_media_info: true, 104 | include_mounted_folders: true, 105 | path: path, 106 | recursive: false, 107 | }); 108 | if (LIST && LIST.entries) { 109 | for (const ENTRY of LIST.entries) { 110 | switch (deploy_helpers.normalizeString(ENTRY['.tag'])) { 111 | case 'file': 112 | { 113 | const FI: deploy_files.FileInfo = { 114 | download: async () => { 115 | return await ME.downloadFile( 116 | deploy_helpers.normalizePath( 117 | deploy_helpers.normalizePath(path) + '/' + ENTRY.name 118 | ) 119 | ); 120 | }, 121 | //TODO: exportPath: false, 122 | name: ENTRY.name, 123 | path: deploy_helpers.normalizePath(path), 124 | size: ENTRY.size, 125 | time: Moment(ENTRY.server_modified), 126 | type: deploy_files.FileSystemType.File, 127 | }; 128 | 129 | RESULT.push(FI); 130 | } 131 | break; 132 | 133 | case 'folder': 134 | { 135 | const DI: deploy_files.DirectoryInfo = { 136 | //TODO: exportPath: false, 137 | name: ENTRY.name, 138 | path: deploy_helpers.normalizePath(path), 139 | type: deploy_files.FileSystemType.Directory, 140 | }; 141 | 142 | RESULT.push(DI); 143 | } 144 | break; 145 | 146 | default: 147 | { 148 | const FSI: deploy_files.FileSystemInfo = { 149 | //TODO: exportPath: false, 150 | name: ENTRY.name, 151 | path: deploy_helpers.normalizePath(path), 152 | }; 153 | 154 | RESULT.push(FSI); 155 | } 156 | break; 157 | } 158 | } 159 | } 160 | 161 | return RESULT; 162 | } 163 | 164 | /** @inheritdoc */ 165 | public async removeFolder(path: string): Promise { 166 | path = toDropBoxPath(path); 167 | if ('/' === path) { 168 | return false; // NOT the root folder! 169 | } 170 | 171 | try { 172 | await this.connection.filesDeleteV2({ 173 | path: path, 174 | }); 175 | 176 | return true; 177 | } 178 | catch (e) { 179 | deploy_log.CONSOLE 180 | .trace(e, 'clients.dropbox.DropBoxClient.removeFolder(1)'); 181 | 182 | return false; 183 | } 184 | } 185 | 186 | /** @inheritdoc */ 187 | public get type() { 188 | return 'dropbox'; 189 | } 190 | 191 | /** @inheritdoc */ 192 | public async uploadFile(path: string, data: Buffer): Promise { 193 | path = toDropBoxPath(path); 194 | 195 | await this.connection.filesUpload({ 196 | autorename: false, 197 | contents: data, 198 | mode: 'overwrite', 199 | mute: false, 200 | path: path, 201 | }); 202 | } 203 | } 204 | 205 | 206 | /** 207 | * Creates a new client. 208 | * 209 | * @param {DropboxOptions} opts The options for the new client. 210 | * 211 | * @return {DropBoxClient} The new client. 212 | */ 213 | export function createClient(opts: DropboxOptions): DropBoxClient { 214 | if (!opts) { 215 | return opts; 216 | } 217 | 218 | return new DropBoxClient(opts); 219 | } 220 | 221 | /** 222 | * Converts to a Dropbox path. 223 | * 224 | * @param {string} p The path to convert. 225 | * 226 | * @return {string} The converted path. 227 | */ 228 | export function toDropBoxPath(p: string) { 229 | p = deploy_helpers.normalizePath(p); 230 | 231 | if ('.' === p) { 232 | p = ''; 233 | } 234 | if ('' !== p) { 235 | p = '/' + p; 236 | } 237 | 238 | return p; 239 | } 240 | -------------------------------------------------------------------------------- /src/code.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_values from './values'; 19 | 20 | 21 | /** 22 | * A code execution context. 23 | */ 24 | export interface CodeExecutionContext { 25 | /** 26 | * The code to execute. 27 | */ 28 | readonly code: string; 29 | /** 30 | * The context. 31 | */ 32 | readonly context?: TContext; 33 | /** 34 | * One or more values. 35 | */ 36 | readonly values?: deploy_values.Value | deploy_values.Value[]; 37 | } 38 | 39 | 40 | /** 41 | * Execute code. 42 | * 43 | * @param {any} code The code to execute. 44 | * 45 | * @return {TResult} The result of the execution. 46 | */ 47 | export function exec(context: CodeExecutionContext): TResult { 48 | if (!context) { 49 | return; 50 | } 51 | 52 | // tslint:disable-next-line:no-unused-variable 53 | const $ctx = context.context; 54 | // tslint:disable-next-line:no-unused-variable 55 | const $h = require('./helpers'); 56 | // tslint:disable-next-line:no-unused-variable 57 | const $r = (id) => { 58 | return $h.requireFromExtension(id); 59 | }; 60 | // tslint:disable-next-line:no-unused-variable 61 | const $v = deploy_values.toValueStorage(context.values); 62 | 63 | // tslint:disable-next-line:no-unused-variable 64 | const $e = (code: any) => { 65 | return eval( 66 | $h.toStringSafe(code) 67 | ); 68 | }; 69 | 70 | return $e( 71 | context.code 72 | ); 73 | } 74 | -------------------------------------------------------------------------------- /src/compilers/coffeescript.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | const CoffeeScript = require('coffeescript'); 19 | import * as Path from 'path'; 20 | import * as deploy_compilers from '../compilers'; 21 | import * as deploy_helpers from '../helpers'; 22 | 23 | 24 | /** 25 | * CoffeeScript compile options. 26 | */ 27 | export interface CompileOptions extends deploy_compilers.CompileOptions { 28 | /** 29 | * The encoding of / for the files. 30 | */ 31 | readonly encoding?: string; 32 | /** 33 | * The custom file extension for the output files to use. 34 | */ 35 | readonly extension?: string; 36 | } 37 | 38 | /** 39 | * CoffeeScript compiler result. 40 | */ 41 | export interface CompileResult extends deploy_compilers.CompileResult { 42 | /** @inheritdoc */ 43 | readonly messages: CompileResultMessage[]; 44 | } 45 | 46 | /** 47 | * A CoffeeScript result message (entry). 48 | */ 49 | export interface CompileResultMessage extends deploy_compilers.CompileResultMessage { 50 | } 51 | 52 | 53 | /** 54 | * Compiles CoffeeScript files. 55 | * 56 | * @param {CompileOptions} compileOpts The options for the compilation. 57 | * 58 | * @return {Promise} The promise with the result. 59 | */ 60 | export async function compile(compileOpts: CompileOptions) { 61 | const WORKSPACE = compileOpts.workspace; 62 | 63 | const RESULT: CompileResult = { 64 | messages: [], 65 | }; 66 | 67 | const OPTS = compileOpts.options || {}; 68 | 69 | const FILES_TO_COMPILE = await deploy_compilers.collectFiles( 70 | compileOpts, 71 | '**/*.coffee' 72 | ); 73 | 74 | let enc = deploy_helpers.normalizeString( 75 | WORKSPACE.replaceWithValues(compileOpts.encoding) 76 | ); 77 | if ('' === enc) { 78 | enc = 'utf8'; 79 | } 80 | 81 | let outExt = deploy_helpers.toStringSafe( 82 | WORKSPACE.replaceWithValues(compileOpts.extension) 83 | ).trim(); 84 | if ('' === outExt) { 85 | outExt = 'js'; 86 | } 87 | 88 | for (const FTC of FILES_TO_COMPILE) { 89 | let msg: CompileResultMessage; 90 | 91 | try { 92 | const OUTPUT_FILE_PATH = deploy_compilers.getFullOutputPathForSourceFile(FTC, compileOpts); 93 | const OUT_DIR = Path.dirname(OUTPUT_FILE_PATH); 94 | 95 | await deploy_helpers.createDirectoryIfNeeded(OUT_DIR); 96 | 97 | const EXT = Path.extname(OUTPUT_FILE_PATH); 98 | const FILENAME = Path.basename(OUTPUT_FILE_PATH, EXT); 99 | 100 | const OUTPUT_FILE = Path.join(OUT_DIR, 101 | FILENAME + '.' + outExt); 102 | 103 | const JS_CODE: string = CoffeeScript.compile((await deploy_helpers.readFile(FTC)).toString(enc), 104 | OPTS); 105 | 106 | await deploy_helpers.writeFile(OUTPUT_FILE, 107 | new Buffer(JS_CODE, enc)); 108 | } 109 | catch (e) { 110 | msg = { 111 | category: deploy_compilers.CompileResultMessageCategory.Error, 112 | compiler: deploy_compilers.Compiler.CoffeeScript, 113 | file: FTC, 114 | message: deploy_helpers.toStringSafe(e), 115 | }; 116 | } 117 | 118 | if (msg) { 119 | RESULT.messages.push(msg); 120 | } 121 | } 122 | 123 | return RESULT; 124 | } 125 | -------------------------------------------------------------------------------- /src/compilers/htmlminifier.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_compilers from '../compilers'; 19 | import * as deploy_helpers from '../helpers'; 20 | import * as HtmlMinifier from 'html-minifier'; 21 | import * as Path from 'path'; 22 | 23 | 24 | /** 25 | * HTMLMinifier compile options. 26 | */ 27 | export interface CompileOptions extends deploy_compilers.CompileOptions { 28 | /** 29 | * Delete the source file(s) on success or not. 30 | */ 31 | readonly deleteSources?: boolean; 32 | /** 33 | * The encoding of / for the files. 34 | */ 35 | readonly encoding?: string; 36 | /** 37 | * The extension to use for the output files. 38 | */ 39 | readonly extension?: string; 40 | } 41 | 42 | /** 43 | * HTMLMinifier compiler result. 44 | */ 45 | export interface CompileResult extends deploy_compilers.CompileResult { 46 | /** @inheritdoc */ 47 | readonly messages: CompileResultMessage[]; 48 | } 49 | 50 | /** 51 | * A HTMLMinifier result message (entry). 52 | */ 53 | export interface CompileResultMessage extends deploy_compilers.CompileResultMessage { 54 | } 55 | 56 | 57 | /** 58 | * Minifies HTML files by HTMLMinifier. 59 | * 60 | * @param {CompileOptions} compileOpts The options for the compilation. 61 | * 62 | * @return {Promise} The promise with the result. 63 | */ 64 | export async function compile(compileOpts: CompileOptions) { 65 | const OPTS: HtmlMinifier.Options = compileOpts.options || {}; 66 | 67 | const WORKSPACE = compileOpts.workspace; 68 | 69 | const RESULT: CompileResult = { 70 | messages: [], 71 | }; 72 | 73 | let outExt: string; 74 | if (deploy_helpers.isNullOrUndefined(compileOpts.extension)) { 75 | outExt = 'min.html'; 76 | } 77 | else { 78 | outExt = deploy_helpers.toStringSafe( 79 | WORKSPACE.replaceWithValues(compileOpts.extension) 80 | ).trim(); 81 | } 82 | 83 | let enc = deploy_helpers.normalizeString( 84 | WORKSPACE.replaceWithValues(compileOpts.encoding) 85 | ); 86 | if ('' === enc) { 87 | enc = 'utf8'; 88 | } 89 | 90 | const FILES_TO_COMPILE = await deploy_compilers.collectFiles( 91 | compileOpts, 92 | '**/*.html', 93 | '**/*.min.html', 94 | ); 95 | 96 | const DELETE_SOURCES = deploy_helpers.toBooleanSafe(compileOpts.deleteSources); 97 | 98 | for (const FTC of FILES_TO_COMPILE) { 99 | let msg: CompileResultMessage; 100 | 101 | try { 102 | const OUTPUT_FILE_PATH = deploy_compilers.getFullOutputPathForSourceFile(FTC, compileOpts); 103 | const OUT_DIR = Path.dirname(OUTPUT_FILE_PATH); 104 | 105 | await deploy_helpers.createDirectoryIfNeeded(OUT_DIR); 106 | 107 | const EXT = Path.extname(OUTPUT_FILE_PATH); 108 | const FILENAME = Path.basename(OUTPUT_FILE_PATH, EXT); 109 | 110 | let outputFile: string; 111 | if ('' === outExt) { 112 | outputFile = OUTPUT_FILE_PATH; 113 | } 114 | else { 115 | outputFile = Path.join(OUT_DIR, 116 | FILENAME + '.' + outExt); 117 | } 118 | outputFile = Path.resolve(outputFile); 119 | 120 | const MINI_HTML = HtmlMinifier.minify((await deploy_helpers.readFile(FTC)).toString(enc), 121 | OPTS); 122 | 123 | await deploy_helpers.writeFile(outputFile, 124 | new Buffer(MINI_HTML, enc)); 125 | 126 | if (DELETE_SOURCES) { 127 | try { 128 | if (outputFile !== Path.resolve(FTC)) { 129 | await deploy_helpers.unlink(FTC); 130 | } 131 | } 132 | catch (e) { 133 | RESULT.messages.push({ 134 | category: deploy_compilers.CompileResultMessageCategory.Warning, 135 | compiler: deploy_compilers.Compiler.HtmlMinifier, 136 | file: FTC, 137 | message: WORKSPACE.t('compilers.errors.couldNotDeleteSourceFile', 138 | e), 139 | }); 140 | } 141 | } 142 | } 143 | catch (e) { 144 | msg = { 145 | category: deploy_compilers.CompileResultMessageCategory.Error, 146 | compiler: deploy_compilers.Compiler.HtmlMinifier, 147 | file: FTC, 148 | message: deploy_helpers.toStringSafe(e), 149 | }; 150 | } 151 | 152 | if (msg) { 153 | RESULT.messages.push(msg); 154 | } 155 | } 156 | 157 | return RESULT; 158 | } 159 | -------------------------------------------------------------------------------- /src/compilers/less.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_compilers from '../compilers'; 19 | import * as deploy_helpers from '../helpers'; 20 | import * as LESS from 'less'; 21 | import * as Path from 'path'; 22 | 23 | 24 | /** 25 | * LESS compile options. 26 | */ 27 | export interface CompileOptions extends deploy_compilers.CompileOptions { 28 | /** 29 | * The encoding of / for the files. 30 | */ 31 | readonly encoding?: string; 32 | /** 33 | * The custom file extension for the output files to use. 34 | */ 35 | readonly extension?: string; 36 | } 37 | 38 | /** 39 | * LESS compiler result. 40 | */ 41 | export interface CompileResult extends deploy_compilers.CompileResult { 42 | /** @inheritdoc */ 43 | readonly messages: CompileResultMessage[]; 44 | } 45 | 46 | /** 47 | * A LESS result message (entry). 48 | */ 49 | export interface CompileResultMessage extends deploy_compilers.CompileResultMessage { 50 | } 51 | 52 | 53 | /** 54 | * Compiles CSS files by LESS. 55 | * 56 | * @param {CompileOptions} compileOpts The options for the compilation. 57 | * 58 | * @return {Promise} The promise with the result. 59 | */ 60 | export async function compile(compileOpts: CompileOptions) { 61 | const WORKSPACE = compileOpts.workspace; 62 | 63 | const RESULT: CompileResult = { 64 | messages: [], 65 | }; 66 | 67 | const OPTS: Less.Options = compileOpts.options || {}; 68 | 69 | const FILES_TO_COMPILE = await deploy_compilers.collectFiles( 70 | compileOpts, 71 | '**/*.less' 72 | ); 73 | 74 | let enc = deploy_helpers.normalizeString( 75 | WORKSPACE.replaceWithValues(compileOpts.encoding) 76 | ); 77 | if ('' === enc) { 78 | enc = 'utf8'; 79 | } 80 | 81 | let outExt = deploy_helpers.toStringSafe( 82 | WORKSPACE.replaceWithValues(compileOpts.extension) 83 | ).trim(); 84 | if ('' === outExt) { 85 | outExt = 'css'; 86 | } 87 | 88 | for (const FTC of FILES_TO_COMPILE) { 89 | let msg: CompileResultMessage; 90 | 91 | try { 92 | const LESS_CODE = (await deploy_helpers.readFile(FTC)).toString(enc); 93 | 94 | const OUTPUT_FILE_PATH = deploy_compilers.getFullOutputPathForSourceFile(FTC, compileOpts); 95 | const OUT_DIR = Path.dirname(OUTPUT_FILE_PATH); 96 | 97 | await deploy_helpers.createDirectoryIfNeeded(OUT_DIR); 98 | 99 | const EXT = Path.extname(OUTPUT_FILE_PATH); 100 | const FILENAME = Path.basename(OUTPUT_FILE_PATH, EXT); 101 | 102 | const OUTPUT_FILE = Path.join(OUT_DIR, 103 | FILENAME + '.' + outExt); 104 | 105 | const LESS_OUTPUT = await LESS.render(LESS_CODE, OPTS); 106 | 107 | await deploy_helpers.writeFile(OUTPUT_FILE, 108 | new Buffer(LESS_OUTPUT.css, enc)); 109 | } 110 | catch (e) { 111 | msg = { 112 | category: deploy_compilers.CompileResultMessageCategory.Error, 113 | compiler: deploy_compilers.Compiler.Less, 114 | file: FTC, 115 | message: deploy_helpers.toStringSafe(e), 116 | }; 117 | } 118 | 119 | if (msg) { 120 | RESULT.messages.push(msg); 121 | } 122 | } 123 | 124 | return RESULT; 125 | } 126 | -------------------------------------------------------------------------------- /src/compilers/pug.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_compilers from '../compilers'; 19 | import * as deploy_helpers from '../helpers'; 20 | import * as Path from 'path'; 21 | import * as Pug from 'pug'; 22 | 23 | 24 | /** 25 | * Pug compile options. 26 | */ 27 | export interface CompileOptions extends deploy_compilers.CompileOptions { 28 | /** 29 | * The encoding of / for the files. 30 | */ 31 | readonly encoding?: string; 32 | /** 33 | * The custom file extension for the output files to use. 34 | */ 35 | readonly extension?: string; 36 | } 37 | 38 | /** 39 | * Pug compiler result. 40 | */ 41 | export interface CompileResult extends deploy_compilers.CompileResult { 42 | /** @inheritdoc */ 43 | readonly messages: CompileResultMessage[]; 44 | } 45 | 46 | /** 47 | * A Pug result message (entry). 48 | */ 49 | export interface CompileResultMessage extends deploy_compilers.CompileResultMessage { 50 | } 51 | 52 | 53 | /** 54 | * Compiles Pug files. 55 | * 56 | * @param {CompileOptions} compileOpts The options for the compilation. 57 | * 58 | * @return {Promise} The promise with the result. 59 | */ 60 | export async function compile(compileOpts: CompileOptions) { 61 | const WORKSPACE = compileOpts.workspace; 62 | 63 | const RESULT: CompileResult = { 64 | messages: [], 65 | }; 66 | 67 | const OPTS: Pug.Options = compileOpts.options || {}; 68 | 69 | const FILES_TO_COMPILE = await deploy_compilers.collectFiles( 70 | compileOpts, 71 | '**/*.pug' 72 | ); 73 | 74 | let enc = deploy_helpers.normalizeString( 75 | WORKSPACE.replaceWithValues(compileOpts.encoding) 76 | ); 77 | if ('' === enc) { 78 | enc = 'utf8'; 79 | } 80 | 81 | let outExt = deploy_helpers.toStringSafe( 82 | WORKSPACE.replaceWithValues(compileOpts.extension) 83 | ).trim(); 84 | if ('' === outExt) { 85 | outExt = 'html'; 86 | } 87 | 88 | for (const FTC of FILES_TO_COMPILE) { 89 | let msg: CompileResultMessage; 90 | 91 | try { 92 | const PUG_OPTS = deploy_helpers.cloneObject(OPTS); 93 | PUG_OPTS.filename = FTC; 94 | 95 | const OUTPUT_FILE_PATH = deploy_compilers.getFullOutputPathForSourceFile(FTC, compileOpts); 96 | const OUT_DIR = Path.dirname(OUTPUT_FILE_PATH); 97 | 98 | await deploy_helpers.createDirectoryIfNeeded(OUT_DIR); 99 | 100 | const EXT = Path.extname(OUTPUT_FILE_PATH); 101 | const FILENAME = Path.basename(OUTPUT_FILE_PATH, EXT); 102 | 103 | const OUTPUT_FILE = Path.join(OUT_DIR, 104 | FILENAME + '.' + outExt); 105 | 106 | const HTML = Pug.render((await deploy_helpers.readFile(FTC)).toString(enc), 107 | PUG_OPTS); 108 | 109 | await deploy_helpers.writeFile(OUTPUT_FILE, 110 | new Buffer(HTML, enc)); 111 | } 112 | catch (e) { 113 | msg = { 114 | category: deploy_compilers.CompileResultMessageCategory.Error, 115 | compiler: deploy_compilers.Compiler.Pug, 116 | file: FTC, 117 | message: deploy_helpers.toStringSafe(e), 118 | }; 119 | } 120 | 121 | if (msg) { 122 | RESULT.messages.push(msg); 123 | } 124 | } 125 | 126 | return RESULT; 127 | } 128 | -------------------------------------------------------------------------------- /src/compilers/uglifyjs.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | 19 | import * as deploy_compilers from '../compilers'; 20 | import * as deploy_helpers from '../helpers'; 21 | import * as Path from 'path'; 22 | const UglifyJS = require('uglify-js'); 23 | 24 | 25 | /** 26 | * UglifyJS compile options. 27 | */ 28 | export interface CompileOptions extends deploy_compilers.CompileOptions { 29 | /** 30 | * Delete the source file(s) on success or not. 31 | */ 32 | readonly deleteSources?: boolean; 33 | /** 34 | * The encoding of / for the files. 35 | */ 36 | readonly encoding?: string; 37 | /** 38 | * The extension to use for the output files. 39 | */ 40 | readonly extension?: string; 41 | } 42 | 43 | /** 44 | * UglifyJS compiler result. 45 | */ 46 | export interface CompileResult extends deploy_compilers.CompileResult { 47 | /** @inheritdoc */ 48 | readonly messages: CompileResultMessage[]; 49 | } 50 | 51 | /** 52 | * A UglifyJS result message (entry). 53 | */ 54 | export interface CompileResultMessage extends deploy_compilers.CompileResultMessage { 55 | } 56 | 57 | 58 | /** 59 | * Minifies JavaScript files by UglifyJS. 60 | * 61 | * @param {CompileOptions} compileOpts The options for the compilation. 62 | * 63 | * @return {Promise} The promise with the result. 64 | */ 65 | export async function compile(compileOpts: CompileOptions) { 66 | const WORKSPACE = compileOpts.workspace; 67 | 68 | const RESULT: CompileResult = { 69 | messages: [], 70 | }; 71 | 72 | const OPTS = compileOpts.options || {}; 73 | 74 | let outExt: string; 75 | if (deploy_helpers.isNullOrUndefined(compileOpts.extension)) { 76 | outExt = 'min.js'; 77 | } 78 | else { 79 | outExt = deploy_helpers.toStringSafe( 80 | WORKSPACE.replaceWithValues(compileOpts.extension) 81 | ).trim(); 82 | } 83 | 84 | let enc = deploy_helpers.normalizeString( 85 | WORKSPACE.replaceWithValues(compileOpts.encoding) 86 | ); 87 | if ('' === enc) { 88 | enc = 'utf8'; 89 | } 90 | 91 | const FILES_TO_COMPILE = await deploy_compilers.collectFiles( 92 | compileOpts, 93 | '**/*.js', 94 | '**/*.min.js', 95 | ); 96 | 97 | const DELETE_SOURCES = deploy_helpers.toBooleanSafe(compileOpts.deleteSources); 98 | 99 | for (const FTC of FILES_TO_COMPILE) { 100 | let msg: CompileResultMessage; 101 | 102 | try { 103 | const OUTPUT_FILE_PATH = deploy_compilers.getFullOutputPathForSourceFile(FTC, compileOpts); 104 | const OUT_DIR = Path.dirname(OUTPUT_FILE_PATH); 105 | 106 | await deploy_helpers.createDirectoryIfNeeded(OUT_DIR); 107 | 108 | const EXT = Path.extname(OUTPUT_FILE_PATH); 109 | const FILENAME = Path.basename(OUTPUT_FILE_PATH, EXT); 110 | 111 | let outputFile: string; 112 | if ('' === outExt) { 113 | outputFile = OUTPUT_FILE_PATH; 114 | } 115 | else { 116 | outputFile = Path.join(OUT_DIR, 117 | FILENAME + '.' + outExt); 118 | } 119 | outputFile = Path.resolve(outputFile); 120 | 121 | const UGLY_RESULT: any = UglifyJS.minify((await deploy_helpers.readFile(FTC)).toString(enc), 122 | OPTS); 123 | 124 | if (UGLY_RESULT.error) { 125 | // error occurred 126 | 127 | RESULT.messages.push({ 128 | category: deploy_compilers.CompileResultMessageCategory.Error, 129 | compiler: deploy_compilers.Compiler.UglifyJS, 130 | file: FTC, 131 | message: JSON.stringify(UGLY_RESULT.error), 132 | }); 133 | } 134 | else { 135 | deploy_helpers.asArray(UGLY_RESULT.warnings).filter(w => !deploy_helpers.isEmptyString(w)).forEach(w => { 136 | RESULT.messages.push({ 137 | category: deploy_compilers.CompileResultMessageCategory.Warning, 138 | compiler: deploy_compilers.Compiler.UglifyJS, 139 | file: FTC, 140 | message: JSON.stringify(w), 141 | }); 142 | }); 143 | 144 | const UGLY_CODE = deploy_helpers.toStringSafe(UGLY_RESULT.code); 145 | 146 | await deploy_helpers.writeFile(outputFile, 147 | new Buffer(UGLY_CODE, enc)); 148 | 149 | if (DELETE_SOURCES) { 150 | try { 151 | if (outputFile !== Path.resolve(FTC)) { 152 | await deploy_helpers.unlink(FTC); 153 | } 154 | } 155 | catch (e) { 156 | RESULT.messages.push({ 157 | category: deploy_compilers.CompileResultMessageCategory.Warning, 158 | compiler: deploy_compilers.Compiler.UglifyJS, 159 | file: FTC, 160 | message: WORKSPACE.t('compilers.errors.couldNotDeleteSourceFile', 161 | e), 162 | }); 163 | } 164 | } 165 | } 166 | } 167 | catch (e) { 168 | msg = { 169 | category: deploy_compilers.CompileResultMessageCategory.Error, 170 | compiler: deploy_compilers.Compiler.UglifyJS, 171 | file: FTC, 172 | message: deploy_helpers.toStringSafe(e), 173 | }; 174 | } 175 | 176 | if (msg) { 177 | RESULT.messages.push(msg); 178 | } 179 | } 180 | 181 | return RESULT; 182 | } 183 | -------------------------------------------------------------------------------- /src/files.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_helpers from './helpers'; 19 | import * as Path from 'path'; 20 | import * as Moment from 'moment'; 21 | 22 | 23 | /** 24 | * Additional options for 'createDefaultDirectoryInfo()' function. 25 | */ 26 | export interface CreateDefaultDirectoryInfoOptions { 27 | /** 28 | * The custom export path. 29 | */ 30 | readonly exportPath?: string; 31 | } 32 | 33 | /** 34 | * Information about a directory. 35 | */ 36 | export interface DirectoryInfo extends FileSystemInfo { 37 | /** @inheritdoc */ 38 | readonly compareTo?: (other: DirectoryInfo) => number; 39 | /** @inheritdoc */ 40 | readonly type: FileSystemType; 41 | } 42 | 43 | /** 44 | * Information about a file. 45 | */ 46 | export interface FileInfo extends FileSystemInfo { 47 | /** @inheritdoc */ 48 | readonly compareTo?: (other: FileInfo) => number; 49 | /** 50 | * Downloads the file. 51 | * 52 | * @return {Buffer|PromiseLike} The downloaded data. 53 | */ 54 | readonly download?: () => Buffer | PromiseLike; 55 | /** @inheritdoc */ 56 | readonly type: FileSystemType; 57 | } 58 | 59 | /** 60 | * Information about an item on a file system. 61 | */ 62 | export interface FileSystemInfo { 63 | /** 64 | * An optional method to compare that object with another. 65 | */ 66 | readonly compareTo?: (other: FileSystemInfo) => number; 67 | /** 68 | * A value that can be used to export the path 69 | * to clipboard, e.g. 70 | */ 71 | readonly exportPath?: string; 72 | /** 73 | * A custom icon to use. 74 | */ 75 | readonly icon?: string; 76 | /** 77 | * The internal name of that item. 78 | */ 79 | readonly internal_name?: string; 80 | /** 81 | * The name of the item. 82 | */ 83 | readonly name: string; 84 | /** 85 | * The path. 86 | */ 87 | readonly path: string; 88 | /** 89 | * The size. 90 | */ 91 | readonly size?: number; 92 | /** 93 | * The timestamp. 94 | */ 95 | readonly time?: Moment.Moment; 96 | /** 97 | * The type of the item. 98 | */ 99 | readonly type?: FileSystemType; 100 | } 101 | 102 | /** 103 | * The type of a file system item. 104 | */ 105 | export enum FileSystemType { 106 | /** 107 | * Directory / folder 108 | */ 109 | Directory = 1, 110 | /** 111 | * File 112 | */ 113 | File = 2, 114 | } 115 | 116 | /** 117 | * An object with directory and file info objects. 118 | */ 119 | export interface WithDirectoriesAndFiles { 120 | /** 121 | * The directories. 122 | */ 123 | readonly dirs: DirectoryInfo[]; 124 | /** 125 | * The files. 126 | */ 127 | readonly files: FileInfo[]; 128 | } 129 | 130 | 131 | /** 132 | * Creates a default directory info object from a path. 133 | * 134 | * @param {string} dir The path of the directory. 135 | * @param {CreateDefaultDirectoryInfoOptions} [opts] Additional options. 136 | * 137 | * @return {DirectoryInfo} The created object. 138 | */ 139 | export function createDefaultDirectoryInfo(dir: string, opts?: CreateDefaultDirectoryInfoOptions): DirectoryInfo { 140 | dir = deploy_helpers.normalizePath(dir); 141 | 142 | if (!opts) { 143 | opts = {}; 144 | } 145 | 146 | let name: string; 147 | let path: string; 148 | let exportPath = deploy_helpers.toStringSafe(opts.exportPath); 149 | if (!deploy_helpers.isEmptyString(dir)) { 150 | path = Path.dirname(dir); 151 | if ('.' === path) { 152 | path = ''; 153 | } 154 | 155 | name = Path.basename(dir); 156 | } 157 | 158 | if (deploy_helpers.isEmptyString(name)) { 159 | name = ''; 160 | } 161 | if (deploy_helpers.isEmptyString(path)) { 162 | path = ''; 163 | } 164 | if (deploy_helpers.isEmptyString(exportPath)) { 165 | exportPath = '/'; 166 | } 167 | 168 | return { 169 | exportPath: exportPath, 170 | name: name, 171 | path: path, 172 | type: FileSystemType.Directory, 173 | }; 174 | } 175 | -------------------------------------------------------------------------------- /src/html.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_contracts from './contracts'; 19 | import * as deploy_helpers from './helpers'; 20 | import * as deploy_res_html from './resources/html'; 21 | import * as Marked from 'marked'; 22 | const MergeDeep = require('merge-deep'); 23 | import * as vscode from 'vscode'; 24 | 25 | 26 | /** 27 | * Options for openting a Markdown document. 28 | */ 29 | export interface MarkdownDocumentOptions extends Marked.MarkedOptions { 30 | /** 31 | * Custom CSS. 32 | */ 33 | readonly css?: string; 34 | /** 35 | * Custom document ID. 36 | */ 37 | readonly documentId?: any; 38 | /** 39 | * Custom document title. 40 | */ 41 | readonly documentTitle?: string; 42 | } 43 | 44 | 45 | /** 46 | * The URI protocol for opening a HTML document. 47 | */ 48 | export const HTML_URI_PROTOCOL = 'vscode-deploy-reloaded-html'; 49 | /** 50 | * The ID of the global command to open an HTML document. 51 | */ 52 | export const OPEN_HTML_DOC_COMMAND = 'extension.deploy.reloaded.openHtmlDoc'; 53 | 54 | const HTML_DOCS2: deploy_contracts.Document[] = []; 55 | let nextHtmlDocId = Number.MIN_SAFE_INTEGER; 56 | 57 | /** 58 | * Opens a HTML document in a new tab. 59 | * 60 | * @param {string} html The HTML document (source code). 61 | * @param {string} [title] The custom title for the tab. 62 | * @param {any} [id] The custom ID for the document in the storage. 63 | * 64 | * @returns {Promise} The promise with the result. 65 | */ 66 | export async function openHtmlDocument(html: string, title?: string, id?: any): Promise { 67 | let body: Buffer; 68 | let enc = 'utf8'; 69 | if (!deploy_helpers.isNullOrUndefined(html)) { 70 | body = new Buffer(deploy_helpers.toStringSafe(html), enc); 71 | } 72 | 73 | if (deploy_helpers.isNullOrUndefined(id)) { 74 | id = 'vscdr::431E0365-4388-4C61-9F6C-06275215E4B8::' + (nextHtmlDocId++); 75 | } 76 | 77 | const NEW_DOC: deploy_contracts.Document = { 78 | body: body, 79 | encoding: enc, 80 | id: id, 81 | mime: 'text/html', 82 | }; 83 | 84 | if (!deploy_helpers.isEmptyString(title)) { 85 | NEW_DOC.title = deploy_helpers.toStringSafe(title).trim(); 86 | } 87 | 88 | //Find existing column 89 | const column = vscode.window.activeTextEditor 90 | ? vscode.window.activeTextEditor.viewColumn 91 | : undefined; 92 | 93 | //Create webview panel 94 | const panel = vscode.window.createWebviewPanel( 95 | "VscdrGeneralHtmlWebView", 96 | NEW_DOC.title, 97 | column || vscode.ViewColumn.One, 98 | { 99 | enableScripts: false, 100 | } 101 | ); 102 | 103 | //Load content into webview 104 | panel.webview.html = NEW_DOC.body.toString(); 105 | return true; 106 | } 107 | 108 | /** 109 | * Opens a Markdown document in a new tab. 110 | * 111 | * @param {string} md The Markdown document (source code). 112 | * @param {MarkdownDocumentOptions} [opts] Custom options. 113 | * 114 | * @returns {Promise} The promise with the result. 115 | */ 116 | export async function openMarkdownDocument(md: string, opts?: MarkdownDocumentOptions) { 117 | if (!opts) { 118 | opts = {}; 119 | } 120 | 121 | const DEFAULT_OPTS: MarkdownDocumentOptions = { 122 | breaks: true, 123 | gfm: true, 124 | langPrefix: '', 125 | tables: true, 126 | }; 127 | 128 | const CSS = deploy_helpers.toStringSafe(opts.css); 129 | const DOCUMENT_ID = opts.documentId; 130 | const DOCUMENT_TITLE = opts.documentTitle; 131 | 132 | let html = await deploy_res_html.getStringContent("header.html"); 133 | 134 | if (!deploy_helpers.isEmptyString(CSS)) { 135 | html += ` 136 | 141 | `; 142 | } 143 | 144 | html += Marked( 145 | deploy_helpers.toStringSafe(md), 146 | MergeDeep(DEFAULT_OPTS, opts), 147 | ); 148 | 149 | html += await deploy_res_html.getStringContent("footer.html"); 150 | 151 | return await openHtmlDocument( 152 | html, 153 | DOCUMENT_TITLE, DOCUMENT_ID 154 | ); 155 | } 156 | -------------------------------------------------------------------------------- /src/lang/de-de.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as lang_de from './de'; 19 | 20 | // alias for 'de' 21 | export const translation = lang_de.translation; 22 | -------------------------------------------------------------------------------- /src/lang/en-gb.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as lang_en from './en'; 19 | 20 | // alias for 'en' 21 | export const translation = lang_en.translation; 22 | -------------------------------------------------------------------------------- /src/lang/en-us.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as lang_en from './en'; 19 | 20 | // alias for 'en' 21 | export const translation = lang_en.translation; 22 | -------------------------------------------------------------------------------- /src/mappings.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | 19 | /** 20 | * An folder mapping entry. 21 | */ 22 | export type FolderMappingEntry = string | FolderMappingSettings; 23 | 24 | /** 25 | * An object with folder mappings. 26 | */ 27 | export type FolderMappings = { [pattern: string]: FolderMappingEntry }; 28 | 29 | /** 30 | * Folder mapping settings. 31 | */ 32 | export interface FolderMappingSettings { 33 | /** 34 | * The target path if mapping matches. 35 | */ 36 | readonly to: string; 37 | } 38 | -------------------------------------------------------------------------------- /src/output.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_helpers from './helpers'; 19 | import * as deploy_log from './log'; 20 | import * as vscode from 'vscode'; 21 | 22 | 23 | /** 24 | * A channel writer. 25 | * 26 | * @param {string} text The text to write. 27 | * @param {boolean} addNewLine Add new line or not. 28 | */ 29 | export type ChannelWriter = (context: ChannelWriterContext) => void; 30 | 31 | /** 32 | * A context for a channel writer. 33 | */ 34 | export interface ChannelWriterContext { 35 | /** 36 | * Add new line or not. 37 | */ 38 | readonly addNewLine: boolean; 39 | /** 40 | * The base channel. 41 | */ 42 | readonly baseChannel: vscode.OutputChannel; 43 | /** 44 | * The text to write. 45 | */ 46 | readonly text: string; 47 | } 48 | 49 | 50 | /** 51 | * A wrapper for an output channel. 52 | */ 53 | export class OutputChannelWrapper extends deploy_helpers.DisposableBase implements vscode.OutputChannel { 54 | private readonly _OWNS_CHANNEL: boolean; 55 | private readonly _WRITERS: ChannelWriter[] = []; 56 | 57 | /** 58 | * Initializes a new instance of that class. 59 | * 60 | * @param {vscode.OutputChannel} baseChannel The base channel. 61 | * @param {boolean} [ownsChannel] Also dispose base channel or not. 62 | */ 63 | public constructor(public readonly baseChannel: vscode.OutputChannel, ownsChannel?: boolean) { 64 | super(); 65 | 66 | this._OWNS_CHANNEL = deploy_helpers.toBooleanSafe(ownsChannel); 67 | } 68 | 69 | /** 70 | * Adds a writer. 71 | * 72 | * @param {ChannelWriter} writer The writer to add. 73 | * 74 | * @chainable 75 | */ 76 | public addWriter(writer: ChannelWriter): this { 77 | if (writer) { 78 | this._WRITERS.push(writer); 79 | } 80 | 81 | return this; 82 | } 83 | 84 | /** @inheritdoc */ 85 | public append(value: any) { 86 | value = deploy_helpers.toStringSafe(value); 87 | 88 | this.invokeForBaseChannel(this.baseChannel.append, 89 | [ value ]); 90 | 91 | this.sendToWriters(value, false); 92 | } 93 | 94 | /** @inheritdoc */ 95 | public appendLine(value: any) { 96 | value = deploy_helpers.toStringSafe(value); 97 | 98 | this.invokeForBaseChannel(this.baseChannel.appendLine, 99 | [ value ]); 100 | 101 | this.sendToWriters(value, true); 102 | } 103 | 104 | /** @inheritdoc */ 105 | public clear() { 106 | this.invokeForBaseChannel(this.baseChannel.clear, arguments); 107 | } 108 | 109 | /** @inheritdoc */ 110 | public hide() { 111 | this.invokeForBaseChannel(this.baseChannel.hide, arguments); 112 | } 113 | 114 | private invokeForBaseChannel(method: (...args: any[]) => TResult, args?: IArguments | any[]): TResult { 115 | if (method) { 116 | return method.apply( 117 | this.baseChannel, 118 | args || [] 119 | ); 120 | } 121 | } 122 | 123 | /** @inheritdoc */ 124 | public get name() { 125 | return this.baseChannel.name; 126 | } 127 | 128 | /** @inheritdoc */ 129 | protected onDispose() { 130 | while (this._WRITERS.length > 0) { 131 | this._WRITERS.pop(); 132 | } 133 | 134 | if (this._OWNS_CHANNEL) { 135 | this.invokeForBaseChannel(this.baseChannel.dispose, []); 136 | } 137 | } 138 | 139 | private sendToWriters(text: string, addNewLine: boolean) { 140 | if ('' === text) { 141 | return; 142 | } 143 | 144 | for (const WRITER of this._WRITERS) { 145 | try { 146 | WRITER({ 147 | addNewLine: addNewLine, 148 | baseChannel: this.baseChannel, 149 | text: text, 150 | }); 151 | } 152 | catch (e) { 153 | deploy_log.CONSOLE 154 | .trace(e, 'output.OutputChannelWrapper.sendToWriters(1)'); 155 | } 156 | } 157 | } 158 | 159 | /** @inheritdoc */ 160 | public show() { 161 | this.invokeForBaseChannel(this.baseChannel.show, arguments); 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /src/plugins/azureblob.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_clients_azureblob from '../clients/azureblob'; 19 | import * as deploy_helpers from '../helpers'; 20 | import * as deploy_plugins from '../plugins'; 21 | import * as deploy_targets from '../targets'; 22 | 23 | 24 | interface AzureBlobContext extends deploy_plugins.AsyncFileClientPluginContext { 26 | } 27 | 28 | /** 29 | * An 'Azure blob' target. 30 | */ 31 | export interface AzureBlobTarget extends deploy_targets.Target { 32 | /** 33 | * The access key. 34 | */ 35 | readonly accessKey?: string; 36 | /** 37 | * The account name. 38 | */ 39 | readonly account?: string; 40 | /** 41 | * The container name. 42 | */ 43 | readonly container?: string; 44 | /** 45 | * The custom root directory. 46 | */ 47 | readonly dir?: string; 48 | /** 49 | * Hash content or not. 50 | */ 51 | readonly hashContent?: boolean; 52 | /** 53 | * The custom host address. 54 | */ 55 | readonly host?: string; 56 | /** 57 | * Use local development storage or not. 58 | */ 59 | readonly useDevelopmentStorage?: boolean; 60 | } 61 | 62 | class AzureBlobPlugin extends deploy_plugins.AsyncFileClientPluginBase { 65 | protected async createContext(target: AzureBlobTarget): Promise { 66 | const DIR = this.replaceWithValues(target, target.dir); 67 | 68 | return { 69 | client: deploy_clients_azureblob.createClient({ 70 | accessKey: this.replaceWithValues(target, target.accessKey), 71 | account: this.replaceWithValues(target, target.account), 72 | container: this.replaceWithValues(target, target.container), 73 | hashContent: target.hashContent, 74 | host: this.replaceWithValues(target, target.host), 75 | useDevelopmentStorage: target.useDevelopmentStorage, 76 | }), 77 | getDir: (subDir) => { 78 | return deploy_helpers.normalizePath( 79 | deploy_helpers.normalizePath(DIR).trim() + 80 | '/' + 81 | deploy_helpers.normalizePath(subDir).trim() 82 | ); 83 | }, 84 | target: target 85 | }; 86 | } 87 | } 88 | 89 | /** 90 | * Creates a new instance of that plugin. 91 | * 92 | * @param {deploy_plugins.PluginContext} context The context for the plugin. 93 | * 94 | * @return {deploy_plugins.Plugin} The new plugin. 95 | */ 96 | export function createPlugins(context: deploy_plugins.PluginContext) { 97 | return new AzureBlobPlugin(context); 98 | } 99 | -------------------------------------------------------------------------------- /src/plugins/batch.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_plugins from '../plugins'; 19 | import * as deploy_targets from '../targets'; 20 | 21 | 22 | /** 23 | * A 'batch' target. 24 | */ 25 | export interface BatchTarget extends deploy_targets.Target, deploy_targets.TargetProvider { 26 | } 27 | 28 | class BatchPlugin extends deploy_plugins.IterablePluginBase { 29 | } 30 | 31 | /** 32 | * Creates a new instance of that plugin. 33 | * 34 | * @param {deploy_plugins.PluginContext} context The context for the plugin. 35 | * 36 | * @return {deploy_plugins.Plugin} The new plugin. 37 | */ 38 | export function createPlugins(context: deploy_plugins.PluginContext) { 39 | return new BatchPlugin(context); 40 | } 41 | -------------------------------------------------------------------------------- /src/plugins/dropbox.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_clients_dropbox from '../clients/dropbox'; 19 | import * as deploy_helpers from '../helpers'; 20 | import * as deploy_plugins from '../plugins'; 21 | import * as deploy_targets from '../targets'; 22 | 23 | 24 | interface DropboxContext extends deploy_plugins.AsyncFileClientPluginContext { 26 | } 27 | 28 | /** 29 | * A 'Dropbox' target. 30 | */ 31 | export interface DropboxTarget extends deploy_targets.Target { 32 | /** 33 | * The root directory. 34 | */ 35 | readonly dir?: string; 36 | /** 37 | * The API token to use. 38 | */ 39 | readonly token: string; 40 | } 41 | 42 | class DropboxPlugin extends deploy_plugins.AsyncFileClientPluginBase { 45 | protected createContext(target: DropboxTarget): DropboxContext { 46 | const DIR = this.replaceWithValues(target, target.dir); 47 | 48 | return { 49 | client: deploy_clients_dropbox.createClient({ 50 | accessToken: this.replaceWithValues(target, target.token), 51 | }), 52 | getDir: (subDir) => { 53 | return deploy_helpers.normalizePath( 54 | deploy_helpers.normalizePath(DIR).trim() + 55 | '/' + 56 | deploy_helpers.normalizePath(subDir).trim() 57 | ); 58 | }, 59 | target: target 60 | }; 61 | } 62 | } 63 | 64 | /** 65 | * Creates a new instance of that plugin. 66 | * 67 | * @param {deploy_plugins.PluginContext} context The context for the plugin. 68 | * 69 | * @return {deploy_plugins.Plugin} The new plugin. 70 | */ 71 | export function createPlugins(context: deploy_plugins.PluginContext) { 72 | return new DropboxPlugin(context); 73 | } 74 | -------------------------------------------------------------------------------- /src/plugins/each.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_download from '../download'; 19 | import * as deploy_helpers from '../helpers'; 20 | import * as deploy_plugins from '../plugins'; 21 | import * as deploy_targets from '../targets'; 22 | import * as Enumerable from 'node-enumerable'; 23 | 24 | 25 | /** 26 | * A 'each' target. 27 | */ 28 | export interface EachTarget extends deploy_targets.Target, deploy_targets.TargetProvider { 29 | /** 30 | * A list of values or a source from where to load it. 31 | */ 32 | readonly from: string | any | any[]; 33 | /** 34 | * One or more property names where the source values should be written to. 35 | */ 36 | readonly 'to': string | string[]; 37 | /** 38 | * Use placeholders for string values or not. 39 | */ 40 | readonly usePlaceholders?: boolean; 41 | } 42 | 43 | class EachPlugin extends deploy_plugins.IterablePluginBase { 44 | protected async prepareTarget(eachTarget: EachTarget, target: deploy_targets.Target): Promise { 45 | const ME = this; 46 | const WORKSPACE = eachTarget.__workspace; 47 | 48 | const CLONED_TARGETS: deploy_targets.Target[] = []; 49 | 50 | let from: any = eachTarget.from; 51 | if (deploy_helpers.isString(from)) { 52 | // extrenal source 53 | 54 | const DOWNLOAD_SOURCE = ME.replaceWithValues( 55 | eachTarget, 56 | from 57 | ); 58 | 59 | from = JSON.parse( 60 | (await deploy_download.download(DOWNLOAD_SOURCE, 61 | WORKSPACE.getSettingScopes())).toString('utf8') 62 | ); 63 | } 64 | 65 | from = deploy_helpers.asArray(from, false); 66 | 67 | const TO = Enumerable.from(deploy_helpers.asArray(eachTarget.to)).select(t => { 68 | return deploy_helpers.toStringSafe(t).trim(); 69 | }).where(t => '' !== t) 70 | .toArray(); 71 | const USE_PLACE_HOLDERS = deploy_helpers.toBooleanSafe(eachTarget.usePlaceholders, true); 72 | 73 | for (const F of from) { 74 | const CT = deploy_helpers.cloneObjectFlat(target); 75 | 76 | for (const PROP of TO) { 77 | let valueToSet = F; 78 | if (deploy_helpers.isString(valueToSet)) { 79 | if (USE_PLACE_HOLDERS) { 80 | valueToSet = ME.replaceWithValues(eachTarget, valueToSet); 81 | } 82 | } 83 | 84 | CT[PROP] = valueToSet; 85 | } 86 | 87 | CLONED_TARGETS.push(CT); 88 | } 89 | 90 | return CLONED_TARGETS; 91 | } 92 | } 93 | 94 | /** 95 | * Creates a new instance of that plugin. 96 | * 97 | * @param {deploy_plugins.PluginContext} context The context for the plugin. 98 | * 99 | * @return {deploy_plugins.Plugin} The new plugin. 100 | */ 101 | export function createPlugins(context: deploy_plugins.PluginContext) { 102 | return new EachPlugin(context); 103 | } 104 | -------------------------------------------------------------------------------- /src/plugins/list.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_contracts from '../contracts'; 19 | import * as deploy_download from '../download'; 20 | import * as deploy_helpers from '../helpers'; 21 | import * as deploy_plugins from '../plugins'; 22 | import * as deploy_targets from '../targets'; 23 | const MergeDeep = require('merge-deep'); 24 | import * as vscode from 'vscode'; 25 | 26 | 27 | /** 28 | * A 'list' target. 29 | */ 30 | export interface ListTarget extends deploy_targets.Target, deploy_targets.TargetProvider { 31 | /** 32 | * One or more entries with settings to show or a source from where to download them. 33 | */ 34 | readonly entries: string | ListTargetEntry | ListTargetEntry[]; 35 | } 36 | 37 | /** 38 | * An entry of a list target. 39 | */ 40 | export interface ListTargetEntry extends deploy_contracts.WithOptionalName { 41 | /** 42 | * A description for the GUI. 43 | */ 44 | readonly description?: string; 45 | /** 46 | * The settings for the "real" target or a source from where to download them. 47 | */ 48 | readonly settings: string | ListTargetSettings; 49 | } 50 | 51 | /** 52 | * Settings for a "real" target. 53 | */ 54 | export type ListTargetSettings = { [key: string]: any } | string; 55 | 56 | class ListPlugin extends deploy_plugins.IterablePluginBase { 57 | protected async prepareTargetsMany(listTarget: ListTarget, targets: deploy_targets.Target | deploy_targets.Target[]): Promise { 58 | const ME = this; 59 | const WORKSPACE = listTarget.__workspace; 60 | 61 | const CLONED_TARGETS: deploy_targets.Target[] = []; 62 | 63 | let entries: string | ListTargetEntry | ListTargetEntry[]; 64 | if (!deploy_helpers.isObject(entries) && !Array.isArray(entries)) { 65 | // download from source 66 | const DOWNLOAD_SOURCE = ME.replaceWithValues( 67 | listTarget, 68 | entries 69 | ); 70 | 71 | entries = 72 | JSON.parse( 73 | (await deploy_download.download( 74 | DOWNLOAD_SOURCE, WORKSPACE.getSettingScopes() 75 | )).toString('utf8') 76 | ); 77 | } 78 | 79 | const QUICK_PICKS: deploy_contracts.ActionQuickPick[] = deploy_helpers.asArray(entries).map((e, i) => { 80 | let name = deploy_helpers.toStringSafe( 81 | ME.replaceWithValues(listTarget, e.name) 82 | ).trim(); 83 | if ('' === name) { 84 | name = listTarget.__workspace 85 | .t('plugins.list.defaultEntryName', i + 1); 86 | } 87 | 88 | const DESCRIPTION = deploy_helpers.toStringSafe( 89 | ME.replaceWithValues(listTarget, e.description) 90 | ).trim(); 91 | 92 | return { 93 | action: async () => { 94 | let settingsToApply = e.settings; 95 | if (!deploy_helpers.isObject(settingsToApply)) { 96 | // download from source 97 | const DOWNLOAD_SOURCE = ME.replaceWithValues( 98 | listTarget, 99 | settingsToApply 100 | ); 101 | 102 | settingsToApply = 103 | JSON.parse( 104 | (await deploy_download.download( 105 | DOWNLOAD_SOURCE, WORKSPACE.getSettingScopes() 106 | )).toString('utf8') 107 | ); 108 | } 109 | 110 | for (const T of deploy_helpers.asArray(targets)) { 111 | let ct = deploy_helpers.cloneObjectFlat(T); 112 | if (settingsToApply) { 113 | ct = MergeDeep(ct, settingsToApply); 114 | } 115 | 116 | CLONED_TARGETS.push(ct); 117 | } 118 | }, 119 | description: DESCRIPTION, 120 | label: name, 121 | }; 122 | }); 123 | 124 | const SELECTED_ITEM = await vscode.window.showQuickPick(QUICK_PICKS, { 125 | placeHolder: listTarget.__workspace 126 | .t('plugins.list.selectEntry'), 127 | }); 128 | 129 | if (!SELECTED_ITEM) { 130 | return false; 131 | } 132 | 133 | await Promise.resolve( 134 | SELECTED_ITEM.action() 135 | ); 136 | 137 | return CLONED_TARGETS; 138 | } 139 | } 140 | 141 | /** 142 | * Creates a new instance of that plugin. 143 | * 144 | * @param {deploy_plugins.PluginContext} context The context for the plugin. 145 | * 146 | * @return {deploy_plugins.Plugin} The new plugin. 147 | */ 148 | export function createPlugins(context: deploy_plugins.PluginContext) { 149 | return new ListPlugin(context); 150 | } 151 | -------------------------------------------------------------------------------- /src/plugins/mail.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_contracts from '../contracts'; 19 | import * as deploy_helpers from '../helpers'; 20 | import * as deploy_plugins from '../plugins'; 21 | import * as deploy_targets from '../targets'; 22 | import * as Enumerable from 'node-enumerable'; 23 | import * as Mailer from 'nodemailer'; 24 | const Zip = require('node-zip'); 25 | 26 | 27 | /** 28 | * A 'mail' target. 29 | */ 30 | export interface MailTarget extends deploy_targets.Target { 31 | /** 32 | * The address that sends the mail. 33 | */ 34 | readonly from: string; 35 | /** 36 | * The address of the SMTP host. 37 | */ 38 | readonly host?: string; 39 | /** 40 | * Ignore TLS or not. 41 | */ 42 | readonly ignoreTLS?: boolean; 43 | /** 44 | * The password for the authentication. 45 | */ 46 | readonly password?: string; 47 | /** 48 | * The custom TCP port of the SMTP host. 49 | */ 50 | readonly port?: number; 51 | /** 52 | * Reject unauthorized TLS or not. 53 | */ 54 | readonly rejectUnauthorized?: boolean; 55 | /** 56 | * SMTP requires TLS or not. 57 | */ 58 | readonly requireTLS?: boolean; 59 | /** 60 | * Use secure connection or not. 61 | */ 62 | readonly secure?: boolean; 63 | /** 64 | * The list of email addresses to send the file(s) to. 65 | */ 66 | readonly to: string | string[]; 67 | /** 68 | * The user for the authentication. 69 | */ 70 | readonly user?: string; 71 | } 72 | 73 | class MailPlugin extends deploy_plugins.PluginBase { 74 | private sendMail(transporter: Mailer.Transporter, opts: Mailer.SendMailOptions): Promise { 75 | return new Promise((resolve, reject) => { 76 | const COMPLETED = deploy_helpers.createCompletedAction(resolve, reject); 77 | 78 | try { 79 | transporter.sendMail(opts, (err, info) => { 80 | if (err) { 81 | COMPLETED(err); 82 | } 83 | else { 84 | COMPLETED(null, info); 85 | } 86 | }); 87 | } 88 | catch (e) { 89 | COMPLETED(e); 90 | } 91 | }); 92 | } 93 | 94 | public async uploadFiles(context: deploy_plugins.UploadContext) { 95 | const ME = this; 96 | 97 | const TARGET = context.target; 98 | 99 | const ZIPFile = new Zip(); 100 | const ZIPFilename = deploy_targets.getZipFileName(context.target); 101 | 102 | let from = deploy_helpers.normalizeString( 103 | ME.replaceWithValues(TARGET, TARGET.from) 104 | ); 105 | if ('' === from) { 106 | from = undefined; 107 | } 108 | 109 | const TO = Enumerable.from( deploy_helpers.asArray(TARGET.to) ).selectMany(t => { 110 | return deploy_helpers.toStringSafe(t) 111 | .split(','); 112 | }).select(t => deploy_helpers.normalizeString( 113 | ME.replaceWithValues(TARGET, t) 114 | )) 115 | .where(t => '' !== t) 116 | .toArray(); 117 | 118 | const IS_SECURE = deploy_helpers.toBooleanSafe(TARGET.secure, true); 119 | 120 | const IGNORE_TLS = deploy_helpers.toBooleanSafe(TARGET.ignoreTLS); 121 | const REQUIRE_TOLS = deploy_helpers.toBooleanSafe(TARGET.requireTLS); 122 | 123 | const REJECT_UNAUTHORIZED = deploy_helpers.toBooleanSafe(TARGET.rejectUnauthorized, true); 124 | 125 | let host = deploy_helpers.normalizeString( 126 | ME.replaceWithValues(TARGET, TARGET.host) 127 | ); 128 | if ('' === host) { 129 | host = '127.0.0.1'; 130 | } 131 | 132 | let port = parseInt( 133 | deploy_helpers.toStringSafe( 134 | ME.replaceWithValues(TARGET, TARGET.port) 135 | ).trim() 136 | ); 137 | if (isNaN(port)) { 138 | if (IS_SECURE) { 139 | port = REQUIRE_TOLS ? 587 : 465; 140 | } 141 | else { 142 | port = 25; 143 | } 144 | } 145 | 146 | let auth: any; 147 | let user = deploy_helpers.toStringSafe( 148 | ME.replaceWithValues(TARGET, TARGET.user) 149 | ); 150 | if (!deploy_helpers.isEmptyString(user)) { 151 | let password = deploy_helpers.toStringSafe(TARGET.password); 152 | if ('' === password) { 153 | password = undefined; 154 | } 155 | 156 | auth = { 157 | user: user, 158 | pass: password, 159 | }; 160 | } 161 | 162 | const ZIPPED_DATA = new Buffer(ZIPFile.generate({ 163 | base64: false, 164 | comment: deploy_contracts.ZIP_COMMENT, 165 | compression: 'DEFLATE', 166 | }), 'binary'); 167 | 168 | const MAIL_OPTS: Mailer.SendMailOptions = { 169 | from: from, 170 | to: TO, 171 | subject: ME.t(context.target, 'plugins.mail.subject'), 172 | text: ME.t(context.target, 'plugins.mail.text'), 173 | attachments: [ 174 | { 175 | filename: ZIPFilename, 176 | content: ZIPPED_DATA, 177 | } 178 | ] 179 | }; 180 | 181 | const TRANSPORTER = Mailer.createTransport({ 182 | host: host, 183 | port: port, 184 | auth: auth, 185 | secure: IS_SECURE, 186 | ignoreTLS: IGNORE_TLS, 187 | requireTLS: REQUIRE_TOLS, 188 | tls: { 189 | rejectUnauthorized: REJECT_UNAUTHORIZED, 190 | }, 191 | }); 192 | 193 | for (const F of context.files) { 194 | if (context.isCancelling) { 195 | return; 196 | } 197 | 198 | try { 199 | await F.onBeforeUpload(TO.join(', ')); 200 | 201 | ZIPFile.file(deploy_helpers.normalizePath(F.path + '/' + F.name), 202 | await F.read()); 203 | 204 | await F.onUploadCompleted(); 205 | } 206 | catch (e) { 207 | await F.onUploadCompleted(e); 208 | } 209 | } 210 | 211 | await ME.sendMail(TRANSPORTER, MAIL_OPTS); 212 | } 213 | } 214 | 215 | /** 216 | * Creates a new instance of that plugin. 217 | * 218 | * @param {deploy_plugins.PluginContext} context The context for the plugin. 219 | * 220 | * @return {deploy_plugins.Plugin} The new plugin. 221 | */ 222 | export function createPlugins(context: deploy_plugins.PluginContext) { 223 | return new MailPlugin(context); 224 | } 225 | -------------------------------------------------------------------------------- /src/plugins/map.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_download from '../download'; 19 | import * as deploy_helpers from '../helpers'; 20 | import * as deploy_plugins from '../plugins'; 21 | import * as deploy_targets from '../targets'; 22 | const MergeDeep = require('merge-deep'); 23 | 24 | 25 | /** 26 | * A 'map' target. 27 | */ 28 | export interface MapTarget extends deploy_targets.Target, deploy_targets.TargetProvider { 29 | /** 30 | * One or more sources with property values for the targets. 31 | */ 32 | readonly from: MapItem | MapItem[]; 33 | } 34 | 35 | /** 36 | * A map item. 37 | */ 38 | export type MapItem = string | Object; 39 | 40 | /** 41 | * Mappings for a target. 42 | */ 43 | export type TargetMappings = { [name: string]: any }; 44 | 45 | class MapPlugin extends deploy_plugins.IterablePluginBase { 46 | protected async prepareTarget(mapTarget: MapTarget, target: deploy_targets.Target): Promise { 47 | const ME = this; 48 | const WORKSPACE = mapTarget.__workspace; 49 | 50 | const CLONED_TARGETS: deploy_targets.Target[] = []; 51 | 52 | const MAPPINGS: TargetMappings[] = []; 53 | await deploy_helpers.forEachAsync(deploy_helpers.asArray(mapTarget.from), async (item) => { 54 | let itemsToAdd: TargetMappings[]; 55 | 56 | if (!deploy_helpers.isObject(item)) { 57 | const DOWNLOAD_SOURCE = ME.replaceWithValues( 58 | mapTarget, 59 | item 60 | ); 61 | 62 | itemsToAdd = deploy_helpers.asArray( 63 | JSON.parse( 64 | (await deploy_download.download( 65 | DOWNLOAD_SOURCE, 66 | WORKSPACE.getSettingScopes() 67 | )).toString('utf8') 68 | ) 69 | ); 70 | } 71 | else { 72 | itemsToAdd = [ item ]; 73 | } 74 | 75 | MAPPINGS.push 76 | .apply(MAPPINGS, itemsToAdd); 77 | }); 78 | 79 | for (const M of MAPPINGS) { 80 | let ct = deploy_helpers.cloneObjectFlat(target); 81 | ct = MergeDeep(ct, M); 82 | 83 | CLONED_TARGETS.push(ct); 84 | } 85 | 86 | return CLONED_TARGETS; 87 | } 88 | } 89 | 90 | /** 91 | * Creates a new instance of that plugin. 92 | * 93 | * @param {deploy_plugins.PluginContext} context The context for the plugin. 94 | * 95 | * @return {deploy_plugins.Plugin} The new plugin. 96 | */ 97 | export function createPlugins(context: deploy_plugins.PluginContext) { 98 | return new MapPlugin(context); 99 | } 100 | -------------------------------------------------------------------------------- /src/plugins/s3bucket.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_contracts from '../contracts'; 19 | import * as deploy_clients_s3bucket from '../clients/s3bucket'; 20 | import * as deploy_helpers from '../helpers'; 21 | import * as deploy_plugins from '../plugins'; 22 | import * as deploy_targets from '../targets'; 23 | import * as OS from 'os'; 24 | import * as Path from 'path'; 25 | 26 | 27 | interface S3BucketContext extends deploy_plugins.AsyncFileClientPluginContext { 29 | } 30 | 31 | /** 32 | * Filters for detecting the ACL for a file. 33 | */ 34 | export type S3BucketAclFilters = { [acl: string]: string | string[] | deploy_contracts.FileFilter }; 35 | 36 | /** 37 | * A 'S3 bucket' target. 38 | */ 39 | export interface S3BucketTarget extends deploy_targets.Target { 40 | /** 41 | * The custom ACL to set. 42 | */ 43 | readonly acl?: string | S3BucketAclFilters; 44 | /** 45 | * The name of the bucket. 46 | */ 47 | readonly bucket: string; 48 | /** 49 | * Credential settings. 50 | */ 51 | readonly credentials?: { 52 | /** 53 | * Configuration data for the credential provider. 54 | */ 55 | readonly config?: any; 56 | /** 57 | * The credential provider / type. 58 | */ 59 | readonly type?: string; 60 | }; 61 | /** 62 | * Custom options. 63 | */ 64 | readonly customOpts?: object; 65 | /** 66 | * The custom root directory. 67 | */ 68 | readonly dir?: string; 69 | } 70 | 71 | class S3BucketPlugin extends deploy_plugins.AsyncFileClientPluginBase { 74 | protected createContext(target: S3BucketTarget): S3BucketContext { 75 | const ME = this; 76 | 77 | const DIR = ME.replaceWithValues(target, target.dir); 78 | 79 | const FILTERS: deploy_contracts.KeyValuePairs = {}; 80 | if (deploy_helpers.isObject(target.acl)) { 81 | for (const ACL in target.acl) { 82 | const ITEM = target.acl[ACL]; 83 | 84 | let ff: deploy_contracts.FileFilter; 85 | if (deploy_helpers.isObject(ITEM)) { 86 | ff = ITEM; 87 | } 88 | else { 89 | ff = { 90 | files: deploy_helpers.asArray(ITEM), 91 | }; 92 | } 93 | 94 | FILTERS[ deploy_clients_s3bucket.getAclSafe(ACL) ] = ff; 95 | } 96 | } 97 | else { 98 | FILTERS[ deploy_clients_s3bucket.getAclSafe(target.acl) ] = { 99 | files: '**' 100 | }; 101 | } 102 | 103 | const SCOPES: string[] = []; 104 | SCOPES.push 105 | .apply(SCOPES, 106 | target.__workspace.getSettingScopes()); 107 | SCOPES.push( 108 | Path.resolve( 109 | Path.join( 110 | OS.homedir(), 111 | '.aws' 112 | ) 113 | ) 114 | ); 115 | 116 | return { 117 | client: deploy_clients_s3bucket.createClient({ 118 | acl: ME.replaceWithValues(target, target.acl), 119 | bucket: ME.replaceWithValues(target, target.bucket), 120 | credentials: target.credentials, 121 | customOpts: target.customOpts, 122 | directoryScopeProvider: () => { 123 | return SCOPES; 124 | }, 125 | fileAcl: (file, defAcl) => { 126 | for (const ACL in FILTERS) { 127 | if (deploy_helpers.checkIfDoesMatchByFileFilter('/' + file, 128 | deploy_helpers.toMinimatchFileFilter(FILTERS[ACL]))) { 129 | return ME.replaceWithValues(target, ACL); 130 | } 131 | } 132 | 133 | return defAcl; 134 | }, 135 | valueProvider: () => { 136 | return target.__workspace.getValues(); 137 | } 138 | }), 139 | getDir: (subDir) => { 140 | return deploy_helpers.normalizePath( 141 | deploy_helpers.normalizePath(DIR).trim() + 142 | '/' + 143 | deploy_helpers.normalizePath(subDir).trim() 144 | ); 145 | }, 146 | target: target 147 | }; 148 | } 149 | } 150 | 151 | /** 152 | * Creates a new instance of that plugin. 153 | * 154 | * @param {deploy_plugins.PluginContext} context The context for the plugin. 155 | * 156 | * @return {deploy_plugins.Plugin} The new plugin. 157 | */ 158 | export function createPlugins(context: deploy_plugins.PluginContext) { 159 | return new S3BucketPlugin(context); 160 | } 161 | -------------------------------------------------------------------------------- /src/plugins/slack.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_clients_slack from '../clients/slack'; 19 | import * as deploy_contracts from '../contracts'; 20 | import * as deploy_files from '../files'; 21 | import * as deploy_helpers from '../helpers'; 22 | import * as deploy_plugins from '../plugins'; 23 | import * as deploy_targets from '../targets'; 24 | import * as Enumerable from 'node-enumerable'; 25 | const Zip = require('node-zip'); 26 | 27 | 28 | /** 29 | * A 'test' target. 30 | */ 31 | export interface SlackTarget extends deploy_targets.Target { 32 | /** 33 | * One or more channels to deploy to. 34 | */ 35 | readonly channels: string | string[]; 36 | 37 | /** 38 | * The API token to use. 39 | */ 40 | readonly token: string; 41 | } 42 | 43 | class SlackPlugin extends deploy_plugins.PluginBase { 44 | public get canList() { 45 | return true; 46 | } 47 | 48 | private async invokeForClient(target: SlackTarget, 49 | action: (client: deploy_clients_slack.SlackClient, target: SlackTarget) => TResult | PromiseLike): Promise { 50 | const CLIENT = deploy_clients_slack.createClient({ 51 | token: deploy_helpers.toStringSafe( 52 | this.replaceWithValues(target, target.token) 53 | ).trim(), 54 | }); 55 | try { 56 | return await Promise.resolve( 57 | action(CLIENT, target) 58 | ); 59 | } 60 | finally { 61 | deploy_helpers.tryDispose(CLIENT); 62 | } 63 | } 64 | 65 | public async listDirectory(context: deploy_plugins.ListDirectoryContext): Promise> { 66 | const ME = this; 67 | 68 | return await ME.invokeForClient(context.target, async (client, t) => { 69 | const RESULT: deploy_plugins.ListDirectoryResult = { 70 | dirs: [], 71 | files: [], 72 | info: deploy_files.createDefaultDirectoryInfo(context.dir), 73 | others: [], 74 | target: t, 75 | }; 76 | 77 | const LIST = await client.listDirectory(context.dir); 78 | for (const FSI of LIST) { 79 | if (!FSI) { 80 | continue; 81 | } 82 | 83 | switch (FSI.type) { 84 | case deploy_files.FileSystemType.Directory: 85 | RESULT.dirs.push(FSI); 86 | break; 87 | 88 | case deploy_files.FileSystemType.File: 89 | RESULT.files.push(FSI); 90 | break; 91 | 92 | default: 93 | RESULT.others.push(FSI); 94 | break; 95 | } 96 | } 97 | 98 | return RESULT; 99 | }); 100 | } 101 | 102 | public async uploadFiles(context: deploy_plugins.UploadContext): Promise { 103 | const ME = this; 104 | 105 | await ME.invokeForClient(context.target, async (client, t) => { 106 | const CHANNELS = Enumerable.from( 107 | deploy_helpers.asArray(t.channels) 108 | ).selectMany(c => { 109 | return deploy_helpers.toStringSafe( ME.replaceWithValues(t, c) ) 110 | .split(','); 111 | }).select(c => { 112 | return c.toUpperCase() 113 | .trim(); 114 | }).where(c => { 115 | return '' !== c; 116 | }).toArray(); 117 | 118 | for (const C of CHANNELS) { 119 | const FILES_TO_UPLOAD = context.files; 120 | 121 | const FOR_FILE = async (index: number, action: (f: deploy_plugins.FileToUpload) => any) => { 122 | const FILE = FILES_TO_UPLOAD[index]; 123 | 124 | try { 125 | FILE.onBeforeUpload( 126 | CHANNELS.join(', ') 127 | ); 128 | 129 | await Promise.resolve( 130 | action(FILE) 131 | ); 132 | 133 | FILE.onUploadCompleted(); 134 | } 135 | catch (e) { 136 | FILE.onUploadCompleted(e); 137 | } 138 | }; 139 | 140 | if (1 === FILES_TO_UPLOAD.length) { 141 | await FOR_FILE(0, async (f) => { 142 | await client.uploadFile(C + '/' + f.name, 143 | await f.read()); 144 | }); 145 | } 146 | else { 147 | const ZIPFile = new Zip(); 148 | const ZIPFilename = deploy_targets.getZipFileName(context.target); 149 | 150 | for (let i = 0; i < FILES_TO_UPLOAD.length; i++) { 151 | await FOR_FILE(i, async (f) => { 152 | ZIPFile.file(deploy_helpers.normalizePath(f.path + '/' + f.name), 153 | await f.read()); 154 | }); 155 | } 156 | 157 | const ZIPPED_DATA = new Buffer(ZIPFile.generate({ 158 | base64: false, 159 | comment: deploy_contracts.ZIP_COMMENT, 160 | compression: 'DEFLATE', 161 | }), 'binary'); 162 | 163 | await client.uploadFile(C + '/' + ZIPFilename, 164 | ZIPPED_DATA); 165 | } 166 | } 167 | }); 168 | } 169 | } 170 | 171 | /** 172 | * Creates a new instance of that plugin. 173 | * 174 | * @param {deploy_plugins.PluginContext} context The context for the plugin. 175 | * 176 | * @return {deploy_plugins.Plugin} The new plugin. 177 | */ 178 | export function createPlugins(context: deploy_plugins.PluginContext) { 179 | return new SlackPlugin(context); 180 | } 181 | -------------------------------------------------------------------------------- /src/plugins/switch.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_contracts from '../contracts'; 19 | import * as deploy_plugins from '../plugins'; 20 | import * as deploy_targets from '../targets'; 21 | import * as deploy_workspaces from '../workspaces'; 22 | 23 | class SwitchPlugin extends deploy_plugins.IterablePluginBase { 24 | protected async getTargets(switchTarget: deploy_workspaces.SwitchTarget, operation: deploy_contracts.DeployOperation, throwIfNonFound = false) 25 | : Promise 26 | { 27 | const WORKSPACE = switchTarget.__workspace; 28 | 29 | const TARGETS = WORKSPACE.getTargetsOfSwitch(switchTarget); 30 | if (false === TARGETS) { 31 | return false; 32 | } 33 | 34 | return TARGETS; 35 | } 36 | } 37 | 38 | /** 39 | * Creates a new instance of that plugin. 40 | * 41 | * @param {deploy_plugins.PluginContext} context The context for the plugin. 42 | * 43 | * @return {deploy_plugins.Plugin} The new plugin. 44 | */ 45 | export function createPlugins(context: deploy_plugins.PluginContext) { 46 | return new SwitchPlugin(context); 47 | } 48 | -------------------------------------------------------------------------------- /src/resources.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_helpers from './helpers'; 19 | import * as deploy_log from './log'; 20 | 21 | 22 | const REGEX_TEMPLATE_VARS = /(\/\*)(\s+)(VSCODE)(\-)(DEPLOY)(\-)(RELOADED)(\s+)(src\=\")([^\"]*)(\")((\s+)(format\=\")([^\"]*)(\"))?(\s+)(\*\/)/ig; 23 | 24 | 25 | /** 26 | * Replaces template variables with its linked content. 27 | * 28 | * @param {any} src The content to parse. 29 | * 30 | * @return {string} The parsed content. 31 | */ 32 | export function replaceTemplateVars(src: any): string { 33 | if (!src) { 34 | return src; 35 | } 36 | 37 | src = deploy_helpers.toStringSafe(src); 38 | 39 | return src.replace(REGEX_TEMPLATE_VARS, function(match) { 40 | try { 41 | // src="" 42 | if (arguments.length > 10) { 43 | const SRC_ATTR = deploy_helpers.toStringSafe(arguments[10]).trim(); 44 | 45 | const RES_MODULE = SRC_ATTR.substr(0, SRC_ATTR.indexOf('/')) 46 | .trim(); 47 | const RES_NAME = SRC_ATTR.substr(SRC_ATTR.indexOf('/') + 1) 48 | .trim(); 49 | 50 | let strContent = require(`./resources/${RES_MODULE}`).getStringContentSync(RES_NAME); 51 | 52 | // format="" 53 | if ('undefined' !== typeof arguments[15]) { 54 | deploy_helpers.toStringSafe(arguments[15]).split(',').forEach(e => { 55 | e = deploy_helpers.normalizeString(e); 56 | if ('' !== e) { 57 | switch (e) { 58 | case 'base64': 59 | strContent = (new Buffer(strContent, 'utf8')).toString('base64'); 60 | break; 61 | 62 | case 'json': 63 | strContent = JSON.stringify( strContent ); 64 | break; 65 | 66 | default: 67 | throw new Error(`'${e}' formatter not supported!`); 68 | } 69 | } 70 | }); 71 | } 72 | 73 | return strContent; 74 | } 75 | } 76 | catch (e) { 77 | deploy_log.CONSOLE 78 | .trace(e, 'resources.replaceTemplateVars()'); 79 | } 80 | 81 | return match; 82 | }); 83 | } 84 | -------------------------------------------------------------------------------- /src/resources/css.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | 19 | /** 20 | * AUTO GENERATED CODE 21 | */ 22 | 23 | import * as deploy_helpers from '../helpers'; 24 | import * as deploy_resources from '../resources'; 25 | import * as ZLib from 'zlib'; 26 | 27 | 28 | const REPOSITORY = { 29 | // START: style.css 30 | "style.css": new Buffer("H4sIAAAAAAAACo1Q3crCMAy9H+wdAuKdg82/Qfc02RpssTal7fc5Ed/doJswvLFwoJyfnJCyMM0GzFawE+wFB8ER7mUB8gZHGBX0nE33ZrRNweFNOMfDeSIvGE/WV2LLfFHQbMM4KVersxGmrtfCPMqiLPAznB3L8Eh6Mmcac6Vp4IjZslfg2VMnwpxUhv8pzvkv+5/XFJ1dZDL2juZEz1Ecsk4YYdW2LSR2dm5/i1UKOFh/UlAvednWYUikIFFAqaRuUZH1Bqaf+akvoNavoqOoTf06mcx7AlJvfWSTAQAA", 'base64'), 31 | // END: style.css 32 | 33 | // START: hl.railscasts.css 34 | "hl.railscasts.css": new Buffer("H4sIAAAAAAAACq1UwY6bMBC9R8o/WKoq7a6WLCSBAr320msP7bEa2wNxY+wUD5tEVf+9JttAbG3bS4WENI/33ozHMzw9LBfLxSdQ2glw5BKt9sgcnTWyO3HPPitnG3pkH41YsbsP0Ck07MtOEd6Pwoen8b3a6W+O/VguGJPKHTSca8a1Ffv3I2SfsW+0PSanmsFA9gIeQEpl2pqlqxy7C8RB7NveDkbW7M16Mz4XXFhtew9hgZkUHvo55UyE7To09HiNvw+W8KWSq4yLapuXF6fGGkouZ6uZItAqctvj+Wh7Obk51CjI9glBG5qKdbHepKHaUe9PNInN0HHsp7DHFk+HKXyGXgHXOAGEnW8c4fQlTAi5T5lFCQfuKKTlWdXkUV2++Lko6CJjLHlTQKQ4HyKWhG21qa6sqYBzx62ezPmgNdJNqDR9VSYElLkUMYFANDdJK7MPExeyEhzD8g7QQ+eiAlOZNk3IG60VH+KBEBLKogqpHRKErIqXeSWjvii6uTHnZ0NZE8qaRhRFJBtHfWbOY55cRdl2u87Wrw/7zUop4/uDybxZRyVpV7MsTd+GGaUf3L9mLNL0P6ab9kRocC7u47t00/yBr2RILnlVAg/Jfi924NRv23+tsF9Ca9ob7hFVuyP/P7I6upZ52AhP5HsmbA9j12rmW4X9ePoXxS/I9ITHJQUAAA==", 'base64'), 35 | // END: hl.railscasts.css 36 | 37 | }; 38 | 39 | 40 | /** 41 | * A possible value for a repository key. 42 | */ 43 | export type RepositoryKey = "style.css" | "hl.railscasts.css"; 44 | 45 | 46 | /** 47 | * Tries to return content from 'REPOSITORY' constant. 48 | * 49 | * @param {RepositoryKey} key The key inside the constant. 50 | * 51 | * @return {Promise} The promise with the data (if available). 52 | */ 53 | export function getContent(key: RepositoryKey): Promise { 54 | return new Promise((resolve, reject) => { 55 | let data: Buffer; 56 | 57 | for (const P in REPOSITORY) { 58 | if (P === key) { 59 | data = REPOSITORY[P]; 60 | break; 61 | } 62 | } 63 | 64 | if (data) { 65 | ZLib.gunzip(data, (err, uncompressedData) => { 66 | if (err) { 67 | reject(err); 68 | } 69 | else { 70 | resolve(uncompressedData); 71 | } 72 | }); 73 | } 74 | else { 75 | resolve(data); 76 | } 77 | }); 78 | } 79 | 80 | /** 81 | * Tries to return content from 'REPOSITORY' constant. 82 | * 83 | * @param {RepositoryKey} key The key inside the constant. 84 | * 85 | * @return Buffer The data (if available). 86 | */ 87 | export function getContentSync(key: RepositoryKey): Buffer { 88 | let data: Buffer; 89 | 90 | for (const P in REPOSITORY) { 91 | if (P === key) { 92 | data = REPOSITORY[P]; 93 | break; 94 | } 95 | } 96 | 97 | if (data) { 98 | return ZLib.gunzipSync(data); 99 | } 100 | 101 | return data; 102 | } 103 | 104 | /** 105 | * Tries to return content from 'REPOSITORY' constant as string. 106 | * 107 | * @param {RepositoryKey} key The key inside the constant. 108 | * @param {string} [enc] The encoding to use. Default: 'utf8'. 109 | * 110 | * @return {Promise} The promise with the data (if available). 111 | */ 112 | export async function getStringContent(key: RepositoryKey, enc?: string): Promise { 113 | enc = deploy_helpers.normalizeString(enc); 114 | if ('' === enc) { 115 | enc = 'utf8'; 116 | } 117 | 118 | const DATA = await getContent(key); 119 | if (DATA) { 120 | return deploy_resources.replaceTemplateVars( 121 | DATA.toString(enc) 122 | ); 123 | } 124 | } 125 | 126 | /** 127 | * Tries to return content from 'REPOSITORY' constant as string. 128 | * 129 | * @param {RepositoryKey} key The key inside the constant. 130 | * @param {string} [enc] The encoding to use. Default: 'utf8'. 131 | * 132 | * @return {string} The data (if available). 133 | */ 134 | export function getStringContentSync(key: RepositoryKey, enc?: string): string { 135 | enc = deploy_helpers.normalizeString(enc); 136 | if ('' === enc) { 137 | enc = 'utf8'; 138 | } 139 | 140 | const DATA = getContentSync(key); 141 | if (DATA) { 142 | return deploy_resources.replaceTemplateVars( 143 | DATA.toString(enc) 144 | ); 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/resources/html.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | 19 | /** 20 | * AUTO GENERATED CODE 21 | */ 22 | 23 | import * as deploy_helpers from '../helpers'; 24 | import * as deploy_resources from '../resources'; 25 | import * as ZLib from 'zlib'; 26 | 27 | 28 | const REPOSITORY = { 29 | // START: footer.html 30 | "footer.html": new Buffer("H4sIAAAAAAAAClNQUFDg5VKAApvi5KLMghKFksqCVFulktSKEv2sxLJEiKiSHS8XL5e+lkJYsLO/i6uui2uAj3+kbpCrj7+ji6uLQnFRsq0SQrk+hNLLKlZS0NIHaYXbApWygwjZ6Cflp1QCOTb6GSW5OXYAfyZrJ5MAAAA=", 'base64'), 31 | // END: footer.html 32 | 33 | // START: header.html 34 | "header.html": new Buffer("H4sIAAAAAAAACsVTbWvbMBD+Pth/UA3DchrJaQih0KQQYg8GgXR9g34qiqzW8mTJky5hZuS/T7bTNR0dy6BQgznf+e557rmTJkfJcn59d5GiHEp1/vHDZGeRfya5YNnuu/VLAQzxnFknYBrcXH8mp4H/v5fhoFYCQV2JaQDiB8TcuS4l7qHbq/kySUmSXiyWd+QyXSxnSZogZ/k08HlxrqhlUjnOHDjaVKJe/AI+bvHfkLItPpyKW1nBPlfBNqyLdpQPa81BGo02jmf2fjUeJYKbTNxo2RjswEboZwdpBaytRlmXcPllbsrKaKEBz6xlNa2sAdNw0ZJVlDOlMAOzajH66IkJ89+Ae6DhpxAdIxwOBo3ltFna3NPMAA8iCuYKrNSP+GQcRdQpyQUmw6hD2Ua0MFLjMIx8ZPvHUFqtL6dyRAjK5WOu/Au0cIiQ8/8amtgwhbuKv4ztH5t8BoyfG6kY/+a7CdCDsSXz53XFnBiP+oUzutm2FxedHaau+LoWtn5XXcX3pgUypEM6oqXUByhreF9V17m7y71zVyarvfcLA0j+EBAEAAA=", 'base64'), 35 | // END: header.html 36 | 37 | }; 38 | 39 | 40 | /** 41 | * A possible value for a repository key. 42 | */ 43 | export type RepositoryKey = "footer.html" | "header.html"; 44 | 45 | 46 | /** 47 | * Tries to return content from 'REPOSITORY' constant. 48 | * 49 | * @param {RepositoryKey} key The key inside the constant. 50 | * 51 | * @return {Promise} The promise with the data (if available). 52 | */ 53 | export function getContent(key: RepositoryKey): Promise { 54 | return new Promise((resolve, reject) => { 55 | let data: Buffer; 56 | 57 | for (const P in REPOSITORY) { 58 | if (P === key) { 59 | data = REPOSITORY[P]; 60 | break; 61 | } 62 | } 63 | 64 | if (data) { 65 | ZLib.gunzip(data, (err, uncompressedData) => { 66 | if (err) { 67 | reject(err); 68 | } 69 | else { 70 | resolve(uncompressedData); 71 | } 72 | }); 73 | } 74 | else { 75 | resolve(data); 76 | } 77 | }); 78 | } 79 | 80 | /** 81 | * Tries to return content from 'REPOSITORY' constant. 82 | * 83 | * @param {RepositoryKey} key The key inside the constant. 84 | * 85 | * @return Buffer The data (if available). 86 | */ 87 | export function getContentSync(key: RepositoryKey): Buffer { 88 | let data: Buffer; 89 | 90 | for (const P in REPOSITORY) { 91 | if (P === key) { 92 | data = REPOSITORY[P]; 93 | break; 94 | } 95 | } 96 | 97 | if (data) { 98 | return ZLib.gunzipSync(data); 99 | } 100 | 101 | return data; 102 | } 103 | 104 | /** 105 | * Tries to return content from 'REPOSITORY' constant as string. 106 | * 107 | * @param {RepositoryKey} key The key inside the constant. 108 | * @param {string} [enc] The encoding to use. Default: 'utf8'. 109 | * 110 | * @return {Promise} The promise with the data (if available). 111 | */ 112 | export async function getStringContent(key: RepositoryKey, enc?: string): Promise { 113 | enc = deploy_helpers.normalizeString(enc); 114 | if ('' === enc) { 115 | enc = 'utf8'; 116 | } 117 | 118 | const DATA = await getContent(key); 119 | if (DATA) { 120 | return deploy_resources.replaceTemplateVars( 121 | DATA.toString(enc) 122 | ); 123 | } 124 | } 125 | 126 | /** 127 | * Tries to return content from 'REPOSITORY' constant as string. 128 | * 129 | * @param {RepositoryKey} key The key inside the constant. 130 | * @param {string} [enc] The encoding to use. Default: 'utf8'. 131 | * 132 | * @return {string} The data (if available). 133 | */ 134 | export function getStringContentSync(key: RepositoryKey, enc?: string): string { 135 | enc = deploy_helpers.normalizeString(enc); 136 | if ('' === enc) { 137 | enc = 'utf8'; 138 | } 139 | 140 | const DATA = getContentSync(key); 141 | if (DATA) { 142 | return deploy_resources.replaceTemplateVars( 143 | DATA.toString(enc) 144 | ); 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/sql.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_sql_mssql from './sql/mssql'; 19 | import * as deploy_sql_mysql from './sql/mysql'; 20 | import * as i18 from './i18'; 21 | import * as vscode from 'vscode'; 22 | 23 | 24 | /** 25 | * A SQL connection. 26 | */ 27 | export interface SqlConnection extends vscode.Disposable { 28 | /** 29 | * The underlying connection object. 30 | */ 31 | readonly connection: any; 32 | /** 33 | * Closes the connection. 34 | * 35 | * @returns {PromiseLike} The promise that indicates if operation was successful or not. 36 | */ 37 | readonly close: () => PromiseLike; 38 | /** 39 | * Starts a query. 40 | * 41 | * @param {string} sql The SQL command. 42 | * @param {any[]} [args] One or more arguments for the command. 43 | * 44 | * @return {SqlResult[]} The promise with the result(s). 45 | */ 46 | readonly query: (sql: string, ...args: any[]) => PromiseLike; 47 | /** 48 | * The type. 49 | */ 50 | readonly type: SqlConnectionType; 51 | } 52 | 53 | type SqlConnectionFactory = (opts?: SqlConnectionOptions) => SqlConnection | PromiseLike; 54 | 55 | 56 | /** 57 | * Options for a SQL connection. 58 | */ 59 | export interface SqlConnectionOptions { 60 | } 61 | 62 | /** 63 | * A result of a SQL query. 64 | */ 65 | export interface SqlResult { 66 | /** 67 | * The underlying connection. 68 | */ 69 | readonly connection: SqlConnection; 70 | /** 71 | * Gets the rows that have been returned by the query. 72 | */ 73 | readonly rows?: ArrayLike<{ [name: string]: any }>; 74 | } 75 | 76 | 77 | /** 78 | * List of known SQL connection types. 79 | */ 80 | export enum SqlConnectionType { 81 | /** 82 | * MySQL 83 | */ 84 | MySql = 0, 85 | /** 86 | * Microsoft SQL 87 | */ 88 | MSSql = 1, 89 | } 90 | 91 | 92 | /** 93 | * Opens a SQL connection. 94 | * 95 | * @param {SqlConnectionType} type The type / engine. 96 | * @param {SqlConnectionOptions} [opts] The options. 97 | * 98 | * @returns {Promise} The promise with the new, open connection. 99 | */ 100 | export async function openSqlConnection(type: SqlConnectionType, opts?: SqlConnectionOptions): Promise { 101 | let factory: SqlConnectionFactory; 102 | switch (type) { 103 | case SqlConnectionType.MSSql: 104 | // Microsoft SQL 105 | factory = deploy_sql_mssql.openMSSQLConnection; 106 | break; 107 | 108 | case SqlConnectionType.MySql: 109 | // MySQL 110 | factory = deploy_sql_mysql.openMySQLConnection; 111 | break; 112 | } 113 | 114 | if (!factory) { 115 | throw new Error(i18.t('sql.notSupported', type)); 116 | } 117 | 118 | return await Promise.resolve( 119 | factory(opts) 120 | ); 121 | } 122 | -------------------------------------------------------------------------------- /src/sql/mysql.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_contracts from '../contracts'; 19 | import * as deploy_helpers from '../helpers'; 20 | import * as deploy_sql from '../sql'; 21 | import * as MySQL from '../../node_modules/mysql'; 22 | 23 | 24 | /** 25 | * Options for a MySQL connection. 26 | */ 27 | export interface MySQLOptions extends deploy_sql.SqlConnectionOptions { 28 | /** 29 | * The charset to use. 30 | */ 31 | readonly charset?: string; 32 | /** 33 | * The database to connect to. 34 | */ 35 | readonly database?: string; 36 | /** 37 | * The host. 38 | */ 39 | readonly host?: string; 40 | /** 41 | * The TCP port. 42 | */ 43 | readonly port?: number; 44 | /** 45 | * The password. 46 | */ 47 | readonly password?: string; 48 | /** 49 | * Reject untrusted SSL connections or not. 50 | */ 51 | readonly rejectUnauthorized?: boolean; 52 | /** 53 | * The username. 54 | */ 55 | readonly user?: string; 56 | } 57 | 58 | /** 59 | * A result of a MySQL query. 60 | */ 61 | export interface MySQLResult extends deploy_sql.SqlResult { 62 | /** @inheritdoc */ 63 | readonly connection: MySQLConnection; 64 | } 65 | 66 | 67 | /** 68 | * A MySQL connection. 69 | */ 70 | export class MySQLConnection extends deploy_helpers.DisposableBase implements deploy_sql.SqlConnection { 71 | /** 72 | * Initializes a new instance of that class. 73 | * 74 | * @param {MySQL.Connection} connection The underlying connection instance. 75 | */ 76 | constructor(public connection: MySQL.Connection) { 77 | super(); 78 | } 79 | 80 | /** @inheritdoc */ 81 | public close() { 82 | const ME = this; 83 | 84 | return new Promise(async (resolve, reject) => { 85 | const COMPLETED = deploy_helpers.createCompletedAction(resolve, reject); 86 | 87 | const OLD_CONNECTION = ME.connection; 88 | if (!OLD_CONNECTION) { 89 | COMPLETED(null, false); 90 | return; 91 | } 92 | 93 | try { 94 | OLD_CONNECTION.end((err) => { 95 | if (err) { 96 | COMPLETED(err); 97 | } 98 | else { 99 | ME.connection = null; 100 | COMPLETED(null, true); 101 | } 102 | }); 103 | } 104 | catch (e) { 105 | COMPLETED(e); 106 | } 107 | }); 108 | } 109 | 110 | /** @inheritdoc */ 111 | protected onDispose() { 112 | this.close(); 113 | } 114 | 115 | /** @inheritdoc */ 116 | public query(sql: string, ...args: any[]): Promise { 117 | const ME = this; 118 | 119 | return new Promise((resolve, reject) => { 120 | const COMPLETED = deploy_helpers.createCompletedAction(resolve, reject); 121 | 122 | try { 123 | ME.connection.query( 124 | deploy_helpers.toStringSafe(sql), 125 | deploy_helpers.asArray(args), 126 | (err, rows) => { 127 | if (err) { 128 | COMPLETED(err); 129 | } 130 | else { 131 | COMPLETED(null, [ 132 | { 133 | connection: ME, 134 | rows: rows, 135 | } 136 | ]); 137 | } 138 | }); 139 | } 140 | catch (e) { 141 | COMPLETED(e); 142 | } 143 | }); 144 | } 145 | 146 | /** @inheritdoc */ 147 | public readonly type = deploy_sql.SqlConnectionType.MySql; 148 | } 149 | 150 | 151 | /** 152 | * Opens a MySQL connection. 153 | * 154 | * @param {MySQLOptions} [opts] The options. 155 | * 156 | * @return {Promise} The promise with the new connection. 157 | */ 158 | export async function openMySQLConnection(opts?: MySQLOptions) { 159 | if (!opts) { 160 | opts = {}; 161 | } 162 | 163 | return new Promise(async (resolve, reject) => { 164 | const COMPLETED = deploy_helpers.createCompletedAction(resolve, reject); 165 | 166 | try { 167 | let host = deploy_helpers.normalizeString(opts.host); 168 | if ('' === host) { 169 | host = deploy_contracts.DEFAULT_HOST; 170 | } 171 | 172 | let port = parseInt( 173 | deploy_helpers.toStringSafe(opts.port).trim() 174 | ); 175 | if (isNaN(port)) { 176 | port = 3306; 177 | } 178 | 179 | let user = deploy_helpers.toStringSafe(opts.user).trim(); 180 | if ('' === user) { 181 | user = 'root'; 182 | } 183 | 184 | let pwd = deploy_helpers.toStringSafe(opts.password); 185 | if ('' === pwd) { 186 | pwd = undefined; 187 | } 188 | 189 | let db = deploy_helpers.toStringSafe(opts.database).trim(); 190 | if ('' === db) { 191 | db = undefined; 192 | } 193 | 194 | let charset = deploy_helpers.normalizeString(opts.charset); 195 | if ('' === charset) { 196 | charset = undefined; 197 | } 198 | 199 | let ssl: any; 200 | if (!deploy_helpers.isNullOrUndefined(opts.rejectUnauthorized)) { 201 | ssl = { 202 | rejectUnauthorized: deploy_helpers.toBooleanSafe(opts.rejectUnauthorized, true), 203 | }; 204 | } 205 | 206 | const CONN_OPTS: MySQL.ConnectionConfig = { 207 | charset: charset, 208 | database: db, 209 | host: host, 210 | port: port, 211 | user: user, 212 | password: pwd, 213 | ssl: ssl, 214 | }; 215 | 216 | const CONN = MySQL.createConnection(CONN_OPTS); 217 | 218 | CONN.connect(function(err) { 219 | if (err) { 220 | COMPLETED(err); 221 | } 222 | else { 223 | COMPLETED(null, 224 | new MySQLConnection(CONN)); 225 | } 226 | }); 227 | } 228 | catch (e) { 229 | COMPLETED(e); 230 | } 231 | }); 232 | } 233 | -------------------------------------------------------------------------------- /src/switch.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_contracts from './contracts'; 19 | import * as deploy_helpers from './helpers'; 20 | import * as deploy_targets from './targets'; 21 | import * as deploy_workspaces from './workspaces'; 22 | import * as Enumerable from 'node-enumerable'; 23 | import * as i18 from './i18'; 24 | import * as vscode from 'vscode'; 25 | 26 | 27 | /** 28 | * Lets the user change an option of a switch. 29 | * 30 | * @param {deploy_workspaces.Workspace|deploy_workspaces.Workspace[]} workspaces The scope of workspaces. 31 | */ 32 | export async function changeSwitch(workspaces: deploy_workspaces.Workspace | deploy_workspaces.Workspace[]) { 33 | workspaces = deploy_helpers.asArray(workspaces); 34 | 35 | const QUICK_PICKS: deploy_contracts.ActionQuickPick[] = Enumerable.from( workspaces ).selectMany(ws => { 36 | return ws.getSwitchTargets(); 37 | }).select(st => { 38 | return { 39 | action: async () => { 40 | await st.__workspace 41 | .changeSwitchButtonOption(st); 42 | }, 43 | 44 | detail: st.__workspace.rootPath, 45 | label: deploy_targets.getTargetName(st), 46 | description: deploy_helpers.toStringSafe(st.description).trim(), 47 | }; 48 | }).toArray(); 49 | 50 | if (QUICK_PICKS.length < 1) { 51 | deploy_helpers.showWarningMessage( 52 | i18.t('plugins.switch.noDefined'), 53 | ); 54 | 55 | return; 56 | } 57 | 58 | let selectedItem: deploy_contracts.ActionQuickPick; 59 | if (1 === QUICK_PICKS.length) { 60 | selectedItem = QUICK_PICKS[0]; 61 | } 62 | else { 63 | selectedItem = await vscode.window.showQuickPick( 64 | QUICK_PICKS, 65 | { 66 | placeHolder: i18.t('plugins.switch.selectSwitch') 67 | }, 68 | ); 69 | } 70 | 71 | if (selectedItem) { 72 | await selectedItem.action(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/targets/operations/cleanup.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_helpers from '../../helpers'; 19 | import * as deploy_targets from '../../targets'; 20 | import * as FSExtra from 'fs-extra'; 21 | import * as Path from 'path'; 22 | 23 | 24 | /** 25 | * An operation that cleansup a directory 26 | */ 27 | export interface CleanupTargetOperation extends deploy_targets.TargetOperation { 28 | /** 29 | * The directory to cleanup. 30 | */ 31 | readonly dir: string; 32 | /** 33 | * One or more patterns of files to exclude. 34 | */ 35 | readonly exclude?: string | string[]; 36 | /** 37 | * One or more patterns of files to include. 38 | */ 39 | readonly include?: string | string[]; 40 | /** 41 | * Cleanup recursively or not. 42 | */ 43 | readonly recursive?: boolean; 44 | } 45 | 46 | 47 | /** @inheritdoc */ 48 | export async function execute(context: deploy_targets.TargetOperationExecutionContext) { 49 | const OPERATION = context.operation; 50 | const WORKSPACE = context.target.__workspace; 51 | 52 | const INCLUDE = deploy_helpers.asArray(OPERATION.include).map(i => { 53 | return deploy_helpers.toStringSafe(i); 54 | }).filter(i => { 55 | return '' !== i.trim(); 56 | }); 57 | if (INCLUDE.length < 1) { 58 | INCLUDE.push('**'); 59 | } 60 | 61 | const EXCLUDE = deploy_helpers.asArray(OPERATION.exclude).map(e => { 62 | return deploy_helpers.toStringSafe(e); 63 | }).filter(e => { 64 | return '' !== e.trim(); 65 | }); 66 | 67 | let dirToCleanup = deploy_helpers.toStringSafe( 68 | WORKSPACE.replaceWithValues(OPERATION.dir) 69 | ); 70 | if (!Path.isAbsolute(dirToCleanup)) { 71 | dirToCleanup = Path.join(WORKSPACE.rootPath, dirToCleanup); 72 | } 73 | dirToCleanup = Path.resolve(dirToCleanup); 74 | 75 | const RECURSIVE = deploy_helpers.toBooleanSafe(OPERATION.recursive, true); 76 | 77 | const TO_MINIMATCH = (s: any): string => { 78 | s = deploy_helpers.toStringSafe(s); 79 | s = deploy_helpers.replaceAllStrings(s, Path.sep, '/'); 80 | 81 | if (!s.trim().startsWith('/')) { 82 | s = '/' + s; 83 | } 84 | 85 | return s; 86 | }; 87 | 88 | const CLEANUP_DIR = async (d: string, subDir?: string) => { 89 | if (!deploy_helpers.isEmptyString(subDir)) { 90 | d = Path.join(d, subDir); 91 | } 92 | d = Path.resolve(d); 93 | 94 | if (!d.startsWith(dirToCleanup)) { 95 | return; 96 | } 97 | 98 | for (const SD of (await deploy_helpers.readDir(d))) { 99 | const FULL_PATH = Path.resolve( 100 | Path.join(d, SD) 101 | ); 102 | 103 | const RELATIVE_PATH = FULL_PATH.substr(dirToCleanup.length); 104 | 105 | const DOES_MATCH = deploy_helpers.checkIfDoesMatchByFileFilter( 106 | TO_MINIMATCH(RELATIVE_PATH), 107 | deploy_helpers.toMinimatchFileFilter({ 108 | files: INCLUDE, 109 | exclude: EXCLUDE, 110 | }), 111 | ); 112 | if (!DOES_MATCH) { 113 | continue; 114 | } 115 | 116 | let deleteItem = false; 117 | 118 | const STATS = await deploy_helpers.lstat(FULL_PATH); 119 | if (STATS.isDirectory()) { 120 | if (RECURSIVE) { 121 | await CLEANUP_DIR(d, SD); 122 | 123 | deleteItem = (await deploy_helpers.readDir(FULL_PATH)).length < 1; 124 | } 125 | } 126 | else { 127 | deleteItem = true; 128 | } 129 | 130 | if (deleteItem) { 131 | await FSExtra.remove(FULL_PATH); 132 | } 133 | } 134 | }; 135 | 136 | await CLEANUP_DIR(dirToCleanup); 137 | } 138 | -------------------------------------------------------------------------------- /src/targets/operations/command.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_helpers from '../../helpers'; 19 | import * as deploy_targets from '../../targets'; 20 | import * as vscode from 'vscode'; 21 | 22 | 23 | /** 24 | * Executes a Visual Studio Code command. 25 | */ 26 | export interface VSCommandTargetOperation extends deploy_targets.TargetOperation { 27 | /** 28 | * The arguments for the command. 29 | */ 30 | readonly arguments?: any[]; 31 | /** 32 | * The command to execute. 33 | */ 34 | readonly command: string; 35 | } 36 | 37 | 38 | /** @inheritdoc */ 39 | export async function execute(context: deploy_targets.TargetOperationExecutionContext) { 40 | const OPERATION = context.operation; 41 | const TARGET = context.target; 42 | const WORKSPACE = TARGET.__workspace; 43 | 44 | const COMMAND = deploy_helpers.toStringSafe( 45 | WORKSPACE.replaceWithValues( 46 | OPERATION.command 47 | ) 48 | ); 49 | 50 | let args: any[]; 51 | if (deploy_helpers.isNullOrUndefined(OPERATION.arguments)) { 52 | args = []; 53 | } 54 | else { 55 | args = deploy_helpers.asArray(OPERATION.arguments, false); 56 | } 57 | 58 | await vscode.commands.executeCommand 59 | .apply(null, [ COMMAND ].concat(args)); 60 | } 61 | -------------------------------------------------------------------------------- /src/targets/operations/devtools.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as _ from 'lodash'; 19 | import * as deploy_contracts from '../../contracts'; 20 | import * as deploy_helpers from '../../helpers'; 21 | import * as deploy_targets from '../../targets'; 22 | import * as vscode from 'vscode'; 23 | 24 | /** 25 | * An operation that invokes a method for a DevTools compatible browser debugger. 26 | */ 27 | export interface DevToolsTargetOperation extends deploy_targets.TargetOperation { 28 | /** 29 | * Always ask for the browser page or not. 30 | */ 31 | readonly alwaysAskForPage?: boolean; 32 | /** 33 | * Debug results or not. 34 | */ 35 | readonly debug?: boolean; 36 | /** 37 | * The hostname, where the debugger runs. 38 | */ 39 | readonly host?: string; 40 | /** 41 | * The name of the method to invoke. 42 | */ 43 | readonly method?: any; 44 | /** 45 | * A regular expression, which filters page by their title. 46 | */ 47 | readonly pages?: string; 48 | /** 49 | * Parameters for the method. 50 | */ 51 | readonly parameters?: any; 52 | /** 53 | * The TCP port, where the debugger runs. 54 | */ 55 | readonly port?: number; 56 | } 57 | 58 | const KEY_DEV_TOOLS_PAGE = 'lastDevToolsPage'; 59 | 60 | /** @inheritdoc */ 61 | export async function execute(context: deploy_targets.TargetOperationExecutionContext) { 62 | const OPERATION = context.operation; 63 | const TARGET = context.target; 64 | const WORKSPACE = TARGET.__workspace; 65 | 66 | const ALWAYS_ASK_FOR_PAGE = deploy_helpers.toBooleanSafe(OPERATION.alwaysAskForPage); 67 | const PAGES = deploy_helpers.toStringSafe( OPERATION.pages ); 68 | 69 | let sendCallback: deploy_helpers.SendToBrowserItemCallback; 70 | if (deploy_helpers.toBooleanSafe(OPERATION.debug, true)) { 71 | sendCallback = async (msg) => { 72 | if (_.isNil(msg)) { 73 | return; 74 | } 75 | 76 | const LOG_TAG = 'targets.operations.devtools.execute(sendCallback)'; 77 | 78 | let msgJson: string; 79 | try { 80 | msgJson = JSON.stringify(msg, null, 2); 81 | } catch { } 82 | 83 | if (!deploy_helpers.isEmptyString(msgJson)) { 84 | WORKSPACE.output.appendLine(''); 85 | WORKSPACE.output.appendLine( 86 | msgJson 87 | ); 88 | 89 | if (!_.isNil(msg.error)) { 90 | WORKSPACE.logger 91 | .err(msgJson, LOG_TAG); 92 | } else { 93 | WORKSPACE.logger 94 | .info(msgJson, LOG_TAG); 95 | } 96 | } 97 | }; 98 | } 99 | 100 | let params = deploy_helpers.cloneObject( OPERATION.parameters ); 101 | 102 | let method = deploy_helpers.toStringSafe( OPERATION.method ).trim(); 103 | if ('' === method) { 104 | method = 'Page.reload'; 105 | 106 | if (_.isNil(params)) { 107 | params = { 108 | ignoreCache: true, 109 | }; 110 | } 111 | } 112 | 113 | let pageFilter: false | RegExp = false; 114 | if ('' !== PAGES.trim()) { 115 | pageFilter = new RegExp(PAGES, 'i'); 116 | } 117 | 118 | const CLIENT = deploy_helpers.createDevToolsClient({ 119 | host: OPERATION.host, 120 | port: OPERATION.port, 121 | }); 122 | try { 123 | const PAGES = await CLIENT.getPages(); 124 | 125 | const LAST_SELECTED_PAGE: string = WORKSPACE.vars[KEY_DEV_TOOLS_PAGE]; 126 | 127 | const QUICK_PICKS: deploy_contracts.ActionQuickPick[] = 128 | deploy_helpers.from( 129 | PAGES.map((p, i) => { 130 | let title = deploy_helpers.toStringSafe(p.title).trim(); 131 | if ('' === title) { 132 | title = WORKSPACE.t('targets.operations.devTools.pages.defaultTitle', 133 | i + 1); 134 | } 135 | 136 | let description = deploy_helpers.toStringSafe(p.description).trim(); 137 | 138 | return { 139 | action: async () => { 140 | if (!(await p.connect())) { 141 | throw new Error( 142 | WORKSPACE.t('targets.operations.devTools.errors.couldNotConnectTo', 143 | p.socketUri) 144 | ); 145 | } 146 | 147 | try { 148 | await p.send(method, params, 149 | sendCallback); 150 | 151 | WORKSPACE.vars[KEY_DEV_TOOLS_PAGE] = p.id; 152 | } finally { 153 | try { 154 | p.close(); 155 | } catch { } 156 | } 157 | }, 158 | description: description, 159 | detail: p.socketUri, 160 | label: title, 161 | state: p, 162 | }; 163 | }) 164 | ).where(x => { 165 | if (false !== pageFilter) { 166 | return pageFilter.test( 167 | deploy_helpers.toStringSafe(x.state.title) 168 | ); 169 | } 170 | 171 | return true; 172 | }).orderBy(x => { 173 | return LAST_SELECTED_PAGE === x.state.id ? 0 : 1; 174 | }).thenBy(x => { 175 | return deploy_helpers.normalizeString(x.label); 176 | }).toArray(); 177 | 178 | if (QUICK_PICKS.length < 1) { 179 | return; 180 | } 181 | 182 | let selectedItem = deploy_helpers.from(QUICK_PICKS) 183 | .firstOrDefault(x => x.state.id === LAST_SELECTED_PAGE, false); 184 | if (ALWAYS_ASK_FOR_PAGE || (false === selectedItem)) { 185 | delete WORKSPACE.vars[KEY_DEV_TOOLS_PAGE]; 186 | 187 | if (1 === QUICK_PICKS.length) { 188 | selectedItem = QUICK_PICKS[0]; 189 | } else { 190 | selectedItem = await vscode.window.showQuickPick( 191 | QUICK_PICKS, { 192 | canPickMany: false, 193 | placeHolder: WORKSPACE.t('targets.operations.devTools.pages.selectPage'), 194 | } 195 | ); 196 | } 197 | } 198 | 199 | if (selectedItem) { 200 | await selectedItem.action(); 201 | } 202 | } finally { 203 | deploy_helpers.tryDispose( CLIENT ); 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /src/targets/operations/exec.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_helpers from '../../helpers'; 19 | import * as deploy_log from '../../log'; 20 | import * as deploy_targets from '../../targets'; 21 | import * as Path from 'path'; 22 | 23 | 24 | /** 25 | * An operation for executing something inside the workspace folder. 26 | */ 27 | export interface ExecTargetOperation extends deploy_targets.TargetOperation { 28 | /** 29 | * The (shell) command to execute. 30 | */ 31 | readonly command: string; 32 | /** 33 | * The custom working directory. 34 | */ 35 | readonly cwd?: string; 36 | /** 37 | * Largest amount of data in bytes allowed on stdout or stderr. 38 | */ 39 | readonly maxBuffer?: number; 40 | /** 41 | * Do not use placeholders in 'command' property. 42 | */ 43 | readonly noPlaceHolders?: boolean; 44 | /** 45 | * Print the result from stdout to output channel or not. 46 | */ 47 | readonly printOutput?: boolean; 48 | /** 49 | * Execution timeout. 50 | */ 51 | readonly timeout?: number; 52 | } 53 | 54 | 55 | /** @inheritdoc */ 56 | export async function execute(context: deploy_targets.TargetOperationExecutionContext) { 57 | const OPERATION = context.operation; 58 | const OPERATION_NAME = deploy_helpers.toStringSafe(OPERATION.name).trim(); 59 | const TARGET = context.target; 60 | const TARGET_NAME = deploy_targets.getTargetName(TARGET); 61 | const WORKSPACE = TARGET.__workspace; 62 | 63 | let command = deploy_helpers.toStringSafe(OPERATION.command); 64 | if (!deploy_helpers.toBooleanSafe(OPERATION.noPlaceHolders)) { 65 | command = WORKSPACE.replaceWithValues(command); 66 | } 67 | 68 | let cwd = deploy_helpers.toStringSafe( 69 | WORKSPACE.replaceWithValues( OPERATION.cwd ) 70 | ); 71 | if (deploy_helpers.isEmptyString(cwd)) { 72 | cwd = WORKSPACE.rootPath; 73 | } 74 | if (!Path.isAbsolute(cwd)) { 75 | cwd = Path.join(WORKSPACE.rootPath, cwd); 76 | } 77 | cwd = Path.resolve(cwd); 78 | 79 | let maxBuffer = parseInt( 80 | deploy_helpers.toStringSafe(OPERATION.maxBuffer).trim() 81 | ); 82 | if (isNaN(maxBuffer)) { 83 | maxBuffer = undefined; 84 | } 85 | 86 | let timeout = parseInt( 87 | deploy_helpers.toStringSafe(OPERATION.timeout).trim() 88 | ); 89 | if (isNaN(timeout)) { 90 | timeout = undefined; 91 | } 92 | 93 | const RESULT = await deploy_helpers.exec(command, { 94 | cwd: cwd, 95 | maxBuffer: maxBuffer, 96 | timeout: timeout, 97 | }); 98 | 99 | if (deploy_helpers.toBooleanSafe(OPERATION.printOutput, true)) { 100 | const OUTPUT = deploy_helpers.toStringSafe(RESULT.stdOut); 101 | 102 | if ('' !== OUTPUT) { 103 | WORKSPACE.output.appendLine(''); 104 | WORKSPACE.output.appendLine(''); 105 | 106 | WORKSPACE.output.appendLine(OUTPUT); 107 | 108 | WORKSPACE.output.appendLine(''); 109 | } 110 | } 111 | 112 | const ERR = deploy_helpers.toStringSafe(RESULT.stdErr); 113 | if ('' !== ERR) { 114 | deploy_log.CONSOLE 115 | .err(ERR, `targets.operations.exec('${TARGET_NAME}' :: '${OPERATION_NAME}')`); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/targets/operations/open.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_helpers from '../../helpers'; 19 | import * as deploy_targets from '../../targets'; 20 | 21 | 22 | /** 23 | * An operation for open something. 24 | */ 25 | export interface OpenTargetOperation extends deploy_targets.TargetOperation { 26 | /** 27 | * The target to open. 28 | */ 29 | readonly target: string; 30 | /** 31 | * Wait until operation has been finished or not. 32 | */ 33 | readonly wait?: boolean; 34 | } 35 | 36 | 37 | /** @inheritdoc */ 38 | export async function execute(context: deploy_targets.TargetOperationExecutionContext) { 39 | const TARGET_TO_OPEN = deploy_helpers.toStringSafe(context.operation.target); 40 | if (deploy_helpers.isEmptyString(TARGET_TO_OPEN)) { 41 | return; 42 | } 43 | 44 | const WORKSPACE = context.target.__workspace; 45 | const WAIT = deploy_helpers.toBooleanSafe(context.operation.wait, true); 46 | 47 | await deploy_helpers.open(TARGET_TO_OPEN, { 48 | cwd: WORKSPACE.rootPath, 49 | wait: WAIT, 50 | }); 51 | } 52 | -------------------------------------------------------------------------------- /src/targets/operations/script.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_contracts from '../../contracts'; 19 | import * as deploy_helpers from '../../helpers'; 20 | import * as deploy_targets from '../../targets'; 21 | import * as i18 from '../../i18'; 22 | 23 | 24 | /** 25 | * An operation that executes a script. 26 | */ 27 | export interface ScriptTargetOperation extends deploy_targets.TargetOperation { 28 | /** 29 | * Additional data / options for the script. 30 | */ 31 | readonly options?: any; 32 | /** 33 | * The path to the script to execute. 34 | */ 35 | readonly script: string; 36 | } 37 | 38 | /** 39 | * Arguments for script execution. 40 | */ 41 | export interface ScriptTargetOperationExecutionArguments extends deploy_contracts.ScriptArguments { 42 | /** 43 | * The underlying operation context. 44 | */ 45 | readonly context: deploy_targets.TargetOperationExecutionContext; 46 | } 47 | 48 | /** 49 | * A function / method that executes a script. 50 | * 51 | * @param {ScriptTargetOperationExecutionArguments} args The arguments. 52 | * 53 | * @return {any} The result, 54 | */ 55 | export type ScriptTargetOperationExecutor = (args: ScriptTargetOperationExecutionArguments) => any; 56 | 57 | /** 58 | * A script module. 59 | */ 60 | export interface ScriptTargetOperationModule { 61 | /** 62 | * Executes the script. 63 | */ 64 | readonly execute: ScriptTargetOperationExecutor; 65 | } 66 | 67 | 68 | /** @inheritdoc */ 69 | export async function execute(context: deploy_targets.TargetOperationExecutionContext) { 70 | const OPERATION = context.operation; 71 | const TARGET = context.target; 72 | const WORKSPACE = TARGET.__workspace; 73 | 74 | let scriptFile = deploy_helpers.toStringSafe( 75 | WORKSPACE.replaceWithValues(OPERATION.script) 76 | ); 77 | if (deploy_helpers.isEmptyString(scriptFile)) { 78 | switch (context.event) { 79 | case deploy_targets.TargetOperationEvent.AfterDeployed: 80 | scriptFile = './deployed.js'; 81 | break; 82 | 83 | case deploy_targets.TargetOperationEvent.BeforeDeploy: 84 | scriptFile = './beforeDeploy.js'; 85 | break; 86 | } 87 | } 88 | 89 | let scriptFullPath = await WORKSPACE.getExistingSettingPath(scriptFile); 90 | 91 | if (false === scriptFullPath) { 92 | throw new Error(i18.t('targets.operations.script.scriptNotFound', 93 | scriptFile)); 94 | } 95 | 96 | const SCRIPT_MODULE = deploy_helpers.loadModule(scriptFullPath); 97 | if (SCRIPT_MODULE) { 98 | const EXECUTE = SCRIPT_MODULE.execute; 99 | if (EXECUTE) { 100 | const ARGS: ScriptTargetOperationExecutionArguments = { 101 | _: require('lodash'), 102 | context: context, 103 | events: WORKSPACE.workspaceSessionState['target_operations']['script']['events'], 104 | extension: WORKSPACE.context.extension, 105 | folder: WORKSPACE.folder, 106 | globalEvents: deploy_helpers.EVENTS, 107 | globals: WORKSPACE.globals, 108 | globalState: WORKSPACE.workspaceSessionState['target_operations']['script']['global'], 109 | homeDir: deploy_helpers.getExtensionDirInHome(), 110 | logger: WORKSPACE.createLogger(), 111 | options: deploy_helpers.cloneObject(OPERATION.options), 112 | output: WORKSPACE.output, 113 | replaceWithValues: (val) => { 114 | return WORKSPACE.replaceWithValues(val); 115 | }, 116 | require: (id) => { 117 | return deploy_helpers.requireFromExtension(id); 118 | }, 119 | sessionState: deploy_helpers.SESSION, 120 | settingFolder: WORKSPACE.settingFolder, 121 | state: undefined, 122 | workspaceRoot: WORKSPACE.rootPath, 123 | }; 124 | 125 | // ARGS.state 126 | Object.defineProperty(ARGS, 'state', { 127 | enumerable: true, 128 | 129 | get: () => { 130 | return WORKSPACE.workspaceSessionState['target_operations']['script']['scripts'][scriptFullPath]; 131 | }, 132 | 133 | set: (newValue) => { 134 | WORKSPACE.workspaceSessionState['target_operations']['script']['scripts'][scriptFullPath] = newValue; 135 | } 136 | }); 137 | 138 | await Promise.resolve( 139 | EXECUTE.apply(SCRIPT_MODULE, [ ARGS ]) 140 | ); 141 | } 142 | else { 143 | throw new Error(i18.t('targets.operations.script.noScriptFunction', 144 | scriptFile)); 145 | } 146 | } 147 | else { 148 | throw new Error(i18.t('targets.operations.script.noScriptModule', 149 | scriptFile)); 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /src/targets/operations/slack.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_helpers from '../../helpers'; 19 | import * as deploy_targets from '../../targets'; 20 | import * as Enumerable from 'node-enumerable'; 21 | const Slack = require('@slack/client'); 22 | 23 | 24 | /** 25 | * An operation that send a message to one or more slack channels. 26 | */ 27 | export interface SlackTargetOperation extends deploy_targets.TargetOperation { 28 | /** 29 | * The IDs of one or more channels. 30 | */ 31 | readonly channels: string | string[]; 32 | /** 33 | * The minimum number of handled files before a notification is send. 34 | */ 35 | readonly minimumNumberOfFiles?: number; 36 | /** 37 | * The API token. 38 | */ 39 | readonly token: string; 40 | /** 41 | * The optional username that sends the notifications. 42 | */ 43 | readonly user?: string; 44 | } 45 | 46 | 47 | /** @inheritdoc */ 48 | export async function execute(context: deploy_targets.TargetOperationExecutionContext) { 49 | const OPERATION = context.operation; 50 | const WORKSPACE = context.target.__workspace; 51 | 52 | const CHANNELS = Enumerable.from( deploy_helpers.asArray(OPERATION.channels) ).select(c => { 53 | return deploy_helpers.toStringSafe( 54 | WORKSPACE.replaceWithValues(c) 55 | ).toUpperCase() 56 | .trim(); 57 | }).where(c => '' !== c) 58 | .distinct() 59 | .toArray(); 60 | 61 | const TARGET_NAME = deploy_targets.getTargetName(context.target); 62 | 63 | const TOKEN = deploy_helpers.toStringSafe( 64 | WORKSPACE.replaceWithValues(OPERATION.token) 65 | ).trim(); 66 | 67 | const USER = deploy_helpers.normalizeString( 68 | WORKSPACE.replaceWithValues(OPERATION.user) 69 | ); 70 | 71 | let minimumNumberOfFiles = parseInt( 72 | deploy_helpers.toStringSafe( 73 | OPERATION.minimumNumberOfFiles 74 | ).trim() 75 | ); 76 | if (isNaN(minimumNumberOfFiles)) { 77 | minimumNumberOfFiles = 1; 78 | } 79 | 80 | if (context.files.length < minimumNumberOfFiles) { 81 | return; 82 | } 83 | 84 | let msg = ''; 85 | switch (context.event) { 86 | case deploy_targets.TargetOperationEvent.AfterDeleted: 87 | msg = `The following files have been deleted in '${TARGET_NAME}'`; 88 | break; 89 | case deploy_targets.TargetOperationEvent.AfterDeployed: 90 | msg = `The following files have been deployed to '${TARGET_NAME}'`; 91 | break; 92 | 93 | case deploy_targets.TargetOperationEvent.BeforeDelete: 94 | msg = `The following files are going to be deleted in '${TARGET_NAME}'`; 95 | break; 96 | 97 | case deploy_targets.TargetOperationEvent.BeforeDeploy: 98 | msg = `The following files are going to be deployed to '${TARGET_NAME}'`; 99 | break; 100 | } 101 | 102 | if ('' !== USER) { 103 | msg += ' by @' + USER; 104 | } 105 | 106 | msg += ":\n" + Enumerable.from(context.files) 107 | .select(f => { 108 | return '• ' + f; 109 | }) 110 | .orderBy(f => f.length) 111 | .thenBy(f => deploy_helpers.normalizeString(f)) 112 | .joinToString("\n"); 113 | 114 | if (msg.length > 4000) { 115 | msg = msg.substr(0, 4000); // too big => cut 116 | } 117 | 118 | msg = msg.trim(); 119 | if ('' === msg) { 120 | return; 121 | } 122 | 123 | for (const C of CHANNELS) { 124 | const CLIENT = new Slack.WebClient(TOKEN); 125 | 126 | await CLIENT.chat.postMessage(C, msg, { 127 | link_names: true, 128 | mrkdwn: true, 129 | parse: 'full', 130 | }); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/targets/operations/sql.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_helpers from '../../helpers'; 19 | import * as deploy_log from '../../log'; 20 | import * as deploy_sql from '../../sql'; 21 | import * as deploy_targets from '../../targets'; 22 | 23 | 24 | /** 25 | * An operation that executes SQL statements. 26 | */ 27 | export interface SqlTargetOperation extends deploy_targets.TargetOperation { 28 | /** 29 | * The engine. 30 | */ 31 | readonly engine: string; 32 | /** 33 | * The connection options. 34 | */ 35 | readonly options?: any; 36 | /** 37 | * The list of queries to execute. 38 | */ 39 | readonly queries: string | string[]; 40 | } 41 | 42 | 43 | /** @inheritdoc */ 44 | export async function execute(context: deploy_targets.TargetOperationExecutionContext) { 45 | const OPERATION = context.operation; 46 | const TARGET = context.target; 47 | const WORKSPACE = TARGET.__workspace; 48 | 49 | let type: deploy_sql.SqlConnectionType | false = false; 50 | 51 | const ENGINE = deploy_helpers.normalizeString(OPERATION.engine); 52 | switch (ENGINE) { 53 | case 'mysql': 54 | type = deploy_sql.SqlConnectionType.MySql; 55 | break; 56 | 57 | case 'sql': 58 | type = deploy_sql.SqlConnectionType.MSSql; 59 | break; 60 | } 61 | 62 | if (false === type) { 63 | throw new Error(WORKSPACE.t('sql.notSupported', ENGINE)); 64 | } 65 | 66 | const CONN = await deploy_sql.openSqlConnection(type, OPERATION.options); 67 | try { 68 | for (const SQL of deploy_helpers.asArray(OPERATION.queries) 69 | .map(q => deploy_helpers.toStringSafe(q)) 70 | .filter(q => !deploy_helpers.isEmptyString(q))) { 71 | await CONN.query(SQL); 72 | } 73 | } 74 | finally { 75 | try { 76 | await CONN.close(); 77 | } 78 | catch (e) { 79 | deploy_log.CONSOLE 80 | .trace(e, 'targets.operations.sql.execute()'); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/targets/operations/wait.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_helpers from '../../helpers'; 19 | import * as deploy_targets from '../../targets'; 20 | 21 | 22 | /** 23 | * An operation that waits a number of milliseconds. 24 | */ 25 | export interface WaitTargetOperation extends deploy_targets.TargetOperation { 26 | /** 27 | * The time in milliseconds to wait. 28 | */ 29 | readonly time?: number; 30 | } 31 | 32 | 33 | /** @inheritdoc */ 34 | export async function execute(context: deploy_targets.TargetOperationExecutionContext) { 35 | let timeToWait = parseInt( 36 | deploy_helpers.toStringSafe(context.operation.time).trim() 37 | ); 38 | if (isNaN(timeToWait)) { 39 | timeToWait = 1000; 40 | } 41 | 42 | await deploy_helpers.sleep(timeToWait); 43 | } 44 | -------------------------------------------------------------------------------- /src/tasks.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_helpers from './helpers'; 19 | import * as deploy_log from './log'; 20 | import * as deploy_workspaces from './workspaces'; 21 | import * as vscode from 'vscode'; 22 | 23 | 24 | let buildTaskTimer: NodeJS.Timer; 25 | let gitPullAlreadyRun = false; 26 | let gitPullTimer: NodeJS.Timer; 27 | 28 | /** 29 | * Runs build task on startup. 30 | */ 31 | export async function runBuildTaskOnStartup() { 32 | const ME: deploy_workspaces.Workspace = this; 33 | const CFG = ME.config; 34 | 35 | // close old timer (if defined) 36 | try { 37 | let btt = buildTaskTimer; 38 | if (btt) { 39 | clearTimeout(btt); 40 | } 41 | } 42 | catch (e) { 43 | deploy_log.CONSOLE 44 | .trace(e, 'tasks.runBuildTaskOnStartup(1)'); 45 | } 46 | finally { 47 | buildTaskTimer = null; 48 | } 49 | 50 | let doRun = false; 51 | let timeToWait: number; 52 | if (!deploy_helpers.isNullOrUndefined(CFG.runBuildTaskOnStartup)) { 53 | if (deploy_helpers.isBool(CFG.runBuildTaskOnStartup)) { 54 | doRun = CFG.runBuildTaskOnStartup; 55 | } 56 | else { 57 | doRun = true; 58 | 59 | timeToWait = parseInt(deploy_helpers.toStringSafe(CFG.runBuildTaskOnStartup)); 60 | } 61 | } 62 | 63 | const RUN_BUILD = () => { 64 | vscode.commands.executeCommand('workbench.action.tasks.build').then(() => { 65 | }, (err) => { 66 | deploy_log.CONSOLE 67 | .trace(err, 'tasks.runBuildTaskOnStartup(2)'); 68 | }); 69 | }; 70 | 71 | if (!doRun) { 72 | return; 73 | } 74 | 75 | if (isNaN(timeToWait)) { 76 | RUN_BUILD(); 77 | } 78 | else { 79 | buildTaskTimer = setTimeout(() => { 80 | RUN_BUILD(); 81 | }, timeToWait); 82 | } 83 | } 84 | 85 | /** 86 | * Runs the git pull, if defined in config. 87 | */ 88 | export async function runGitPullOnStartup(cfg?: deploy_workspaces.WorkspaceSettings) { 89 | if (gitPullAlreadyRun) { 90 | return; 91 | } 92 | 93 | const ME: deploy_workspaces.Workspace = this; 94 | const CFG = cfg || ME.config; 95 | 96 | // close old timer (if defined) 97 | try { 98 | let gpt = gitPullTimer; 99 | if (gpt) { 100 | clearTimeout(gpt); 101 | } 102 | } 103 | catch (e) { 104 | deploy_log.CONSOLE 105 | .trace(e, 'tasks.runGitPullOnStartup(1)'); 106 | } 107 | finally { 108 | gitPullTimer = null; 109 | } 110 | 111 | let doRun = false; 112 | let timeToWait: number; 113 | if (!deploy_helpers.isNullOrUndefined(CFG.runGitPullOnStartup)) { 114 | if (deploy_helpers.isBool(CFG.runGitPullOnStartup)) { 115 | doRun = CFG.runGitPullOnStartup; 116 | } 117 | else { 118 | doRun = true; 119 | 120 | timeToWait = parseInt(deploy_helpers.toStringSafe(CFG.runGitPullOnStartup)); 121 | } 122 | } 123 | 124 | const RUN_PULL = () => { 125 | vscode.commands.executeCommand('git.pull').then(() => { 126 | }, (err) => { 127 | deploy_log.CONSOLE 128 | .trace(err, 'tasks.runGitPullOnStartup(2)'); 129 | }); 130 | }; 131 | 132 | if (!doRun) { 133 | return; 134 | } 135 | 136 | gitPullAlreadyRun = true; 137 | 138 | if (isNaN(timeToWait)) { 139 | RUN_PULL(); 140 | } 141 | else { 142 | gitPullTimer = setTimeout(() => { 143 | RUN_PULL(); 144 | }, timeToWait); 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/test/extension.test.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | 3 | /** 4 | * This file is part of the vscode-deploy-reloaded distribution. 5 | * Copyright (c) Marcel Joachim Kloubert. 6 | * 7 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU Lesser General Public License as 9 | * published by the Free Software Foundation, version 3. 10 | * 11 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program. If not, see . 18 | */ 19 | 20 | // 21 | // Note: This example test is leveraging the Mocha test framework. 22 | // Please refer to their documentation on https://mochajs.org/ for help. 23 | // 24 | 25 | // The module 'assert' provides assertion methods from node 26 | import * as assert from 'assert'; 27 | 28 | // You can import and use all API from the 'vscode' module 29 | // as well as import your extension to test it 30 | import * as vscode from 'vscode'; 31 | import * as myExtension from '../extension'; 32 | 33 | // Defines a Mocha test suite to group tests of similar kind together 34 | suite("Extension Tests", () => { 35 | 36 | // Defines a Mocha unit test 37 | test("Something 1", () => { 38 | assert.equal(-1, [1, 2, 3].indexOf(5)); 39 | assert.equal(-1, [1, 2, 3].indexOf(0)); 40 | }); 41 | }); -------------------------------------------------------------------------------- /src/test/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | // 19 | // PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING 20 | // 21 | // This file is providing the test runner to use when running extension tests. 22 | // By default the test runner in use is Mocha based. 23 | // 24 | // You can provide your own test runner if you want to override it by exporting 25 | // a function run(testRoot: string, clb: (error:Error) => void) that the extension 26 | // host can call to run the tests. The test runner is expected to use console.log 27 | // to report the results back to the caller. When the tests are finished, return 28 | // a possible error to the callback or null if none. 29 | 30 | import * as testRunner from 'vscode/lib/testrunner'; 31 | 32 | // You can directly control Mocha options by uncommenting the following lines 33 | // See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info 34 | testRunner.configure({ 35 | ui: 'tdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.) 36 | useColors: true // colored output from test results 37 | }); 38 | 39 | module.exports = testRunner; -------------------------------------------------------------------------------- /src/tools/yarn.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as deploy_contracts from '../contracts'; 19 | import * as deploy_gui from '../gui'; 20 | import * as deploy_helpers from '../helpers'; 21 | import * as deploy_log from '../log'; 22 | import * as deploy_workspaces from '../workspaces'; 23 | import * as i18 from '../i18'; 24 | import * as Path from 'path'; 25 | import * as vscode from 'vscode'; 26 | 27 | 28 | interface PackageJsonFile { 29 | dependencies?: { 30 | [ module: string ]: any 31 | }; 32 | } 33 | 34 | 35 | const KEY_YARN_TOOLS_USAGE = 'vscdrLastExecutedYarnToolActions'; 36 | const KEY_LAST_RUN_YARN_ADD_MODULE = 'vscdrRunYarnAddLastModule'; 37 | 38 | 39 | /** 40 | * Resets the NPM tool usage statistics. 41 | * 42 | * @param {vscode.ExtensionContext} context The extension context. 43 | */ 44 | export function resetYarnToolsUsage(context: vscode.ExtensionContext) { 45 | context.globalState.update(KEY_YARN_TOOLS_USAGE, undefined).then(() => { 46 | }, (err) => { 47 | deploy_log.CONSOLE 48 | .trace(err, 'tools.yarn.resetYarnToolsUsage()'); 49 | }); 50 | } 51 | 52 | async function runYarnAdd(ws: deploy_workspaces.Workspace) { 53 | const EXTENSION = ws.context.extension; 54 | 55 | const YARN_MODULE = deploy_helpers.normalizeString( 56 | await vscode.window.showInputBox( 57 | { 58 | placeHolder: ws.t('tools.yarn.moduleExample'), 59 | prompt: ws.t('tools.yarn.runAdd.enterModuleName'), 60 | value: deploy_helpers.normalizeString( 61 | EXTENSION.globalState.get(KEY_LAST_RUN_YARN_ADD_MODULE) 62 | ) 63 | } 64 | ), 65 | ); 66 | 67 | if ('' === YARN_MODULE) { 68 | return; 69 | } 70 | 71 | EXTENSION.globalState.update(KEY_LAST_RUN_YARN_ADD_MODULE, YARN_MODULE).then(() => { 72 | }, (err) => { 73 | deploy_log.CONSOLE 74 | .trace(err, 'tools.yarn.runYarnAdd(1)'); 75 | }); 76 | 77 | const CMD = `yarn add ${YARN_MODULE}`; 78 | 79 | ws.output.appendLine(''); 80 | ws.output.append( 81 | ws.t('tools.yarn.executing', CMD) + ' ' 82 | ); 83 | try { 84 | await ws.exec(CMD); 85 | 86 | ws.output.appendLine( 87 | `[${ws.t('ok')}]` 88 | ); 89 | } 90 | catch (e) { 91 | ws.output.appendLine( 92 | `[${ws.t('error', e)}]` 93 | ); 94 | } 95 | } 96 | 97 | async function runYarnRemove(ws: deploy_workspaces.Workspace) { 98 | const PACKAGE_JSON = Path.resolve( 99 | Path.join( 100 | ws.rootPath, 'package.json', 101 | ) 102 | ); 103 | 104 | if (!(await deploy_helpers.exists(PACKAGE_JSON))) { 105 | ws.showWarningMessage( 106 | ws.t('tools.yarn.runRemove.packageFileNotFound', 107 | ws.rootPath), 108 | ); 109 | 110 | return; 111 | } 112 | 113 | let file: PackageJsonFile; 114 | try { 115 | file = JSON.parse( 116 | (await deploy_helpers.readFile(PACKAGE_JSON)).toString('utf8') 117 | ); 118 | } 119 | catch (e) { 120 | ws.showErrorMessage( 121 | ws.t('tools.yarn.runRemove.errors.loadingPackageFileFailed', 122 | PACKAGE_JSON, e), 123 | ); 124 | 125 | return; 126 | } 127 | 128 | if (!file) { 129 | file = {}; 130 | } 131 | 132 | const MODULES: { 133 | name: string, 134 | version: string, 135 | }[] = []; 136 | 137 | if (file.dependencies) { 138 | for (const M in file.dependencies) { 139 | const MODULE_NAME = deploy_helpers.toStringSafe(M).trim(); 140 | if ('' === MODULE_NAME) { 141 | continue; 142 | } 143 | 144 | MODULES.push({ 145 | name: MODULE_NAME, 146 | version: deploy_helpers.toStringSafe(file.dependencies[M]).trim(), 147 | }); 148 | } 149 | } 150 | 151 | const QUICK_PICKS: deploy_contracts.ActionQuickPick[] = MODULES.sort((x, y) => { 152 | return deploy_helpers.compareValuesBy(x, y, 153 | m => deploy_helpers.normalizeString(m.name)); 154 | }).map(m => { 155 | return { 156 | action: () => { 157 | return m.name; 158 | }, 159 | 160 | label: m.name, 161 | description: m.version, 162 | detail: PACKAGE_JSON, 163 | }; 164 | }); 165 | 166 | if (QUICK_PICKS.length < 1) { 167 | ws.showWarningMessage( 168 | ws.t('tools.yarn.runRemove.packageFileContainsNoModules', 169 | PACKAGE_JSON), 170 | ); 171 | 172 | return; 173 | } 174 | 175 | const SELECTED_ITEM = await vscode.window.showQuickPick( 176 | QUICK_PICKS 177 | ); 178 | 179 | if (!SELECTED_ITEM) { 180 | return; 181 | } 182 | 183 | const YARN_MODULE: string = SELECTED_ITEM.action(); 184 | 185 | const CMD = `yarn remove ${YARN_MODULE}`; 186 | 187 | ws.output.appendLine(''); 188 | ws.output.append( 189 | ws.t('tools.yarn.executing', CMD) + ' ' 190 | ); 191 | try { 192 | await ws.exec(CMD); 193 | 194 | ws.output.appendLine( 195 | `[${ws.t('ok')}]` 196 | ); 197 | } 198 | catch (e) { 199 | ws.output.appendLine( 200 | `[${ws.t('error', e)}]` 201 | ); 202 | } 203 | } 204 | 205 | export async function showYarnTools(context: vscode.ExtensionContext) { 206 | const SELECTED_WORKSPACE = await deploy_workspaces.showWorkspaceQuickPick( 207 | context, 208 | deploy_workspaces.getActiveWorkspaces(), 209 | { 210 | placeHolder: i18.t('workspaces.selectWorkspace') 211 | } 212 | ); 213 | 214 | if (!SELECTED_WORKSPACE) { 215 | return; 216 | } 217 | 218 | const QUICK_PICKS: deploy_contracts.ActionQuickPick[] = [ 219 | { 220 | action: async () => { 221 | await runYarnAdd(SELECTED_WORKSPACE); 222 | }, 223 | 224 | description: SELECTED_WORKSPACE.t('tools.yarn.runAdd.description'), 225 | detail: SELECTED_WORKSPACE.rootPath, 226 | label: SELECTED_WORKSPACE.t('tools.yarn.runAdd.label'), 227 | 228 | state: 0, 229 | }, 230 | 231 | { 232 | action: async () => { 233 | await runYarnRemove(SELECTED_WORKSPACE); 234 | }, 235 | 236 | description: SELECTED_WORKSPACE.t('tools.yarn.runRemove.description'), 237 | detail: SELECTED_WORKSPACE.rootPath, 238 | label: SELECTED_WORKSPACE.t('tools.yarn.runRemove.label'), 239 | 240 | state: 1, 241 | }, 242 | ]; 243 | 244 | const SELECTED_ITEM = await vscode.window.showQuickPick( 245 | deploy_gui.sortQuickPicksByUsage( 246 | QUICK_PICKS, 247 | SELECTED_WORKSPACE.context.extension.globalState, 248 | KEY_YARN_TOOLS_USAGE, 249 | ) 250 | ); 251 | 252 | if (SELECTED_ITEM) { 253 | await SELECTED_ITEM.action(); 254 | } 255 | } 256 | -------------------------------------------------------------------------------- /src/transformers.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is part of the vscode-deploy-reloaded distribution. 3 | * Copyright (c) Marcel Joachim Kloubert. 4 | * 5 | * vscode-deploy-reloaded is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as 7 | * published by the Free Software Foundation, version 3. 8 | * 9 | * vscode-deploy-reloaded is distributed in the hope that it will be useful, but 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | import * as Crypto from 'crypto'; 19 | import * as deploy_contracts from './contracts'; 20 | import * as deploy_helpers from './helpers'; 21 | 22 | 23 | /** 24 | * An object that can transform data. 25 | */ 26 | export interface CanTransformData { 27 | /** 28 | * The path (or URI) to the transformer script. 29 | */ 30 | readonly transformer?: string; 31 | /** 32 | * The options for the transformer script. 33 | */ 34 | readonly transformerOptions?: any; 35 | } 36 | 37 | /** 38 | * A data transformer. 39 | * 40 | * @param {Buffer} input The untransformed data. 41 | * 42 | * @return {DataTransformerResult} The transformed data. 43 | */ 44 | export type DataTransformer = (input: Buffer, context: DataTransformerContext) => DataTransformerResult; 45 | 46 | /** 47 | * A data transformer context. 48 | */ 49 | export interface DataTransformerContext extends deploy_contracts.ScriptArguments { 50 | /** 51 | * The sub context. 52 | */ 53 | readonly context?: any; 54 | /** 55 | * The mode. 56 | */ 57 | readonly mode: DataTransformerMode; 58 | } 59 | 60 | /** 61 | * A possible result of a data transformer. 62 | */ 63 | export type DataTransformerResult = Buffer | PromiseLike; 64 | 65 | /** 66 | * The transformer mode. 67 | */ 68 | export enum DataTransformerMode { 69 | /** 70 | * Restore transformed data. 71 | */ 72 | Restore = 0, 73 | /** 74 | * Transform UNtransformed data. 75 | */ 76 | Transform = 1, 77 | } 78 | 79 | /** 80 | * A data transformer module. 81 | */ 82 | export interface DataTransformerModule { 83 | /** 84 | * The transformer. 85 | */ 86 | readonly transform: DataTransformer; 87 | } 88 | 89 | /** 90 | * Creates a "safe" data transformer. 91 | * 92 | * @param {DataTransformer} transformer The transformer to wrap. 93 | * @param {any} [thisArg] The custom object / value that should be applied to 'transformer'. 94 | * 95 | * @return {DataTransformer} The wrapper. 96 | */ 97 | export function toDataTransformerSafe(transformer: DataTransformer, thisArg?: any): DataTransformer { 98 | if (!transformer) { 99 | transformer = (data) => data; 100 | } 101 | 102 | return async function() { 103 | let data: Buffer = await Promise.resolve( 104 | transformer.apply(thisArg, arguments) 105 | ); 106 | 107 | data = await deploy_helpers.asBuffer(data, 'binary'); 108 | if (!Buffer.isBuffer(data)) { 109 | data = Buffer.alloc(0); 110 | } 111 | 112 | return data; 113 | }; 114 | } 115 | 116 | 117 | /** 118 | * Creates wrapper for a data transformer for encrypting data by password. 119 | * 120 | * @param {DataTransformer} baseTransformer The transformer to wrap. 121 | * @param {deploy_contracts.Encryptable} opts The options. 122 | * 123 | * @return {DataTransformer} The wrapper. 124 | */ 125 | export function toPasswordTransformer(baseTransformer: DataTransformer, opts: deploy_contracts.Encryptable): DataTransformer { 126 | if (!opts) { 127 | opts = {}; 128 | } 129 | 130 | let pwd = deploy_helpers.toStringSafe(opts.encryptWith); 131 | 132 | let algo = deploy_helpers.normalizeString(opts.encryptBy); 133 | if ('' === algo) { 134 | algo = 'aes-256-ctr'; 135 | } 136 | 137 | return async function(input: Buffer, context: DataTransformerContext) { 138 | if (!input) { 139 | return input; 140 | } 141 | 142 | let result = input; 143 | 144 | const INVOKE_TRANSFORMER_FOR = async (buff: Buffer) => { 145 | if (baseTransformer) { 146 | buff = await Promise.resolve( 147 | baseTransformer(buff, context) 148 | ); 149 | } 150 | 151 | return buff; 152 | }; 153 | 154 | let invokeTransformer = true; 155 | 156 | if (result) { 157 | if ('' !== pwd) { 158 | invokeTransformer = false; 159 | 160 | switch (context.mode) { 161 | case DataTransformerMode.Restore: 162 | { 163 | const DECIPHER = Crypto.createDecipher(algo, pwd); 164 | 165 | // 1. UNcrypt 166 | result = Buffer.concat([ 167 | DECIPHER.update(result), 168 | DECIPHER.final() 169 | ]); 170 | 171 | // 2. UNtransform 172 | result = await INVOKE_TRANSFORMER_FOR(result); 173 | } 174 | break; 175 | 176 | case DataTransformerMode.Transform: 177 | { 178 | const CIPHER = Crypto.createCipher(algo, pwd); 179 | 180 | // 1. transform 181 | result = await INVOKE_TRANSFORMER_FOR(result); 182 | 183 | // 2. crypt 184 | result = Buffer.concat([ 185 | CIPHER.update(result), 186 | CIPHER.final() 187 | ]); 188 | } 189 | break; 190 | } 191 | } 192 | } 193 | 194 | if (invokeTransformer) { 195 | result = await INVOKE_TRANSFORMER_FOR(result); 196 | } 197 | 198 | return result; 199 | }; 200 | } 201 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es2017", 5 | "outDir": "out", 6 | "lib": [ 7 | "es2017" 8 | ], 9 | "sourceMap": true, 10 | "rootDir": "src" 11 | }, 12 | "exclude": [ 13 | "node_modules", 14 | ".vscode-test" 15 | ] 16 | } -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "arrow-return-shorthand": true, 4 | "await-promise": [true, "Thenable", "PromiseLike"], 5 | "class-name": true, 6 | "curly": true, 7 | "indent": [ 8 | true, 9 | "spaces" 10 | ], 11 | "jsdoc-format": true, 12 | "no-unused-variable": true, 13 | "no-var-keyword": true, 14 | "semicolon": [ 15 | true, 16 | "always" 17 | ] 18 | }, 19 | "defaultSeverity": "warning" 20 | } --------------------------------------------------------------------------------