UNPKG

3.44 kBJavaScriptView Raw
1/**
2 * Standalone server script which creates an Express server, configures and
3 * binds it according to configuration, and applies the upward-js middleware.
4 */
5
6const { resolve } = require('path');
7const express = require('express');
8const middleware = require('./middleware');
9const errorhandler = require('errorhandler');
10const { version } = require('../package.json');
11const morgan = require('morgan');
12
13/**
14 * Create an upward-js standalone server and optionally bind it to a local
15 * address. Configure logging and debugging middleware depending on standard
16 * detection of environment: `process.env.NODE_ENV` === 'production'.
17 *
18 * ### `createUpwardServer` Configuration Options
19 *
20 * | Property | Type | Default | Description
21 * | -------- | ---- | ------- | -----------
22 * |`upwardPath` | `string` | | Path, relative to the current directory, of a YML file with an UPWARD configuration. **Required**.
23 * |`bindLocal` | `boolean` | `false` | Create and bind an HTTP server before returning.
24 * |`port` | `number` | `0` | Specify the port to be bound. `0` means the first open port.
25 * |`host` | `string` | `0.0.0.0` | Specify the host on which to listen. `0.0.0.0` means all local IPv4 requests.
26 * |`https` | `object` | | To bind an HTTPS server instead of HTTP, pass a valid `{ key, cert }` object here.
27 * |`logUrl` | `boolean` | `false` | Log the bound URL to stdout (mostly used for testing against upward-spec)
28 *
29 * Returns a plain object with the following properties:
30 * an `app` property. This is an Express
31 *
32 *
33 * @param {object} config Configuration object.
34 * @return Promise `{ app, server?, close? }`
35 */
36async function createUpwardServer({
37 bindLocal = false,
38 port = 0,
39 host = '0.0.0.0',
40 https,
41 logUrl = false,
42 upwardPath,
43 env = process.env,
44 before = () => {}
45}) {
46 if (!upwardPath) {
47 throw new Error(`upwardPath is required`);
48 }
49 const app = express();
50 before(app);
51 const upward = await middleware(resolve(upwardPath), env);
52
53 if (env.NODE_ENV === 'production') {
54 app.use(morgan('combined'));
55 app.use(upward);
56 } else {
57 app.use(morgan('dev'));
58 app.use(upward);
59 errorhandler.title = `⚠️ Error in upward-js v${version}`;
60 app.use(errorhandler());
61 }
62
63 if (bindLocal) {
64 return new Promise((resolve, reject) => {
65 try {
66 const protocol = https ? 'https' : 'http';
67 const server = https
68 ? require('https').createServer(https, app)
69 : require('http').createServer(app);
70
71 server.listen(port, host);
72
73 server.on('listening', () => {
74 if (logUrl) {
75 console.log(
76 `${protocol}://${host}:${server.address().port}/`
77 );
78 }
79 resolve({
80 app,
81 server,
82 close() {
83 return new Promise(resolve => {
84 server.on('close', resolve);
85 server.close();
86 });
87 }
88 });
89 });
90 } catch (e) {
91 reject(e);
92 }
93 });
94 }
95 return { app };
96}
97
98module.exports = createUpwardServer;