UNPKG

8.96 kBJavaScriptView Raw
1/*
2 * Copyright 2019 Adobe. All rights reserved.
3 * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License. You may obtain a copy
5 * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 *
7 * Unless required by applicable law or agreed to in writing, software distributed under
8 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 * OF ANY KIND, either express or implied. See the License for the specific language
10 * governing permissions and limitations under the License.
11 */
12
13/* eslint-disable no-console */
14const crypto = require('crypto');
15const yargs = require('yargs');
16const chalk = require('chalk');
17
18const defaultConfig10 = require('./config/adobeioruntime-node10.js');
19const defaultConfig12 = require('./config/adobeioruntime-node12.js');
20
21const defaultConfigs = {
22 'nodejs:10': defaultConfig10,
23 'nodejs:12': defaultConfig12,
24};
25
26class CLI {
27 constructor() {
28 this._yargs = yargs()
29 .pkgConf('wsk')
30 .option('verbose', {
31 alias: 'v',
32 type: 'boolean',
33 default: false,
34 })
35 .option('build', {
36 description: 'Build the deployment package',
37 type: 'boolean',
38 default: true,
39 })
40 .option('directory', {
41 description: 'Project directory',
42 type: 'string',
43 default: '.',
44 })
45 .option('deploy', {
46 description: 'Automatically deploy to OpenWhisk',
47 type: 'boolean',
48 default: false,
49 })
50 .option('test', {
51 description: 'Invoke action after deployment. Can be relative url.',
52 type: 'string',
53 })
54 .option('test-params', {
55 description: 'Invoke openwhisk action after deployment with the given params.',
56 type: 'array',
57 default: [],
58 })
59 .option('hints', {
60 alias: 'no-hints',
61 description: 'Show additional hints for deployment',
62 type: 'boolean',
63 default: true,
64 })
65 .option('version-link', {
66 alias: 'l',
67 description: 'Create symlinks (sequences) after deployment. "major" and "minor" will create respective version links',
68 type: 'string',
69 array: true,
70 })
71 .option('delete', {
72 description: 'Delete the action from OpenWhisk. Implies no-build',
73 type: 'boolean',
74 default: false,
75 })
76 .option('linkPackage', {
77 description: 'Package name for version links',
78 type: 'string',
79 })
80 .group(['build', 'deploy', 'test', 'test-params', 'hints', 'update-package', 'version-link', 'linkPackage', 'delete'], 'Operation Options')
81
82 .option('name', {
83 description: 'OpenWhisk action name. Can be prefixed with package.',
84 })
85 .option('namespace', {
86 description: 'OpenWhisk namespace. Needs to match the namespace provided with the openwhisk credentials.',
87 })
88 .option('pkgVersion', {
89 description: 'Version use in the embedded package.json.',
90 })
91 .option('kind', {
92 description: 'Specifies the action kind.',
93 default: 'nodejs:12',
94 })
95 .option('web-export', {
96 description: 'Annotates the action as web-action',
97 type: 'boolean',
98 default: true,
99 })
100 .option('raw-http', {
101 description: 'Annotates the action as raw web-action (enforces web-export=true)',
102 type: 'boolean',
103 default: false,
104 })
105 .option('web-secure', {
106 description: 'Annotates the action with require-whisk-auth. leave empty to generate random token.',
107 type: 'string',
108 coerce: (value) => {
109 if (typeof value === 'string') {
110 if (value === 'true') {
111 return true;
112 }
113 if (value === 'false') {
114 return false;
115 }
116 return (value.trim() ? value.trim() : crypto.randomBytes(32).toString('base64'));
117 }
118 return value;
119 },
120 })
121 .option('docker', {
122 description: 'Specifies a docker image.',
123 })
124 .option('params', {
125 alias: 'p',
126 description: 'Include the given action param. can be json or env.',
127 type: 'array',
128 default: [],
129 })
130 .option('modules', {
131 alias: 'm',
132 description: 'Include a node_module as is.',
133 type: 'array',
134 default: [],
135 })
136 .option('params-file', {
137 alias: 'f',
138 description: 'Include the given action param from a file; can be json or env.',
139 type: 'array',
140 default: [],
141 })
142 .option('timeout', {
143 alias: 't',
144 description: 'the timeout limit in milliseconds after which the action is terminated',
145 type: 'integer',
146 default: 60000,
147 })
148 .option('memory', {
149 description: 'the maximum memory LIMIT in MB for the action',
150 type: 'integer',
151 })
152 .option('concurrency', {
153 description: 'the maximum intra-container concurrent activation LIMIT for the action',
154 type: 'integer',
155 })
156 .option('updated-by', {
157 description: 'user that updated the action or sequence.',
158 type: 'string',
159 })
160 .option('updated-at', {
161 description: 'unix timestamp when the action or sequence was updated (defaults to the current time).',
162 type: 'number',
163 default: (new Date().getTime()),
164 })
165 .group([
166 'name', 'kind', 'docker', 'params', 'params-file', 'web-export', 'raw-http', 'web-secure',
167 'namespace', 'timeout', 'updated-by', 'updated-at'], 'OpenWhisk Action Options')
168
169 .option('update-package', {
170 description: 'Create or update wsk package.',
171 type: 'boolean',
172 default: false,
173 })
174 .option('package.name', {
175 description: 'OpenWhisk package name.',
176 type: 'string',
177 })
178 .option('package.shared', {
179 description: 'OpenWhisk package scope.',
180 type: 'boolean',
181 default: false,
182 })
183 .option('package.params', {
184 description: 'OpenWhisk package params.',
185 type: 'array',
186 default: [],
187 })
188 .option('package.params-file', {
189 description: 'OpenWhisk package params file.',
190 type: 'array',
191 default: [],
192 })
193 .group(['package.name', 'package.params', 'package.params-file', 'package.shared'], 'OpenWhisk Package Options')
194
195 .option('static', {
196 alias: 's',
197 description: 'Includes a static file into the archive',
198 type: 'array',
199 default: [],
200 })
201 .option('entryFile', {
202 description: 'Specifies the entry file.',
203 default: 'src/index.js',
204 })
205 .option('externals', {
206 description: 'Defines the externals for webpack.',
207 type: 'array',
208 default: [],
209 })
210 .group(['static', 'entryFile', 'externals', 'modules'], 'Bundling Options')
211 .help();
212 }
213
214 // eslint-disable-next-line class-methods-use-this
215 createBuilder() {
216 // eslint-disable-next-line global-require
217 const ActionBuilder = require('./action_builder.js');
218 return new ActionBuilder();
219 }
220
221 prepare(args) {
222 const argv = this._yargs.parse(args);
223
224 if (argv.externals.length === 0 && defaultConfigs[argv.kind]) {
225 argv.externals = defaultConfigs[argv.kind].externals;
226 }
227 return this.createBuilder()
228 .verbose(argv.verbose)
229 .withDirectory(argv.directory)
230 .withBuild(argv.build)
231 .withDelete(argv.delete)
232 .withDeploy(argv.deploy)
233 .withTest(argv.test)
234 .withTestParams(argv.testParams)
235 .withHints(argv.hints)
236 .withStatic(argv.static)
237 .withName(argv.name)
238 .withNamespace(argv.namespace)
239 .withUpdatedAt(argv.updatedAt)
240 .withUpdatedBy(argv.updatedBy)
241 .withParams(argv.params)
242 .withParamsFile(argv.paramsFile)
243 .withVersion(argv.pkgVersion)
244 .withKind(argv.kind)
245 .withEntryFile(argv.entryFile)
246 .withExternals(argv.externals)
247 .withDocker(argv.docker)
248 .withModules(argv.modules)
249 .withWebExport(argv.webExport)
250 .withWebSecure(argv.webSecure)
251 .withRawHttp(argv.rawHttp)
252 .withUpdatePackage(argv.updatePackage)
253 .withPackageName(argv.package.name)
254 .withPackageParams(argv.package.params)
255 .withPackageParamsFile(argv.package['params-file'])
256 .withTimeout(argv.timeout)
257 .withMemory(argv.memory)
258 .withConcurrency(argv.concurrency)
259 .withLinks(argv.versionLink)
260 .withLinksPackage(argv.linksPackage)
261 .withPackageShared(argv.package.shared);
262 }
263
264 async run(args) {
265 try {
266 const res = await this.prepare(args).run();
267 console.log(JSON.stringify(res, null, 2));
268 } catch (err) {
269 console.log(`${chalk.red('error:')} ${err.message}`);
270 process.exitCode = 1;
271 }
272 }
273}
274
275module.exports = CLI;