├── .gitignore ├── .travis.yml ├── .vscode └── launch.json ├── .vscodeignore ├── CONTRIBUTING.md ├── LICENSE.txt ├── README.md ├── RELEASE-README.md ├── github-assets ├── logo.png └── screenshot.png ├── gulpfile.js ├── issue_template.md ├── openwhisk.configuration.json ├── package.json └── static-src ├── commands ├── controller.js ├── util.js ├── wsk.action.js ├── wsk.activation.js ├── wsk.help.js ├── wsk.list.js ├── wsk.package.js ├── wsk.property.js ├── wsk.rule.js ├── wsk.trigger.js └── wsk.util.js ├── extension.js ├── jsconfig.json ├── templates ├── javascript.template ├── javascript6.template ├── php.template ├── python.template └── swift.template ├── typings ├── node.d.ts └── vscode-typings.d.ts └── vsc-extension-quickstart.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.vsix 3 | out 4 | package-lock.json -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.12" 4 | - 4.4.7 5 | - 5.10.1 6 | - 6.3.0 7 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that launches the extension inside a new window 2 | { 3 | "version": "0.1.0", 4 | "configurations": [ 5 | { 6 | "name": "Launch Extension", 7 | "type": "extensionHost", 8 | "request": "launch", 9 | "runtimeExecutable": "${execPath}", 10 | "args": ["--extensionDevelopmentPath=${workspaceRoot}/" ], 11 | "stopOnEntry": false 12 | }, 13 | { 14 | "name": "Launch Tests", 15 | "type": "extensionHost", 16 | "request": "launch", 17 | "runtimeExecutable": "${execPath}", 18 | "args": ["--extensionDevelopmentPath=${workspaceRoot}/", "--extensionTestsPath=${workspaceRoot}/test" ], 19 | "stopOnEntry": false 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | static-src/typings/** 3 | static-src/test/** 4 | .gitignore 5 | jsconfig.json 6 | vsc-extension-quickstart.md 7 | RELEASE-README.md -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 18 | 19 | # Contributing to Apache OpenWhisk 20 | 21 | Anyone can contribute to the OpenWhisk project and we welcome your contributions. 22 | 23 | There are multiple ways to contribute: report bugs, improve the docs, and 24 | contribute code, but you must follow these prerequisites and guidelines: 25 | 26 | - [Contributor License Agreement](#contributor-license-agreement) 27 | - [Raising issues](#raising-issues) 28 | - [Coding Standards](#coding-standards) 29 | 30 | ### Contributor License Agreement 31 | 32 | All contributors must sign and submit an Apache CLA (Contributor License Agreement). 33 | 34 | Instructions on how to do this can be found here: 35 | [http://www.apache.org/licenses/#clas](http://www.apache.org/licenses/#clas) 36 | 37 | Once submitted, you will receive a confirmation email from the Apache Software Foundation (ASF) and be added to 38 | the following list: http://people.apache.org/unlistedclas.html. 39 | 40 | Project committers will use this list to verify pull requests (PRs) come from contributors that have signed a CLA. 41 | 42 | We look forward to your contributions! 43 | 44 | ## Raising issues 45 | 46 | Please raise any bug reports on the respective project repository's GitHub issue tracker. Be sure to search the 47 | list to see if your issue has already been raised. 48 | 49 | A good bug report is one that make it easy for us to understand what you were trying to do and what went wrong. 50 | Provide as much context as possible so we can try to recreate the issue. 51 | 52 | ### Discussion 53 | 54 | Please use the project's developer email list to engage our community: 55 | [dev@openwhisk.incubator.apache.org](dev@openwhisk.incubator.apache.org) 56 | 57 | In addition, we provide a "dev" Slack team channel for conversations at: 58 | https://openwhisk-team.slack.com/messages/dev/ 59 | 60 | ### Coding standards 61 | 62 | Please ensure you follow the coding standards used throughout the existing 63 | code base. Some basic rules include: 64 | 65 | - all files must have the Apache license in the header. 66 | - all PRs must have passing builds for all operating systems. 67 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2015-2016 IBM Corporation 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VSCode OpenWhisk Extension 2 | 3 | This is a prototype extension for Visual Studio Code https://code.visualstudio.com/ that enables complete round trip cycles for authoring OpenWhisk actions inside the editor. The key point for this extension is that it has full round trip for open whisk actions (list, create new local, create new remote, update, import from remote system, invoke, etc…) without ever leaving the IDE and makes dev cycles far shorter and easier. It also works for both Swift and JS actions on Windows, Mac, and Linux. 4 | 5 | Download and run the installer for your platform from the [Downloads Section](#downloads). 6 | 7 | [![Build Status](https://travis-ci.org/openwhisk/openwhisk-vscode.svg?branch=master)](https://travis-ci.org/openwhisk/openwhisk-vscode) [![License](https://img.shields.io/badge/license-MIT-green.svg?style=flat)](https://raw.githubusercontent.com/openwhisk/openwhisk-vscode/blob/master/LICENSE) 8 | 9 | Preview of VS Code OpenWhisk extension here: 10 | 11 | [![VS Code OpenWhisk extension video](https://img.youtube.com/vi/aPsLXvphkro/0.jpg)](https://www.youtube.com/watch?v=aPsLXvphkro) 12 | 13 | https://youtu.be/aPsLXvphkro 14 | 15 | 16 | ## 17 | Downloads 18 | ========= 19 | **Latest stable:** Download the packaged extension from the [releases page.](https://github.com/openwhisk/vscode-openwhisk/releases) 20 | 21 | To install download the extension and drag it into VSCode 22 | 23 | ## Usage 24 | 25 | OpenWhisk command can be invoked from the Command Palette using the prefix `wsk`. You can invoke the Command Palette by pressing `F1` or by using the key combination `CMD Shift P` (OS X, there is an equivalent for Windows/Linux). 26 | 27 | ![Command Palette Screenshot](./github-assets/screenshot.png) 28 | 29 | ## Configuration 30 | 31 | Once you have the extension installed, you will have to run `wsk property set` inside of VS Code to set the auth and namespace values. These values can be retrieved from either the OpenWhisk CLI using `wsk property get` or from the web interface. 32 | 33 | ## Util Commands 34 | 35 | ### `wsk` commands: 36 | bluemix launch OpenWhisk console on Bluemix 37 | docs open OpenWhisk docs 38 | property set set property 39 | property unset unset property 40 | property get get property 41 | action see available commands for OpenWhisk actions 42 | 43 | ### `wsk action` commands: 44 | init create new action boilerplate file 45 | create create new action 46 | sequence create a new sequence of actions 47 | update update an existing action 48 | invoke invoke action 49 | get get action 50 | delete delete action 51 | list list all actions 52 | rest display CURL rest invocation parameters 53 | 54 | 55 | -------------------------------------------------------------------------------- /RELEASE-README.md: -------------------------------------------------------------------------------- 1 | # Packaging the VSCode extension for release 2 | 3 | All based on information here: https://code.visualstudio.com/docs/extensions/publish-extension 4 | 5 | ## Packaging a VS Code extension for local distribution. 6 | 7 | 1. cd into the project root directory (this is the one that contains `package.json`) 8 | 2. Update the `version` value in `package.json` (this can be manual or using `npm version`) 9 | 3. Run the command `vsce package` - this compiles the .vsix file for release, which can be installed into vscode. This file can be uploaded into the "Releases" section on github 10 | 11 | ---- 12 | 13 | ## Packaging for remote distribution in windows marketplace: 14 | 15 | 1. cd into the project root directory (this is the one that contains `package.json`) 16 | 2. Update the `version` value in `package.json` (this can be manual or using `npm version`) 17 | 3. Run the command `vsce publish` - This compiles the extension and publishes to the windows marketplace in one step. ***This requires an account with sufficient priveleges 18 | 19 | -------------------------------------------------------------------------------- /github-assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/openwhisk-vscode/d44b31c9d31438966a5c3205a38a93a436fc0241/github-assets/logo.png -------------------------------------------------------------------------------- /github-assets/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/openwhisk-vscode/d44b31c9d31438966a5c3205a38a93a436fc0241/github-assets/screenshot.png -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | var gulp = require('gulp'); 19 | var zip = require('gulp-vinyl-zip').zip; 20 | 21 | gulp.task('build-zip', () => { 22 | const platform = process.platform; 23 | 24 | return gulp.src([ 25 | 'static-src/commands/**', 26 | 'static-src/templates/**', 27 | 'static-src/extension.js', 28 | 'node_modules/**', 29 | 'LICENSE', 30 | 'package.json', 31 | 'github-assets/**', 32 | 'README.md', 33 | '!node_modules/.bin/**', 34 | '!node_modules/**/.bin' 35 | ], { base: '.' }) 36 | .pipe(zip(`openwhisk-vscode-${platform}.zip`)) 37 | .pipe(gulp.dest('./out')); 38 | }); 39 | -------------------------------------------------------------------------------- /issue_template.md: -------------------------------------------------------------------------------- 1 | - Git revision: 2 | - OS Version: 3 | 4 | Steps to Reproduce: 5 | 6 | 1. 7 | 2. 8 | 9 | Screencaps: (use [recordit](http://recordit.co) or something comparable) 10 | -------------------------------------------------------------------------------- /openwhisk.configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | "lineComment": "//", 4 | "blockComment": [ "/*", "*/" ] 5 | }, 6 | "brackets": [ 7 | ["{", "}"], 8 | ["[", "]"], 9 | ["(", ")"] 10 | ] 11 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "openwhisk", 3 | "displayName": "OpenWhisk", 4 | "description": "A VSCode extension for OpenWhisk", 5 | "version": "0.0.6", 6 | "publisher": "IBM", 7 | "engines": { 8 | "vscode": "^0.10.10" 9 | }, 10 | "categories": [ 11 | "Languages", 12 | "Other" 13 | ], 14 | "activationEvents": [ 15 | "*" 16 | ], 17 | "repository": { 18 | "type": "git", 19 | "url": "https://github.com/openwhisk/openwhisk-vscode.git" 20 | }, 21 | "author": { 22 | "name": "Andrew Trice", 23 | "email": "amtrice@us.ibm.com" 24 | }, 25 | "contributors": [ 26 | { 27 | "name": "Jeff Sloyer", 28 | "email": "jbsloyer@us.ibm.com" 29 | } 30 | ], 31 | "icon": "github-assets/logo.png", 32 | "galleryBanner": { 33 | "color": "#CFB69A", 34 | "theme": "light" 35 | }, 36 | "main": "./static-src/extension", 37 | "contributes": { 38 | "commands": [ 39 | { 40 | "command": "extension.wsk.list", 41 | "title": "wsk list" 42 | }, 43 | { 44 | "command": "extension.wsk.help", 45 | "title": "wsk" 46 | }, 47 | { 48 | "command": "extension.wsk.help", 49 | "title": "wsk help" 50 | }, 51 | { 52 | "command": "extension.wsk.action", 53 | "title": "wsk action" 54 | }, 55 | { 56 | "command": "extension.wsk.action.list", 57 | "title": "wsk action list" 58 | }, 59 | { 60 | "command": "extension.wsk.action.invoke", 61 | "title": "wsk action invoke" 62 | }, 63 | { 64 | "command": "extension.wsk.action.debug", 65 | "title": "wsk action debug" 66 | }, 67 | { 68 | "command": "extension.wsk.action.create", 69 | "title": "wsk action create" 70 | }, 71 | { 72 | "command": "extension.wsk.action.sequence.create", 73 | "title": "wsk sequence create" 74 | }, 75 | { 76 | "command": "extension.wsk.action.update", 77 | "title": "wsk action update" 78 | }, 79 | { 80 | "command": "extension.wsk.action.delete", 81 | "title": "wsk action delete" 82 | }, 83 | { 84 | "command": "extension.wsk.action.get", 85 | "title": "wsk action get" 86 | }, 87 | { 88 | "command": "extension.wsk.action.init", 89 | "title": "wsk action init" 90 | }, 91 | { 92 | "command": "extension.wsk.action.rest", 93 | "title": "wsk action REST" 94 | }, 95 | { 96 | "command": "extension.wsk.util.bluemix", 97 | "title": "wsk bluemix" 98 | }, 99 | { 100 | "command": "extension.wsk.util.docs", 101 | "title": "wsk docs" 102 | }, 103 | { 104 | "command": "extension.wsk.property.get", 105 | "title": "wsk property get" 106 | }, 107 | { 108 | "command": "extension.wsk.property.set", 109 | "title": "wsk property set" 110 | }, 111 | { 112 | "command": "extension.wsk.property.unset", 113 | "title": "wsk property unset" 114 | }, 115 | { 116 | "command": "extension.wsk.trigger", 117 | "title": "wsk trigger" 118 | }, 119 | { 120 | "command": "extension.wsk.trigger.list", 121 | "title": "wsk trigger list" 122 | }, 123 | { 124 | "command": "extension.wsk.trigger.create", 125 | "title": "wsk trigger create" 126 | }, 127 | { 128 | "command": "extension.wsk.trigger.update", 129 | "title": "wsk trigger update" 130 | }, 131 | { 132 | "command": "extension.wsk.trigger.delete", 133 | "title": "wsk trigger delete" 134 | }, 135 | { 136 | "command": "extension.wsk.trigger.get", 137 | "title": "wsk trigger get" 138 | }, 139 | { 140 | "command": "extension.wsk.trigger.fire", 141 | "title": "wsk trigger fire" 142 | }, 143 | { 144 | "command": "extension.wsk.rule", 145 | "title": "wsk rule" 146 | }, 147 | { 148 | "command": "extension.wsk.rule.list", 149 | "title": "wsk rule list" 150 | }, 151 | { 152 | "command": "extension.wsk.rule.create", 153 | "title": "wsk rule create" 154 | }, 155 | { 156 | "command": "extension.wsk.rule.update", 157 | "title": "wsk rule update" 158 | }, 159 | { 160 | "command": "extension.wsk.rule.delete", 161 | "title": "wsk rule delete" 162 | }, 163 | { 164 | "command": "extension.wsk.rule.enable", 165 | "title": "wsk rule enable" 166 | }, 167 | { 168 | "command": "extension.wsk.rule.disable", 169 | "title": "wsk rule disable" 170 | }, 171 | { 172 | "command": "extension.wsk.rule.status", 173 | "title": "wsk rule status" 174 | }, 175 | { 176 | "command": "extension.wsk.rule.get", 177 | "title": "wsk rule get" 178 | }, 179 | { 180 | "command": "extension.wsk.activation", 181 | "title": "wsk activation" 182 | }, 183 | { 184 | "command": "extension.wsk.activation.list", 185 | "title": "wsk activation list" 186 | }, 187 | { 188 | "command": "extension.wsk.activation.get", 189 | "title": "wsk activation get" 190 | }, 191 | { 192 | "command": "extension.wsk.activation.logs", 193 | "title": "wsk activation logs" 194 | }, 195 | { 196 | "command": "extension.wsk.activation.result", 197 | "title": "wsk activation result" 198 | } 199 | ] 200 | }, 201 | "scripts": { 202 | "postinstall": "rm -rf ./node_modules/openwhisk/test/" 203 | }, 204 | "devDependencies": { 205 | "gulp": "^3.9.1", 206 | "gulp-vinyl-zip": "^1.2.2", 207 | "vscode": "^0.11.0" 208 | }, 209 | "dependencies": { 210 | "open": "0.0.5", 211 | "openwhisk": "https://github.com/triceam/openwhisk-client-js/tarball/master", 212 | "request-promise": "^3.0.0" 213 | }, 214 | "keywords": [ 215 | "IBM", 216 | "openwhisk" 217 | ], 218 | "bugs": { 219 | "url": "https://github.com/openwhisk/openwhisk-vscode/issues" 220 | }, 221 | "license": "MIT", 222 | "homepage": "https://github.com/openwhisk/openwhisk-vscode/blob/master/README.md" 223 | } 224 | -------------------------------------------------------------------------------- /static-src/commands/controller.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | "use strict"; 19 | 20 | var vscode = require('vscode'); 21 | var openwhisk = require('openwhisk'); 22 | 23 | let util = require("./util.js"); 24 | let wskLst = require("./wsk.list.js"); 25 | let wskHelp = require("./wsk.help.js"); 26 | let wskAction = require("./wsk.action.js"); 27 | let wskPackage = require("./wsk.package.js"); 28 | let wskTrigger = require("./wsk.trigger.js"); 29 | let wskRule = require("./wsk.rule.js"); 30 | let wskUtil = require("./wsk.util.js"); 31 | let wskActivation = require("./wsk.activation.js"); 32 | let wskProperty = require("./wsk.property.js"); 33 | 34 | var ow; 35 | let log = vscode.window.createOutputChannel("OpenWhisk"); 36 | 37 | 38 | function init(context) { 39 | 40 | //api key and namespace will be set when config values are loaded 41 | ow = openwhisk({api: 'https://openwhisk.ng.bluemix.net/api/v1/', api_key: 'invalid', namespace: ''}); 42 | 43 | util.setLog(log); 44 | 45 | wskProperty.register(ow, context, log); 46 | wskLst.register(ow, context, log, wskProperty); 47 | wskHelp.register(ow, context, log, wskProperty); 48 | wskAction.register(ow, context, log, wskProperty); 49 | wskPackage.register(ow, context, log, wskProperty); 50 | wskTrigger.register(ow, context, log, wskProperty); 51 | wskRule.register(ow, context, log, wskProperty); 52 | wskUtil.register(ow, context, log, wskProperty); 53 | wskActivation.register(ow, context, log, wskProperty); 54 | } 55 | 56 | module.exports = { 57 | init: init, 58 | ow: ow 59 | }; 60 | -------------------------------------------------------------------------------- /static-src/commands/util.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | 'use strict'; 19 | 20 | var vscode = require('vscode'); 21 | let log; 22 | 23 | function pad(input, length) { 24 | if (input == undefined) { 25 | input = ''; 26 | } 27 | while (input.length < length) { 28 | input += ' '; 29 | } 30 | return input; 31 | } 32 | 33 | function appendHeading(name) { 34 | log.appendLine('\n'+name+'\n---------------------------------------------------------------------------------'); 35 | } 36 | 37 | function appendEntry(entry, qualified) { 38 | 39 | var qualifiedName = formatQualifiedName(entry, qualified); 40 | var suffix = '' 41 | 42 | if ( entry.hasOwnProperty('binding') && entry.binding ) { 43 | suffix = ' binding'; 44 | } 45 | 46 | log.appendLine( pad(qualifiedName, 66) + (entry.publish ? 'public':'private') + suffix); 47 | } 48 | 49 | function appendActivation(entry, qualified) { 50 | 51 | var qualifiedName = formatQualifiedName(entry, qualified); 52 | var suffix = '' 53 | 54 | if ( entry.hasOwnProperty('binding') && entry.binding ) { 55 | suffix = ' binding'; 56 | } 57 | 58 | log.appendLine( pad(entry.activationId, 45) + entry.name); 59 | } 60 | 61 | function formatQualifiedName(entry, qualified) { 62 | if (qualified == undefined) { 63 | qualified = true; 64 | } 65 | 66 | var qualifiedName = (qualified ? (entry.namespace + '/'):'') + entry.name; 67 | return qualifiedName; 68 | } 69 | 70 | function parseQualifiedName(name) { 71 | var nameString = name.toString(); 72 | var startIndex = nameString.indexOf('/'); 73 | var namespace = nameString.substring(0, startIndex); 74 | var parsedName = nameString.substring(startIndex+1); 75 | return { 76 | "name":parsedName, 77 | "namespace":namespace 78 | }; 79 | } 80 | 81 | function setLog(_log) { 82 | log = _log; 83 | } 84 | 85 | function printOpenWhiskError(error) { 86 | log.appendLine('\nERROR: '+error.toString()); 87 | if (error.error.activationId) { 88 | log.appendLine('activationId: '+error.error.activationId); 89 | } 90 | if (error.error.logs && (error.error.logs.length > 0)) { 91 | for (var x=0; x0 && firstSpace >= 0) { 109 | var key = token.substring(0, firstSpace).trim(); 110 | var value = token.substring(firstSpace+1).trim(); 111 | params[key] = value; 112 | } 113 | } 114 | 115 | console.log(params) 116 | 117 | return params; 118 | } 119 | 120 | module.exports = { 121 | pad:pad, 122 | appendHeading:appendHeading, 123 | appendEntry:appendEntry, 124 | formatQualifiedName:formatQualifiedName, 125 | setLog:setLog, 126 | printOpenWhiskError: printOpenWhiskError, 127 | parseParametersString: parseParametersString, 128 | parseQualifiedName:parseQualifiedName, 129 | appendActivation:appendActivation 130 | } 131 | -------------------------------------------------------------------------------- /static-src/commands/wsk.action.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | 'use strict'; 19 | 20 | var vscode = require('vscode'); 21 | let util = require('./util.js'); 22 | let fs = require('fs'); 23 | let spawn = require('child_process').spawn; 24 | 25 | 26 | var importDirectory = '/wsk-import/'; 27 | 28 | var log; 29 | var ow; 30 | var actions = []; 31 | var props; 32 | var context 33 | 34 | 35 | //supported OpenWhisk file formats 36 | var NODE = 'JavaScript', 37 | NODE6 = 'JavaScript 6', 38 | PHP = 'PHP', 39 | PYTHON = 'Python', 40 | SWIFT = 'Swift'; 41 | 42 | var sequenceComplete = { 43 | description:'', 44 | detail:'Sequence Complete - select this option to complete the sequence. No additional action will be added to the sequence.', 45 | label:'-- No Action --', 46 | }//'--- - Sequence Complete ---'; 47 | 48 | function register(_ow, _context, _log, _props) { 49 | ow = _ow; 50 | log = _log; 51 | props = _props; 52 | context = _context 53 | 54 | var defaultDisposable = vscode.commands.registerCommand('extension.wsk.action', defaultAction); 55 | var listDisposable = vscode.commands.registerCommand('extension.wsk.action.list', listAction); 56 | var invokeDisposable = vscode.commands.registerCommand('extension.wsk.action.invoke', invokeAction); 57 | var debugDisposable = vscode.commands.registerCommand('extension.wsk.action.debug', debugAction); 58 | var createDisposable = vscode.commands.registerCommand('extension.wsk.action.create', createAction); 59 | var updateDisposable = vscode.commands.registerCommand('extension.wsk.action.update', updateAction); 60 | var deleteDisposable = vscode.commands.registerCommand('extension.wsk.action.delete', deleteAction); 61 | var getDisposable = vscode.commands.registerCommand('extension.wsk.action.get', getAction); 62 | var initDisposable = vscode.commands.registerCommand('extension.wsk.action.init', initAction); 63 | var restDisposable = vscode.commands.registerCommand('extension.wsk.action.rest', restAction); 64 | var createSequenceDisposable = vscode.commands.registerCommand('extension.wsk.action.sequence.create', createSequenceAction); 65 | 66 | context.subscriptions.push(defaultDisposable, listDisposable, invokeDisposable, debugDisposable, createDisposable, updateDisposable, deleteDisposable, getDisposable, initDisposable, createSequenceDisposable, restDisposable); 67 | } 68 | 69 | function defaultAction(params) { 70 | 71 | log.show(true); 72 | log.appendLine('\n$ wsk action'); 73 | log.appendLine('available commands:'); 74 | log.appendLine(' init create new action boilerplate file'); 75 | log.appendLine(' create create new action'); 76 | log.appendLine(' sequence create a new sequence of actions'); 77 | log.appendLine(' update update an existing action'); 78 | log.appendLine(' invoke invoke action'); 79 | log.appendLine(' get get action'); 80 | log.appendLine(' delete delete action'); 81 | log.appendLine(' list list all actions'); 82 | log.appendLine(' rest display CURL rest invocation parameters'); 83 | } 84 | 85 | function listAction(params) { 86 | 87 | if (!props.validate()){ 88 | return; 89 | } 90 | 91 | log.show(true); 92 | log.appendLine('\n$ wsk action list'); 93 | list(); 94 | } 95 | 96 | function list() { 97 | return getList().then(function (actions) { 98 | util.appendHeading('actions'); 99 | for (var x=0; x0) { 161 | invocationParams.params = util.parseParametersString(parametersString); 162 | } 163 | ow.actions.invoke(invocationParams) 164 | .then(function(result) { 165 | var totalTime = startTime - (new Date().getTime()); 166 | clearInterval(activityInterval); 167 | log.appendLine('\n'+JSON.stringify(result.response, null, 4)); 168 | log.appendLine('>> completed in ' + (-totalTime) + 'ms'); 169 | }) 170 | .catch(function(error) { 171 | clearInterval(activityInterval); 172 | util.printOpenWhiskError(error); 173 | }); 174 | 175 | }) 176 | } 177 | 178 | 179 | function selectActionAndRequestParameters(callback) { 180 | 181 | vscode.window.showQuickPick( getListAsStringArray(), {placeHolder:'Select an action.'}).then( function (action) { 182 | 183 | if (action == undefined) { 184 | return; 185 | } 186 | 187 | var actionString = action.toString(); 188 | var startIndex = actionString.indexOf('/'); 189 | var namespace = actionString.substring(0, startIndex); 190 | var actionToInvoke = actionString.substring(startIndex+1); 191 | 192 | vscode.window.showInputBox({ 193 | placeHolder:'Enter parameters list (-p key value) or leave blank for no parameters:', 194 | value:props.get(actionToInvoke) 195 | }).then(function (parametersString) { 196 | 197 | var pString = '' 198 | if (parametersString != undefined) { 199 | pString = parametersString 200 | } 201 | 202 | props.set(actionToInvoke, pString, true); 203 | 204 | callback( namespace, actionToInvoke, parametersString ) 205 | }); 206 | }); 207 | 208 | } 209 | 210 | 211 | var wskdb = undefined; 212 | function debugAction(params) { 213 | 214 | if (!props.validate()){ 215 | return; 216 | } 217 | selectActionAndRequestParameters( function(namespace, actionToInvoke, parametersString) { 218 | 219 | wskdb = spawn('wskdb', []); 220 | wskdb.stdout.setEncoding('utf-8'); 221 | wskdb.stdin.setEncoding('utf-8'); 222 | 223 | wskdb.on('error', (error) => { 224 | console.error(error); 225 | log.appendLine("Unable to invoke the wskdb debugger. Please make sure that you have it installed."); 226 | }) 227 | 228 | wskdb.stderr.on('data', (data) => { 229 | console.log(`stderr: ${data}`); 230 | log.appendLine("ERROR:" + data.toString()) 231 | wskdb.kill(); 232 | }); 233 | 234 | wskdb.on('close', (code) => { 235 | console.log(`child process exited with code ${code}`); 236 | wskdb = undefined; 237 | }); 238 | 239 | var OK = /ok[\n|.*]*?\(wskdb\)/; 240 | var ERROR = /^Error\:/; 241 | 242 | var exit = function() { 243 | wskdb.stdout.removeAllListeners("data") 244 | wskdb.stdin.write("exit\n"); 245 | } 246 | 247 | var attachDebugger = function() { 248 | log.appendLine('\n$ attaching wskdb to ' + actionToInvoke); 249 | 250 | wskdb.stdout.removeAllListeners("data") 251 | wskdb.stdin.write("attach " + actionToInvoke + "\n"); 252 | 253 | var stdoutData; 254 | wskdb.stdout.on('data', (data) => { 255 | //console.log(`stdout: ${data}`); 256 | 257 | if (stdoutData == undefined) { 258 | stdoutData = data; 259 | } else { 260 | stdoutData += data; 261 | } 262 | 263 | var str = data.toString(); 264 | if (stdoutData.match(OK)) { 265 | invokeAction(); 266 | } else if (stdoutData.match(ERROR)) { 267 | log.appendLine(str); 268 | exit(); 269 | } 270 | }); 271 | } 272 | 273 | var invokeAction = function() { 274 | 275 | log.appendLine('$ invoking wskdb with ' + actionToInvoke + ' ' + parametersString); 276 | wskdb.stdout.removeAllListeners("data") 277 | var stdinData = "invoke " + actionToInvoke + ' ' + parametersString; 278 | wskdb.stdin.write(stdinData + "\n"); 279 | 280 | var stdoutData; 281 | var wroteOutput = false; 282 | 283 | wskdb.stdout.on('data', (data) => { 284 | //console.log(`stdout: ${data}`); 285 | 286 | var str = data.toString(); 287 | 288 | if (stdoutData == undefined) { 289 | stdoutData = data; 290 | } else { 291 | stdoutData += data; 292 | } 293 | 294 | //clean garbage that sometimes gets shoved into stdout when writing to stdin 295 | if (stdoutData.indexOf(stdinData) >= 0) { 296 | stdoutData = stdoutData.substring( stdoutData.indexOf(stdinData)+stdinData.length+1 ) 297 | } 298 | 299 | //if contains a complete json doc, print it 300 | if (stdoutData.match(/{([^}]*)}/) && !wroteOutput) { 301 | var outString = stdoutData.substring(stdoutData.indexOf("{")) 302 | outString = outString.substring(0, outString.lastIndexOf("}")+1); 303 | log.appendLine(outString); 304 | wroteOutput = true 305 | } 306 | 307 | if (stdoutData.match(OK)) { 308 | exit(); 309 | } else if (stdoutData.match(ERROR)) { 310 | log.appendLine(str); 311 | exit(); 312 | } 313 | }); 314 | } 315 | 316 | log.show(true); 317 | attachDebugger(); 318 | 319 | }); 320 | } 321 | 322 | 323 | 324 | function createAction(params) { 325 | 326 | if (!props.validate()){ 327 | return; 328 | } 329 | 330 | if (vscode.window.activeTextEditor == undefined || vscode.window.activeTextEditor.document == undefined) { 331 | vscode.window.showWarningMessage('Must have a document open for editing. The currently focused document will be used to create the OpenWhisk action.'); 332 | return; 333 | } 334 | 335 | vscode.window.showInputBox({placeHolder:'Enter a name for your action:'}) 336 | .then(function(action){ 337 | 338 | if (action == undefined) { 339 | return; 340 | } 341 | 342 | log.show(true); 343 | log.appendLine('\n$ wsk action create ' + action); 344 | 345 | log.appendLine('Creating a new action using the currently open document: ' + vscode.window.activeTextEditor.document.uri); 346 | 347 | var options = { 348 | actionName: action, 349 | action: vscode.window.activeTextEditor.document.getText() 350 | }; 351 | 352 | var swiftExt = '.swift'; 353 | var pyExt = '.py'; 354 | var phpExt = '.php'; 355 | var lastIndex = vscode.window.activeTextEditor.document.uri.fsPath.lastIndexOf(swiftExt); 356 | if (lastIndex == vscode.window.activeTextEditor.document.uri.fsPath.length - swiftExt.length) { 357 | options.action = { exec: { kind: 'swift:3', code: options.action }} 358 | } else { 359 | 360 | lastIndex = vscode.window.activeTextEditor.document.uri.fsPath.lastIndexOf(pyExt); 361 | if (lastIndex == vscode.window.activeTextEditor.document.uri.fsPath.length - pyExt.length) { 362 | options.action = { exec: { kind: 'python:3', code: options.action }} 363 | }else { 364 | lastIndex = vscode.window.activeTextEditor.document.uri.fsPath.lastIndexOf(phpExt); 365 | if (lastIndex == vscode.window.activeTextEditor.document.uri.fsPath.length - phpExt.length) { 366 | options.action = { exec: { kind: 'php:7.1', code: options.action }} 367 | }else { 368 | options.action = { exec: { kind: 'nodejs:6', code: options.action }} 369 | } 370 | } 371 | } 372 | 373 | ow.actions.create(options) 374 | .then(function(result) { 375 | log.appendLine('OpenWhisk action created: ' + util.formatQualifiedName(result)); 376 | vscode.window.showInformationMessage('OpenWhisk action created: ' + util.formatQualifiedName(result)); 377 | }) 378 | .catch(function(error) { 379 | util.printOpenWhiskError(error); 380 | }); 381 | }); 382 | 383 | } 384 | 385 | function updateAction(params) { 386 | 387 | if (!props.validate()){ 388 | return; 389 | } 390 | 391 | if (vscode.window.activeTextEditor == undefined || vscode.window.activeTextEditor.document == undefined) { 392 | vscode.window.showWarningMessage('Must have a document open for editing. The currently focused document will be used to create the OpenWhisk action.'); 393 | return; 394 | } 395 | 396 | var YES = 'Yes'; 397 | var NO = 'No'; 398 | 399 | vscode.window.showQuickPick(getListAsStringArray(), {placeHolder:'Select an action to update:'}) 400 | .then(function(action){ 401 | 402 | if (action == undefined) { 403 | return; 404 | } 405 | 406 | vscode.window.showWarningMessage('Are you sure you want to overwrite ' + action, YES, NO) 407 | .then( function(selection) { 408 | if (selection === YES) { 409 | 410 | var actionString = action.toString(); 411 | var startIndex = actionString.indexOf('/'); 412 | var namespace = actionString.substring(0, startIndex); 413 | var actionToUpdate = actionString.substring(startIndex+1); 414 | 415 | log.show(true); 416 | log.appendLine('\n$ wsk action update ' + actionToUpdate); 417 | 418 | log.appendLine('Updating action ' + actionToUpdate + ' using the currently open document: ' + vscode.window.activeTextEditor.document.uri); 419 | 420 | var options = { 421 | actionName: actionToUpdate, 422 | action: vscode.window.activeTextEditor.document.getText() 423 | }; 424 | 425 | var swiftExt = '.swift'; 426 | var pyExt = '.py'; 427 | var phpExt = '.php'; 428 | var lastIndex = vscode.window.activeTextEditor.document.uri.fsPath.lastIndexOf(swiftExt); 429 | if (lastIndex == vscode.window.activeTextEditor.document.uri.fsPath.length - swiftExt.length) { 430 | options.action = { exec: { kind: 'swift:3', code: options.action }} 431 | } else { 432 | 433 | lastIndex = vscode.window.activeTextEditor.document.uri.fsPath.lastIndexOf(pyExt); 434 | if (lastIndex == vscode.window.activeTextEditor.document.uri.fsPath.length - pyExt.length) { 435 | options.action = { exec: { kind: 'python:3', code: options.action }} 436 | }else { 437 | lastIndex = vscode.window.activeTextEditor.document.uri.fsPath.lastIndexOf(phpExt); 438 | if (lastIndex == vscode.window.activeTextEditor.document.uri.fsPath.length - phpExt.length) { 439 | options.action = { exec: { kind: 'php:7.1', code: options.action }} 440 | }else { 441 | options.action = { exec: { kind: 'nodejs:6', code: options.action }} 442 | } 443 | } 444 | } 445 | 446 | ow.actions.update(options) 447 | .then(function(result) { 448 | var message = 'OpenWhisk action updated: ' + util.formatQualifiedName(result) 449 | log.appendLine(message); 450 | vscode.window.showInformationMessage(message); 451 | }) 452 | .catch(function(error) { 453 | util.printOpenWhiskError(error); 454 | }); 455 | } 456 | }); 457 | }); 458 | } 459 | 460 | function createSequenceAction(params) { 461 | 462 | if (!props.validate()){ 463 | return; 464 | } 465 | 466 | vscode.window.showInputBox({placeHolder:'Enter a name for your action:'}) 467 | .then(function(action){ 468 | 469 | if (action == undefined) { 470 | return; 471 | } 472 | 473 | //first get the pipe action, so we can create the sequence action 474 | ow.actions.get({ 475 | actionName: 'system/pipe', 476 | blocking:true, 477 | namespace: 'whisk.system' 478 | }).then(function(result) { 479 | 480 | console.log(result); 481 | var pipeCode = result.exec.code; 482 | 483 | log.show(true); 484 | log.appendLine('\n$ wsk action create ' + action + ' --sequence'); 485 | 486 | var sequenceActions = []; 487 | 488 | var selectSequenceActions = function(firstCall) { 489 | 490 | vscode.window.showQuickPick(getListAsStringArrayForSequenceDialog(firstCall), {placeHolder:`Select action #${(sequenceActions.length+1)} for the sequence.`}) 491 | .then(function(selectedActionStep){ 492 | 493 | if (selectedActionStep == undefined) { 494 | log.appendLine('cancelled by user ESC'); 495 | return; 496 | } 497 | else if (selectedActionStep != sequenceComplete) { 498 | 499 | sequenceActions.push('/'+selectedActionStep); 500 | selectSequenceActions(false); 501 | } 502 | else { 503 | //sequence complete 504 | if (sequenceActions.length > 0) { 505 | 506 | var options = { 507 | actionName: action, 508 | action: { exec: { kind: 'nodejs:6', code: pipeCode }, 509 | parameters:[{ 510 | 'key': '_actions', 511 | 'value': sequenceActions 512 | }] 513 | } 514 | }; 515 | 516 | ow.actions.create(options) 517 | .then(function(result) { 518 | var message = 'OpenWhisk sequence created: ' + util.formatQualifiedName(result); 519 | log.appendLine(message); 520 | vscode.window.showInformationMessage(message); 521 | }) 522 | .catch(function(error) { 523 | util.printOpenWhiskError(error); 524 | }); 525 | } 526 | } 527 | }); 528 | } 529 | 530 | selectSequenceActions(true); 531 | 532 | 533 | 534 | }); 535 | }); 536 | } 537 | 538 | function deleteAction(params) { 539 | 540 | if (!props.validate()){ 541 | return; 542 | } 543 | 544 | vscode.window.showQuickPick(getListAsStringArray(), {placeHolder:'Select an action to delete:'}) 545 | .then(function(action){ 546 | 547 | if (action == undefined) { 548 | return; 549 | } 550 | 551 | var actionString = action.toString(); 552 | var startIndex = actionString.indexOf('/'); 553 | var namespace = actionString.substring(0, startIndex); 554 | var actionToDelete = actionString.substring(startIndex+1); 555 | 556 | log.show(true); 557 | log.appendLine('\n$ wsk action delete ' + actionToDelete); 558 | 559 | var options = { 560 | actionName: actionToDelete 561 | }; 562 | 563 | var YES = 'Yes'; 564 | var NO = 'No'; 565 | 566 | vscode.window.showWarningMessage('Are you sure you want to delete ' + actionToDelete, YES, NO) 567 | .then( function(selection) { 568 | if (selection === YES) { 569 | ow.actions.delete(options) 570 | .then(function(result) { 571 | console.log(result); 572 | log.appendLine('OpenWhisk action deleted: ' + util.formatQualifiedName(result)); 573 | vscode.window.showInformationMessage('OpenWhisk action deleted: ' + util.formatQualifiedName(result)); 574 | }) 575 | .catch(function(error) { 576 | util.printOpenWhiskError(error); 577 | }); 578 | } 579 | }); 580 | }); 581 | } 582 | 583 | function getAction(params) { 584 | 585 | if (!props.validate()){ 586 | return; 587 | } 588 | 589 | if (!hasValidProjectRoot()) { 590 | return; 591 | } 592 | 593 | vscode.window.showQuickPick( getListAsStringArray(), {placeHolder:'Select an action to retrieve:'}).then( function (action) { 594 | 595 | if (action == undefined) { 596 | return; 597 | } 598 | 599 | var actionString = action.toString(); 600 | var startIndex = actionString.indexOf('/'); 601 | var namespace = actionString.substring(0, startIndex); 602 | var actionToGet = actionString.substring(startIndex+1); 603 | 604 | log.show(true); 605 | log.appendLine('\n$ wsk action get ' + actionToGet); 606 | 607 | var activityInterval = setInterval(function() { 608 | log.append('.'); 609 | },300); 610 | 611 | var startTime = new Date().getTime(); 612 | ow.actions.get({ 613 | actionName: actionToGet, 614 | blocking:true, 615 | namespace: namespace 616 | }).then(function(result) { 617 | var totalTime = startTime - (new Date().getTime());; 618 | clearInterval(activityInterval); 619 | log.appendLine('>> completed in ' + (-totalTime) + 'ms') 620 | 621 | if (isSequence(result)) { 622 | var message = actionToGet + ' is a sequence. It cannot be edited directly, and has not be written to a file.'; 623 | log.appendLine(message) 624 | vscode.window.showWarningMessage(message); 625 | log.appendLine('You can edit these individual sequence actions: '); 626 | for (var x=0; x < result.parameters.length; x ++){ 627 | var param = result.parameters[x]; 628 | if (param.key == '_actions') { 629 | for (var y=0; y < param.value.length; y ++){ 630 | log.appendLine(' > ' + param.value[y]) 631 | } 632 | } 633 | } 634 | } 635 | else { 636 | log.appendLine(JSON.stringify(result, null, 4)) 637 | //todo: check if file exists before writing 638 | //todo: make sure user has selected a directory to import into 639 | 640 | var buffer = new Buffer(result.exec.code); 641 | var fileName = result.name; 642 | 643 | var fileExt = ''; 644 | if (result.exec.kind.toString().search('swift') >= 0) { 645 | fileName += '.swift' 646 | } else if (result.exec.kind.toString().search('python') >= 0) { 647 | fileName += '.py' 648 | } else { 649 | fileName += '.js' 650 | } 651 | 652 | var path = vscode.workspace.rootPath + importDirectory 653 | 654 | if (!fs.existsSync(path)){ 655 | fs.mkdirSync(path); 656 | } 657 | 658 | var filePath = getUniqueFilename(path, fileName, fileExt); 659 | 660 | fs.open(filePath, 'w', function(err, fd) { 661 | if (err) { 662 | throw 'error opening file: ' + err; 663 | } 664 | 665 | fs.write(fd, buffer, 0, buffer.length, null, function(err) { 666 | if (err) throw 'error writing file: ' + err; 667 | fs.close(fd, function() { 668 | //console.log('file written'); 669 | 670 | vscode.workspace.openTextDocument(filePath) 671 | .then(function(document) { 672 | vscode.window.showTextDocument(document); 673 | vscode.window.showInformationMessage('Successfully imported ' + importDirectory + fileName); 674 | log.appendLine('Successfully imported file to ' + filePath); 675 | }); 676 | 677 | }) 678 | }); 679 | }); 680 | } 681 | }) 682 | .catch(function(error) { 683 | util.printOpenWhiskError(error); 684 | }); 685 | }); 686 | } 687 | 688 | function isSequence(result) { 689 | if (result.parameters) { 690 | for (var x=0; x < result.parameters.length; x ++){ 691 | var param = result.parameters[x]; 692 | if (param.key == '_actions') { 693 | return true; 694 | } 695 | } 696 | } 697 | return false; 698 | } 699 | 700 | function initAction(params) { 701 | 702 | if (!hasValidProjectRoot()) { 703 | return; 704 | } 705 | 706 | vscode.window.showQuickPick( [NODE, PHP, PYTHON, SWIFT], {placeHolder:'Select the type of action:'}).then( function (action) { 707 | 708 | if (action == undefined) { 709 | return; 710 | } 711 | 712 | log.show(true); 713 | log.appendLine('\n$ wsk action init:' + action); 714 | 715 | var templateName = action.toLowerCase() 716 | templateName = templateName.replace(/\s/g, ''); 717 | templateName = context.extensionPath + "/static-src/templates/" + templateName + ".template" 718 | var template = ''; 719 | 720 | 721 | var path = vscode.workspace.rootPath + importDirectory 722 | 723 | fs.readFile( templateName, 'utf8', function (err,data) { 724 | if (err) { 725 | log.appendLine(err); 726 | console.log(err) 727 | return false; 728 | } 729 | 730 | template = data.toString() 731 | 732 | //todo: make it look for unique names or prompt for name 733 | 734 | var buffer = new Buffer(template); 735 | var fileName = 'newAction'; 736 | var fileExt = ''; 737 | if (action == NODE || action == NODE6) { 738 | fileExt += '.js' 739 | } else if (action == PHP) { 740 | fileExt += '.php' 741 | } else if (action == PYTHON) { 742 | fileExt += '.py' 743 | } else { 744 | fileExt += '.swift' 745 | } 746 | 747 | var path = vscode.workspace.rootPath + importDirectory 748 | 749 | if (!fs.existsSync(path)){ 750 | fs.mkdirSync(path); 751 | } 752 | 753 | var filePath = getUniqueFilename(path, fileName, fileExt); 754 | 755 | fs.open(filePath, 'w', function(err, fd) { 756 | if (err) { 757 | throw 'error opening file: ' + err; 758 | } 759 | 760 | fs.write(fd, buffer, 0, buffer.length, null, function(err) { 761 | if (err) throw 'error writing file: ' + err; 762 | fs.close(fd, function() { 763 | //console.log('file written'); 764 | 765 | vscode.workspace.openTextDocument(filePath) 766 | .then(function(document) { 767 | //console.log(document) 768 | vscode.window.showTextDocument(document); 769 | log.appendLine('Created new action using ' + action + ' template as ' + filePath); 770 | }); 771 | 772 | }) 773 | }); 774 | }); 775 | 776 | }); 777 | }); 778 | } 779 | 780 | function restAction(params) { 781 | 782 | if (!props.validate()){ 783 | return; 784 | } 785 | 786 | vscode.window.showQuickPick( getListAsStringArray(), {placeHolder:'Select an action to retrieve:'}).then( function (action) { 787 | 788 | if (action == undefined) { 789 | return; 790 | } 791 | 792 | var actionString = action.toString(); 793 | var startIndex = actionString.indexOf('/'); 794 | var namespace = actionString.substring(0, startIndex); 795 | var actionToGet = actionString.substring(startIndex+1); 796 | 797 | log.show(true); 798 | log.appendLine('\n$ wsk action get ' + actionToGet); 799 | 800 | var activityInterval = setInterval(function() { 801 | log.append('.'); 802 | },300); 803 | 804 | 805 | var apiRoot = ow.actions.options.api 806 | var startTime = new Date().getTime(); 807 | ow.actions.get({ 808 | actionName: actionToGet, 809 | blocking:true, 810 | namespace: namespace 811 | }).then(function(result) { 812 | var totalTime = startTime - (new Date().getTime());; 813 | clearInterval(activityInterval); 814 | 815 | var hash = new Buffer(props.get('auth')).toString('base64') 816 | var parsedNamespace = util.parseQualifiedName(result.namespace) 817 | 818 | var restEndpoint =`curl -d '{ "arg": "value" }' '${props.host()}namespaces/${parsedNamespace.namespace}/actions/${parsedNamespace.name}/${result.name}?blocking=true' -X POST -H 'Authorization: Basic ${hash}' -H 'Content-Type: application/json'`; 819 | 820 | log.appendLine(`\nCURL REST invocation (You still need to set parameter key/value pairs):`); 821 | log.appendLine(`-------------------------------------------------------------------------`); 822 | log.appendLine(`\n${restEndpoint}`); 823 | }) 824 | .catch(function(error) { 825 | util.printOpenWhiskError(error); 826 | }); 827 | }); 828 | } 829 | 830 | function hasValidProjectRoot() { 831 | if (vscode.workspace.rootPath == undefined) { 832 | var message = 'You must specify a project folder before you can import actions from OpenWhisk. Please use the \'File\' menu, select \'Open\', then select a folder for your project.'; 833 | 834 | log.show(); 835 | log.appendLine(message); 836 | 837 | vscode.window.showWarningMessage(message) 838 | return false; 839 | } 840 | return true; 841 | } 842 | 843 | function getUniqueFilename(path, fileName, fileExt) { 844 | 845 | var unique = false; 846 | var attempt = 0; 847 | while (!unique) { 848 | var suffix = (attempt > 0) ? (attempt+1):""; 849 | var uniquePath = path + fileName + suffix + fileExt; 850 | 851 | //if file exists, updated attempt count and try again in the loop 852 | if (fs.existsSync(uniquePath)) { 853 | attempt++; 854 | } 855 | else { 856 | var unique = true; 857 | return uniquePath; 858 | } 859 | } 860 | return undefined; 861 | } 862 | 863 | module.exports = { 864 | register: register, 865 | list:list, 866 | getListAsStringArray:getListAsStringArray 867 | }; 868 | -------------------------------------------------------------------------------- /static-src/commands/wsk.activation.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | 'use strict'; 19 | 20 | var vscode = require('vscode'); 21 | let util = require('./util.js'); 22 | 23 | var log; 24 | var ow; 25 | var props; 26 | 27 | function register(_ow, context, _log, _props) { 28 | ow = _ow; 29 | log = _log; 30 | props = _props; 31 | 32 | var defaultDisposable = vscode.commands.registerCommand('extension.wsk.activation', defaultAction); 33 | var listDisposable = vscode.commands.registerCommand('extension.wsk.activation.list', listAction); 34 | var getDisposable = vscode.commands.registerCommand('extension.wsk.activation.get', getAction); 35 | var logsDisposable = vscode.commands.registerCommand('extension.wsk.activation.logs', logsAction); 36 | var resultDisposable = vscode.commands.registerCommand('extension.wsk.activation.result', resultAction); 37 | 38 | 39 | context.subscriptions.push(defaultDisposable, listDisposable, getDisposable, logsDisposable,resultDisposable ); 40 | } 41 | 42 | 43 | function defaultAction(params) { 44 | 45 | log.show(true); 46 | log.appendLine('\n$ wsk activation'); 47 | log.appendLine('available commands:'); 48 | log.appendLine(' list retrieve activations'); 49 | log.appendLine(' get get activation'); 50 | log.appendLine(' logs get the logs of an activation'); 51 | log.appendLine(' result get resul tof an activation'); 52 | } 53 | 54 | 55 | 56 | 57 | 58 | function listAction(params) { 59 | 60 | if (!props.validate()){ 61 | return; 62 | } 63 | 64 | log.show(true); 65 | log.appendLine('\n$ wsk activation list'); 66 | list(); 67 | } 68 | 69 | function list() { 70 | 71 | if (!props.validate()){ 72 | return; 73 | } 74 | 75 | return getList().then(function (activations) { 76 | util.appendHeading('activations'); 77 | for (var x=0; x> completed in ' + (-totalTime) + 'ms'); 124 | }; 125 | 126 | getActionImpl(params, "get", callback); 127 | } 128 | 129 | 130 | function logsAction(params) { 131 | 132 | if (!props.validate()){ 133 | return; 134 | } 135 | 136 | var startTime = new Date().getTime(); 137 | var callback = function(result) { 138 | var totalTime = startTime - (new Date().getTime()); 139 | var logs = result.logs; 140 | log.appendLine(""); 141 | if (result.logs) { 142 | for (var x =0; x > completed in ' + (-totalTime) + 'ms'); 147 | }; 148 | 149 | getActionImpl(params, "logs", callback); 150 | } 151 | 152 | 153 | function resultAction(params) { 154 | 155 | if (!props.validate()){ 156 | return; 157 | } 158 | 159 | var startTime = new Date().getTime(); 160 | var callback = function(result) { 161 | var totalTime = startTime - (new Date().getTime()); 162 | log.appendLine("\n"+JSON.stringify(result.response.result, null, 4)) 163 | log.appendLine('>> completed in ' + (-totalTime) + 'ms'); 164 | }; 165 | 166 | getActionImpl(params, "result", callback); 167 | } 168 | 169 | 170 | function getActionImpl(params, command, callback) { 171 | 172 | if (!props.validate()){ 173 | return; 174 | } 175 | 176 | vscode.window.showInputBox({placeHolder:'Enter an activation id:'}) 177 | .then(function(activationId){ 178 | 179 | if (activationId == undefined) { 180 | return; 181 | } 182 | 183 | log.appendLine('\n$ wsk activation ' + command + ' ' + activationId); 184 | 185 | var activityInterval = setInterval(function() { 186 | log.append('.'); 187 | },300); 188 | 189 | var invocationParams = { 190 | "activation": activationId, 191 | "namespace": "_" 192 | } 193 | ow.activations.get(invocationParams) 194 | .then(function(result) { 195 | clearInterval(activityInterval); 196 | callback(result) 197 | }) 198 | .catch(function(error) { 199 | clearInterval(activityInterval); 200 | util.printOpenWhiskError(error); 201 | }); 202 | }); 203 | } 204 | 205 | 206 | 207 | module.exports = { 208 | register: register, 209 | list:list 210 | }; 211 | -------------------------------------------------------------------------------- /static-src/commands/wsk.help.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | 'use strict'; 19 | 20 | var vscode = require('vscode'); 21 | 22 | var log; 23 | var ow; 24 | var props; 25 | 26 | function register(_ow, context, _log, _props) { 27 | ow = _ow; 28 | log = _log; 29 | props = _props; 30 | 31 | var disposable = vscode.commands.registerCommand('extension.wsk.help', defaultAction); 32 | context.subscriptions.push(disposable); 33 | } 34 | 35 | function defaultAction(params) { 36 | 37 | log.show(true); 38 | log.appendLine('\n$ wsk help'); 39 | log.appendLine('available commands:'); 40 | log.appendLine(' bluemix launch OpenWhisk console on Bluemix'); 41 | log.appendLine(' docs open OpenWhisk docs'); 42 | log.appendLine(' property set set property'); 43 | log.appendLine(' property unset unset property'); 44 | log.appendLine(' property get get property'); 45 | log.appendLine(' action see available commands for OpenWhisk actions'); 46 | } 47 | 48 | module.exports = { 49 | register: register 50 | }; 51 | -------------------------------------------------------------------------------- /static-src/commands/wsk.list.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | 'use strict'; 19 | 20 | var vscode = require('vscode'); 21 | let util = require('./util.js'); 22 | 23 | let wskAction = require('./wsk.action.js'); 24 | let wskPackage = require('./wsk.package.js'); 25 | let wskTrigger = require('./wsk.trigger.js'); 26 | let wskRule = require('./wsk.rule.js'); 27 | 28 | var log; 29 | var ow; 30 | var props; 31 | 32 | function register(_ow, context, _log, _props) { 33 | ow = _ow; 34 | log = _log; 35 | props = _props; 36 | 37 | 38 | var disposable = vscode.commands.registerCommand('extension.wsk.list', list); 39 | context.subscriptions.push(disposable); 40 | } 41 | 42 | function list() { 43 | 44 | log.appendLine('\n$ wsk list'); 45 | 46 | if (!props.validate()){ 47 | return; 48 | } 49 | 50 | wskPackage.list() 51 | .then(function(){ 52 | return wskAction.list() 53 | }) 54 | .then(function(){ 55 | return wskTrigger.list() 56 | }) 57 | .then(function(){ 58 | return wskRule.list() 59 | }) 60 | } 61 | 62 | 63 | module.exports = { 64 | register: register 65 | }; 66 | -------------------------------------------------------------------------------- /static-src/commands/wsk.package.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | 'use strict'; 19 | 20 | var vscode = require('vscode'); 21 | let util = require('./util.js'); 22 | 23 | var log; 24 | var ow; 25 | var props; 26 | 27 | function register(_ow, context, _log, _props) { 28 | ow = _ow; 29 | log = _log; 30 | props = _props; 31 | 32 | var defaultDisposable = vscode.commands.registerCommand('extension.wsk.package', defaultAction); 33 | context.subscriptions.push(defaultDisposable); 34 | } 35 | 36 | 37 | function defaultAction(params) { 38 | log.show(true); 39 | log.appendLine('\n$ wsk package'); 40 | log.appendLine('available commands:'); 41 | log.appendLine(' create create a new package'); 42 | log.appendLine(' update create a new package'); 43 | log.appendLine(' bind bind parameters to the package'); 44 | log.appendLine(' refresh refresh package bindings'); 45 | log.appendLine(' get get package'); 46 | log.appendLine(' delete delete package'); 47 | log.appendLine(' list list all packages'); 48 | } 49 | 50 | function list() { 51 | 52 | if (!props.validate()){ 53 | return; 54 | } 55 | 56 | return ow.packages.list().then(function (packages) { 57 | util.appendHeading('packages'); 58 | for (var x=0; x> completed in ' + (-totalTime) + 'ms'); 183 | 184 | 185 | vscode.window.showWarningMessage('Would you like to activate ' + rule + '?', YES, NO) 186 | .then( function(selection) { 187 | if (selection === YES) { 188 | 189 | var qualifiedRule = props.get("namespace") + "/" + rule; 190 | 191 | doStatusChange(qualifiedRule, true); 192 | } 193 | }); 194 | 195 | }) 196 | .catch(function(error) { 197 | clearInterval(activityInterval); 198 | util.printOpenWhiskError(error); 199 | }); 200 | 201 | }) 202 | }) 203 | }); 204 | } 205 | 206 | function updateAction(params) { 207 | 208 | if (!props.validate()){ 209 | return; 210 | } 211 | 212 | var YES = 'Yes'; 213 | var NO = 'No'; 214 | 215 | vscode.window.showQuickPick(getListAsStringArray(), {placeHolder:'Select a rule to update:'}) 216 | .then(function(rule){ 217 | 218 | if (rule == undefined) { 219 | return; 220 | } 221 | 222 | var parsedRule = util.parseQualifiedName(rule); 223 | rule = parsedRule.name; 224 | 225 | 226 | vscode.window.showQuickPick(getTriggerListAsStringArray(), {placeHolder:'Select a trigger to bind:'}) 227 | .then(function(trigger){ 228 | 229 | if (trigger == undefined) { 230 | return; 231 | } 232 | 233 | vscode.window.showQuickPick(getActionListAsStringArray(), {placeHolder:'Select a action to bind:'}) 234 | .then(function(action){ 235 | 236 | if (action == undefined) { 237 | return; 238 | } 239 | 240 | var parsedTrigger = util.parseQualifiedName(trigger); 241 | var parsedAction = util.parseQualifiedName(action); 242 | 243 | log.show(true); 244 | log.appendLine(`\n$ wsk rule update ${rule} ${parsedTrigger.name} ${parsedAction.name}`); 245 | 246 | vscode.window.showWarningMessage('Are you sure you want to overwrite ' + rule, YES, NO) 247 | .then( function(selection) { 248 | if (selection === YES) { 249 | 250 | var activityInterval = setInterval(function() { 251 | log.append('.'); 252 | },300); 253 | 254 | var startTime = new Date().getTime(); 255 | var invocationParams = { 256 | ruleName: rule, 257 | trigger:parsedTrigger.name, 258 | action:parsedAction.name 259 | } 260 | 261 | ow.rules.update(invocationParams) 262 | .then(function(result) { 263 | var totalTime = startTime - (new Date().getTime()); 264 | clearInterval(activityInterval); 265 | log.appendLine(JSON.stringify(result, null, 4)) 266 | log.appendLine('>> completed in ' + (-totalTime) + 'ms'); 267 | }) 268 | .catch(function(error) { 269 | clearInterval(activityInterval); 270 | util.printOpenWhiskError(error); 271 | }); 272 | } else { 273 | log.appendLine('cancelled by user') 274 | } 275 | }) 276 | }) 277 | }) 278 | }); 279 | } 280 | 281 | 282 | 283 | 284 | 285 | function deleteAction(params) { 286 | 287 | if (!props.validate()){ 288 | return; 289 | } 290 | 291 | vscode.window.showQuickPick(getListAsStringArray(), {placeHolder:'Select a rule to delete:'}) 292 | .then(function(rule){ 293 | 294 | if (rule == undefined) { 295 | return; 296 | } 297 | 298 | var parsedRule = util.parseQualifiedName(rule) 299 | 300 | log.show(true); 301 | log.appendLine('\n$ wsk trigger delete ' + parsedRule.name); 302 | 303 | var options = { 304 | ruleName: parsedRule.name, 305 | namespace: parsedRule.namespace 306 | }; 307 | 308 | var YES = 'Yes'; 309 | var NO = 'No'; 310 | 311 | vscode.window.showWarningMessage('Are you sure you want to delete ' + parsedRule.name, YES, NO) 312 | .then( function(selection) { 313 | if (selection === YES) { 314 | ow.rules.delete(options) 315 | .then(function(result) { 316 | var message = 'OpenWhisk rule deleted: ' + util.formatQualifiedName(result); 317 | log.appendLine(message); 318 | vscode.window.showInformationMessage(message); 319 | }) 320 | .catch(function(error) { 321 | log.appendLine('rule status must be \'inactive\' to delete'); 322 | }); 323 | } 324 | }); 325 | }); 326 | } 327 | 328 | 329 | function getAction(params) { 330 | 331 | if (!props.validate()){ 332 | return; 333 | } 334 | 335 | vscode.window.showQuickPick(getListAsStringArray(), {placeHolder:'Select a rule to fetch:'}) 336 | .then(function(rule){ 337 | 338 | if (rule == undefined) { 339 | return; 340 | } 341 | 342 | var parsedRule = util.parseQualifiedName(rule) 343 | 344 | log.appendLine('\n$ wsk rule get ' + parsedRule.name); 345 | 346 | var activityInterval = setInterval(function() { 347 | log.append('.'); 348 | },300); 349 | 350 | var startTime = new Date().getTime(); 351 | var invocationParams = { 352 | ruleName: parsedRule.name, 353 | blocking:true, 354 | namespace: parsedRule.namespace 355 | } 356 | ow.rules.get(invocationParams) 357 | .then(function(result) { 358 | var totalTime = startTime - (new Date().getTime()); 359 | clearInterval(activityInterval); 360 | log.appendLine(JSON.stringify(result, null, 4)) 361 | log.appendLine('>> completed in ' + (-totalTime) + 'ms'); 362 | }) 363 | .catch(function(error) { 364 | clearInterval(activityInterval); 365 | util.printOpenWhiskError(error); 366 | }); 367 | }); 368 | } 369 | 370 | 371 | function statusAction(params) { 372 | 373 | if (!props.validate()){ 374 | return; 375 | } 376 | 377 | vscode.window.showQuickPick(getListAsStringArray(), {placeHolder:'Select a rule to fetch:'}) 378 | .then(function(rule){ 379 | 380 | if (rule == undefined) { 381 | return; 382 | } 383 | 384 | var parsedRule = util.parseQualifiedName(rule) 385 | 386 | log.appendLine('\n$ wsk rule status ' + parsedRule.name); 387 | 388 | var activityInterval = setInterval(function() { 389 | log.append('.'); 390 | },300); 391 | 392 | var startTime = new Date().getTime(); 393 | var invocationParams = { 394 | ruleName: parsedRule.name, 395 | blocking:true, 396 | namespace: parsedRule.namespace 397 | } 398 | ow.rules.get(invocationParams) 399 | .then(function(result) { 400 | var totalTime = startTime - (new Date().getTime()); 401 | clearInterval(activityInterval); 402 | log.appendLine(`\nok: rule ${parsedRule.name} is ${result.status}`) 403 | log.appendLine('>> completed in ' + (-totalTime) + 'ms'); 404 | }) 405 | .catch(function(error) { 406 | clearInterval(activityInterval); 407 | util.printOpenWhiskError(error); 408 | }); 409 | }); 410 | } 411 | 412 | 413 | 414 | 415 | function enableAction(params) { 416 | 417 | doStatusChange(undefined, true); 418 | } 419 | 420 | function disableAction(params) { 421 | 422 | doStatusChange(undefined, false); 423 | } 424 | 425 | function doStatusChange(rule, enable) { 426 | if (!props.validate()){ 427 | return; 428 | } 429 | 430 | var statusChangeImpl = function(rule){ 431 | 432 | if (rule == undefined) { 433 | return; 434 | } 435 | 436 | var parsedRule = util.parseQualifiedName(rule) 437 | log.appendLine(`\n$ wsk rule ${enable?'enable':'disable'} ${parsedRule.name}`); 438 | 439 | var activityInterval = setInterval(function() { 440 | log.append('.'); 441 | },300); 442 | 443 | var startTime = new Date().getTime(); 444 | var invocationParams = { 445 | ruleName: parsedRule.name, 446 | blocking:true, 447 | namespace: parsedRule.namespace 448 | } 449 | 450 | var callback = function(result) { 451 | var totalTime = startTime - (new Date().getTime()); 452 | clearInterval(activityInterval); 453 | log.appendLine(`ok: rule ${parsedRule.name} ${enable?'enabled':'disabled'}`) 454 | log.appendLine('>> completed in ' + (-totalTime) + 'ms'); 455 | } 456 | var error = function(error) { 457 | clearInterval(activityInterval); 458 | util.printOpenWhiskError(error); 459 | } 460 | 461 | if (enable) { 462 | ow.rules.enable(invocationParams) 463 | .then(callback) 464 | .catch(error); 465 | } else { 466 | ow.rules.disable(invocationParams) 467 | .then(callback) 468 | .catch(error); 469 | } 470 | } 471 | 472 | if (rule == undefined) { 473 | //${enable?'enable'?'disable'} 474 | vscode.window.showQuickPick(getListAsStringArray(), {placeHolder:`Select a rule to :`}) 475 | .then(statusChangeImpl); 476 | } else { 477 | statusChangeImpl(rule) 478 | } 479 | 480 | } 481 | 482 | 483 | 484 | module.exports = { 485 | register: register, 486 | list:list 487 | }; 488 | -------------------------------------------------------------------------------- /static-src/commands/wsk.trigger.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | 'use strict'; 19 | 20 | var vscode = require('vscode'); 21 | let util = require('./util.js'); 22 | 23 | var log; 24 | var ow; 25 | var props; 26 | 27 | function register(_ow, context, _log, _props) { 28 | ow = _ow; 29 | log = _log; 30 | props = _props; 31 | 32 | var defaultDisposable = vscode.commands.registerCommand('extension.wsk.trigger', defaultAction); 33 | var listDisposable = vscode.commands.registerCommand('extension.wsk.trigger.list', listAction); 34 | var createDisposable = vscode.commands.registerCommand('extension.wsk.trigger.create', createAction); 35 | var updateDisposable = vscode.commands.registerCommand('extension.wsk.trigger.update', updateAction); 36 | var deleteDisposable = vscode.commands.registerCommand('extension.wsk.trigger.delete', deleteAction); 37 | var getDisposable = vscode.commands.registerCommand('extension.wsk.trigger.get', getAction); 38 | var fireDisposable = vscode.commands.registerCommand('extension.wsk.trigger.fire', fireAction); 39 | 40 | 41 | 42 | context.subscriptions.push(defaultDisposable, listDisposable, createDisposable, updateDisposable, deleteDisposable, getDisposable, fireDisposable); 43 | } 44 | 45 | 46 | function defaultAction(params) { 47 | 48 | log.show(true); 49 | log.appendLine('\n$ wsk trigger'); 50 | log.appendLine('available commands:'); 51 | log.appendLine(' create create new trigger'); 52 | log.appendLine(' update update an existing trigger'); 53 | log.appendLine(' fire fire trigger event'); 54 | log.appendLine(' get get trigger'); 55 | log.appendLine(' delete delete trigger'); 56 | log.appendLine(' list list all triggers'); 57 | } 58 | 59 | 60 | 61 | function listAction(params) { 62 | 63 | if (!props.validate()){ 64 | return; 65 | } 66 | 67 | log.show(true); 68 | log.appendLine('\n$ wsk trigger list'); 69 | list(); 70 | } 71 | 72 | function list() { 73 | 74 | if (!props.validate()){ 75 | return; 76 | } 77 | 78 | return getList().then(function (triggers) { 79 | util.appendHeading('triggers'); 80 | for (var x=0; x0) { 149 | var params = util.parseParametersString(pString); 150 | var paramsArray = []; 151 | 152 | for (var key in params) { 153 | var object = {}; 154 | object.key = key; 155 | object.value = params[key]; 156 | paramsArray.push(object) 157 | } 158 | 159 | invocationParams.trigger = { 160 | "parameters":paramsArray 161 | }; 162 | } 163 | ow.triggers.create(invocationParams) 164 | .then(function(result) { 165 | var totalTime = startTime - (new Date().getTime()); 166 | clearInterval(activityInterval); 167 | log.appendLine(JSON.stringify(result, null, 4)) 168 | log.appendLine('>> completed in ' + (-totalTime) + 'ms'); 169 | }) 170 | .catch(function(error) { 171 | clearInterval(activityInterval); 172 | util.printOpenWhiskError(error); 173 | }); 174 | }); 175 | }); 176 | } 177 | 178 | 179 | function updateAction(params) { 180 | 181 | if (!props.validate()){ 182 | return; 183 | } 184 | 185 | var YES = 'Yes'; 186 | var NO = 'No'; 187 | 188 | vscode.window.showQuickPick(getListAsStringArray(), {placeHolder:'Select a trigger to update:'}) 189 | .then(function(trigger){ 190 | 191 | if (trigger == undefined) { 192 | return; 193 | } 194 | 195 | 196 | 197 | var triggerString = trigger.toString(); 198 | var startIndex = triggerString.indexOf('/'); 199 | var namespace = triggerString.substring(0, startIndex); 200 | var triggerToUpdate = triggerString.substring(startIndex+1); 201 | 202 | 203 | vscode.window.showInputBox({ 204 | placeHolder:'Enter parameters to bind (-p key value) or leave blank for no parameters:', 205 | value:'' 206 | }).then(function (parametersString) { 207 | 208 | var pString = '' 209 | if (parametersString != undefined) { 210 | pString = parametersString 211 | } 212 | 213 | log.show(true); 214 | log.appendLine('\n$ wsk trigger update ' + trigger + ' ' + pString); 215 | 216 | vscode.window.showWarningMessage('Are you sure you want to overwrite ' + trigger, YES, NO) 217 | .then( function(selection) { 218 | if (selection === YES) { 219 | 220 | var activityInterval = setInterval(function() { 221 | log.append('.'); 222 | },300); 223 | 224 | var startTime = new Date().getTime(); 225 | var invocationParams = { 226 | triggerName: triggerToUpdate, 227 | blocking:true, 228 | namespace: namespace 229 | } 230 | 231 | if (pString.length>0) { 232 | var params = util.parseParametersString(pString); 233 | var paramsArray = []; 234 | 235 | for (var key in params) { 236 | var object = {}; 237 | object.key = key; 238 | object.value = params[key]; 239 | paramsArray.push(object) 240 | } 241 | 242 | invocationParams.trigger = { 243 | "parameters":paramsArray 244 | }; 245 | } 246 | ow.triggers.update(invocationParams) 247 | .then(function(result) { 248 | var totalTime = startTime - (new Date().getTime()); 249 | clearInterval(activityInterval); 250 | log.appendLine(JSON.stringify(result, null, 4)) 251 | log.appendLine('>> completed in ' + (-totalTime) + 'ms'); 252 | }) 253 | .catch(function(error) { 254 | clearInterval(activityInterval); 255 | util.printOpenWhiskError(error); 256 | }); 257 | 258 | } else { 259 | log.appendLine('cancelled by user') 260 | } 261 | }); 262 | 263 | }); 264 | }); 265 | } 266 | 267 | 268 | function deleteAction(params) { 269 | 270 | if (!props.validate()){ 271 | return; 272 | } 273 | 274 | vscode.window.showQuickPick(getListAsStringArray(), {placeHolder:'Select a trigger to delete:'}) 275 | .then(function(trigger){ 276 | 277 | if (trigger == undefined) { 278 | return; 279 | } 280 | 281 | var triggerString = trigger.toString(); 282 | var startIndex = triggerString.indexOf('/'); 283 | var namespace = triggerString.substring(0, startIndex); 284 | var triggerToDelete = triggerString.substring(startIndex+1); 285 | 286 | log.show(true); 287 | log.appendLine('\n$ wsk trigger delete ' + triggerToDelete); 288 | 289 | var options = { 290 | triggerName: triggerToDelete 291 | }; 292 | 293 | var YES = 'Yes'; 294 | var NO = 'No'; 295 | 296 | vscode.window.showWarningMessage('Are you sure you want to delete ' + triggerToDelete, YES, NO) 297 | .then( function(selection) { 298 | if (selection === YES) { 299 | ow.triggers.delete(options) 300 | .then(function(result) { 301 | var message = 'OpenWhisk trigger deleted: ' + util.formatQualifiedName(result); 302 | log.appendLine(message); 303 | vscode.window.showInformationMessage(message); 304 | }) 305 | .catch(function(error) { 306 | util.printOpenWhiskError(error); 307 | }); 308 | } 309 | }); 310 | }); 311 | } 312 | 313 | 314 | function getAction(params) { 315 | 316 | if (!props.validate()){ 317 | return; 318 | } 319 | 320 | vscode.window.showQuickPick(getListAsStringArray(), {placeHolder:'Select a trigger to fetch:'}) 321 | .then(function(trigger){ 322 | 323 | if (trigger == undefined) { 324 | return; 325 | } 326 | 327 | var triggerString = trigger.toString(); 328 | var startIndex = triggerString.indexOf('/'); 329 | var namespace = triggerString.substring(0, startIndex); 330 | var triggerToGet = triggerString.substring(startIndex+1); 331 | 332 | log.appendLine('\n$ wsk trigger get ' + triggerToGet); 333 | 334 | var activityInterval = setInterval(function() { 335 | log.append('.'); 336 | },300); 337 | 338 | var startTime = new Date().getTime(); 339 | var invocationParams = { 340 | triggerName: triggerToGet, 341 | blocking:true, 342 | namespace: namespace 343 | } 344 | ow.triggers.get(invocationParams) 345 | .then(function(result) { 346 | var totalTime = startTime - (new Date().getTime()); 347 | clearInterval(activityInterval); 348 | log.appendLine(JSON.stringify(result, null, 4)) 349 | log.appendLine('>> completed in ' + (-totalTime) + 'ms'); 350 | }) 351 | .catch(function(error) { 352 | clearInterval(activityInterval); 353 | util.printOpenWhiskError(error); 354 | }); 355 | }); 356 | } 357 | 358 | function fireAction(params) { 359 | 360 | if (!props.validate()){ 361 | return; 362 | } 363 | 364 | vscode.window.showQuickPick(getListAsStringArray(), {placeHolder:'Select a trigger to fire:'}) 365 | .then(function(trigger){ 366 | 367 | if (trigger == undefined) { 368 | return; 369 | } 370 | 371 | var triggerString = trigger.toString(); 372 | var startIndex = triggerString.indexOf('/'); 373 | var namespace = triggerString.substring(0, startIndex); 374 | var triggerToFire = triggerString.substring(startIndex+1); 375 | 376 | vscode.window.showInputBox({ 377 | placeHolder:'Enter parameters (-p key value) or leave blank for no parameters:', 378 | value:'' 379 | }).then(function (parametersString) { 380 | 381 | var pString = '' 382 | if (parametersString != undefined) { 383 | pString = parametersString 384 | } 385 | 386 | log.show(true); 387 | log.appendLine('\n$ wsk trigger fire ' + trigger + ' ' + pString); 388 | 389 | var activityInterval = setInterval(function() { 390 | log.append('.'); 391 | },300); 392 | 393 | var startTime = new Date().getTime(); 394 | var invocationParams = { 395 | triggerName: triggerToFire, 396 | blocking:true, 397 | namespace: namespace 398 | } 399 | 400 | if (pString.length>0) { 401 | invocationParams.params = util.parseParametersString(pString); 402 | } 403 | ow.triggers.invoke(invocationParams) 404 | .then(function(result) { 405 | var totalTime = startTime - (new Date().getTime()); 406 | clearInterval(activityInterval); 407 | log.appendLine(`\nok: triggered ${trigger}`); 408 | log.appendLine(JSON.stringify(result, null, 4)); 409 | log.appendLine('>> completed in ' + (-totalTime) + 'ms'); 410 | }) 411 | .catch(function(error) { 412 | clearInterval(activityInterval); 413 | util.printOpenWhiskError(error); 414 | }); 415 | 416 | }); 417 | }); 418 | } 419 | 420 | 421 | module.exports = { 422 | register: register, 423 | list:list, 424 | getListAsStringArray:getListAsStringArray 425 | }; 426 | -------------------------------------------------------------------------------- /static-src/commands/wsk.util.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | 'use strict'; 19 | 20 | var vscode = require('vscode'); 21 | let util = require('./util.js'); 22 | let open = require('open'); 23 | 24 | var log; 25 | var ow; 26 | var props; 27 | 28 | function register(_ow, context, _log, _props) { 29 | ow = _ow; 30 | log = _log; 31 | props = _props; 32 | 33 | var bluemixDisposable = vscode.commands.registerCommand('extension.wsk.util.bluemix', bluemixAction); 34 | var docsDisposable = vscode.commands.registerCommand('extension.wsk.util.docs', docsAction); 35 | context.subscriptions.push(bluemixDisposable, docsDisposable); 36 | } 37 | 38 | 39 | function bluemixAction(params) { 40 | 41 | log.show(true); 42 | log.appendLine('\n$ opening OpenWhisk console on Bluemix'); 43 | open('https://new-console.ng.bluemix.net/openwhisk'); 44 | } 45 | 46 | function docsAction(params) { 47 | log.show(true); 48 | log.appendLine('\n$ opening OpenWhisk console on Bluemix'); 49 | open('https://new-console.ng.bluemix.net/docs/openwhisk/index.html'); 50 | } 51 | 52 | module.exports = { 53 | register: register 54 | }; 55 | -------------------------------------------------------------------------------- /static-src/extension.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | "use strict"; 19 | 20 | // The module 'vscode' contains the VS Code extensibility API 21 | // Import the module and reference it with the alias vscode in your code below 22 | var vscode = require('vscode'); 23 | 24 | let controller = require("./commands/controller.js"); 25 | 26 | // this method is called when your extension is activated 27 | // your extension is activated the very first time the command is executed 28 | function activate(context) { 29 | 30 | // Use the console to output diagnostic information (console.log) and errors (console.error) 31 | // This line of code will only be executed once when your extension is activated 32 | console.log('Congratulations, your extension "vscode-openwhisk" is now active!'); 33 | 34 | // The command has been defined in the package.json file 35 | // Now provide the implementation of the command with registerCommand 36 | // The commandId parameter must match the command field in package.json 37 | 38 | controller.init(context); 39 | } 40 | exports.activate = activate; 41 | 42 | // this method is called when your extension is deactivated 43 | function deactivate() { 44 | } 45 | exports.deactivate = deactivate; 46 | -------------------------------------------------------------------------------- /static-src/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "ES5", 5 | "noLib": true 6 | }, 7 | "exclude": [ 8 | "node_modules" 9 | ] 10 | } -------------------------------------------------------------------------------- /static-src/templates/javascript.template: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * main() will be invoked when you Run This Action 4 | * 5 | * @param Cloud Functions actions accept a single parameter, which must be a JSON object. 6 | * 7 | * @return The output of this action, which must be a JSON object. 8 | * 9 | */ 10 | function main(params) { 11 | return { message: 'Hello World' }; 12 | } 13 | -------------------------------------------------------------------------------- /static-src/templates/javascript6.template: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * main() will be invoked when you Run This Action 4 | * 5 | * @param Cloud Functions actions accept a single parameter, which must be a JSON object. 6 | * 7 | * @return The output of this action, which must be a JSON object. 8 | * 9 | */ 10 | function main(params) { 11 | return { message: 'Hello World' }; 12 | } 13 | -------------------------------------------------------------------------------- /static-src/templates/php.template: -------------------------------------------------------------------------------- 1 | $greeting]; 17 | } 18 | -------------------------------------------------------------------------------- /static-src/templates/python.template: -------------------------------------------------------------------------------- 1 | # 2 | # 3 | # main() will be invoked when you Run This Action. 4 | # 5 | # @param Whisk actions accept a single parameter, 6 | # which must be a JSON object. 7 | # 8 | # @return The return value must also be JSON. 9 | # It will be the output of this action. 10 | # 11 | # 12 | import sys 13 | 14 | def main(dict): 15 | if 'message' in dict: 16 | name = dict['message'] 17 | else: 18 | name = 'stranger' 19 | greeting = 'Hello ' + name + '!' 20 | print(greeting) 21 | return {'greeting':greeting} -------------------------------------------------------------------------------- /static-src/templates/swift.template: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * main() will be invoked when you Run This Action. 4 | * 5 | * @param Whisk actions accept a single parameter, 6 | * which must be a JSON object. 7 | * 8 | * In this case, the params variable will look like: 9 | * { "message": "xxxx" } 10 | * 11 | * @return The return value must also be JSON. 12 | * It will be the output of this action. 13 | * 14 | * This uses the experimental KituraNet networking libraries for Swift on Linux 15 | */ 16 | 17 | import KituraNet 18 | import Dispatch 19 | import Foundation 20 | 21 | func main(args:[String:Any]) -> [String:Any] { 22 | 23 | var str = "No response" 24 | 25 | HTTP.get("https://httpbin.org/get") { response in 26 | do { 27 | str = try response!.readString()! 28 | } catch { 29 | print("Error \(error)") 30 | } 31 | } 32 | 33 | let result:[String:Any] = [ 34 | "response": str 35 | ] 36 | return result 37 | } -------------------------------------------------------------------------------- /static-src/typings/node.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /static-src/typings/vscode-typings.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /static-src/vsc-extension-quickstart.md: -------------------------------------------------------------------------------- 1 | # Welcome to your first VS Code Extension 2 | 3 | ## What's in the folder 4 | * This folder contains all of the files necessary for your extension 5 | * `package.json` - this is the manifest file in which you declare your extension and command. 6 | The sample plugin registers a command and defines its title and command name. With this information 7 | VS Code can show the command in the command palette. It doesn’t yet need to load the plugin. 8 | * `extension.js` - this is the main file where you will provide the implementation of your command. 9 | The file exports one function, `activate`, which is called the very first time your extension is 10 | activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`. 11 | We pass the function containing the implementation of the command as the second parameter to 12 | `registerCommand`. 13 | 14 | ## Get up and running straight away 15 | * press `F5` to open a new window with your extension loaded 16 | * run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World` 17 | * set breakpoints in your code inside extension.ts to debug your extension 18 | * find output from your extension in the debug console 19 | 20 | ## Make changes 21 | * you can relaunch the extension from the debug toolbar after changing code in `extension.js` 22 | * you can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes 23 | 24 | ## Explore the API 25 | * you can open the full set of our API when you open the file `node_modules/vscode/vscode.d.ts` 26 | 27 | ## Run tests 28 | * open the debug viewlet (`Ctrl+Shift+D` or `Cmd+Shift+D` on Mac) and from the launch configuration dropdown pick `Launch Tests` 29 | * press `F5` to run the tests in a new window with your extension loaded 30 | * see the output of the test result in the debug console 31 | * make changes to `test/extension.test.js` or create new test files inside the `test` folder 32 | * by convention, the test runner will only consider files matching the name pattern `**.test.js` 33 | * you can create folders inside the `test` folder to structure your tests any way you want 34 | --------------------------------------------------------------------------------