UNPKG

3.83 kBJavaScriptView Raw
1/*
2 * Copyright 2020 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/* eslint-disable no-underscore-dangle */
13const fse = require('fs-extra');
14const path = require('path');
15const ActionBuilder = require('./action_builder.js');
16
17/**
18 * Development server to use with a expressified openwhisk app.
19 *
20 * Example:
21 *
22 * ```
23 * // test/dev.js
24 *
25 * const { DevelopmentServer } = require('@adobe/openwhisk-action-builder');
26 * const App = require('../src/app.js');
27 *
28 * async function run() {
29 * const devServer = await new DevelopmentServer(App).init();
30 * return devServer.start();
31 * }
32 * run().catch(console.error);
33 * ```
34 *
35 * @type {DevelopmentServer}
36 */
37module.exports = class DevelopmentServer {
38 /**
39 * Creates a new development server using the given express app.
40 * @param {function} appFn - The function that creates an express app.
41 */
42 constructor(appFn) {
43 this._appFn = appFn;
44 this._cwd = process.cwd();
45 this._port = process.env.WEBSERVER_PORT || 3000;
46 }
47
48 withPort(value) {
49 this._port = value;
50 return this;
51 }
52
53 /**
54 * Initializes the development server.
55 * It uses the `wsk.package.params-file` and `wsk.params-file` to read the environment for
56 * the action params.
57 *
58 * @returns this
59 */
60 async init() {
61 // load the action params params
62 let pkgJson = {};
63 try {
64 pkgJson = await fse.readJson(path.resolve('package.json'));
65 } catch (e) {
66 // ignore
67 }
68 const builder = new ActionBuilder();
69 if (pkgJson.wsk && pkgJson.wsk['params-file']) {
70 builder.withParamsFile(pkgJson.wsk['params-file']);
71 }
72 if (pkgJson.wsk && pkgJson.wsk.package && pkgJson.wsk.package['params-file']) {
73 builder.withParamsFile(pkgJson.wsk.package['params-file']);
74 }
75 if (pkgJson.wsk && pkgJson.wsk['dev-params-file']) {
76 const file = pkgJson.wsk['dev-params-file'];
77 if (await fse.exists(file)) {
78 builder.withParamsFile(file);
79 }
80 }
81 await builder.initWskProps();
82
83 const params = await ActionBuilder.resolveParams(builder._params);
84
85 // set openwhisk coordinates for transparent ow client usage.
86 process.env.__OW_API_KEY = builder._wskAuth;
87 process.env.__OW_API_HOST = builder._wskApiHost;
88 process.env.__OW_NAMESPACE = builder._wskNamespace;
89
90 this.params = params;
91 return this;
92 }
93
94 /**
95 * Starts the development server
96 * @returns {Promise<void>}
97 */
98 async start() {
99 const app = await this._appFn(this.params);
100
101 // bind default params like expressify does
102 Object.defineProperty(app.request, 'owActionParams', {
103 value: this.params,
104 enumerable: false,
105 });
106
107 await new Promise((resolve, reject) => {
108 try {
109 this.server = app.listen(this._port, () => {
110 // eslint-disable-next-line no-console
111 console.log(`Started development server on port ${this.server.address().port}`);
112 resolve();
113 });
114 } catch (e) {
115 reject(e);
116 }
117 });
118 }
119
120 /**
121 * Stops the development server.
122 * @returns {Promise<void>}
123 */
124 async stop() {
125 return new Promise((resolve, reject) => {
126 this.server.close((err) => {
127 if (err) {
128 reject(err);
129 } else {
130 resolve();
131 }
132 });
133 });
134 }
135};