UNPKG

4.77 kBJavaScriptView Raw
1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3 return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5const http_1 = __importDefault(require("http"));
6const https_1 = __importDefault(require("https"));
7const fs_1 = __importDefault(require("fs"));
8const path_1 = __importDefault(require("path"));
9const messages_1 = __importDefault(require("./messages"));
10const middleware_1 = __importDefault(require("./middleware"));
11const events_1 = __importDefault(require("events"));
12class Server extends events_1.default {
13 constructor(watcher, host, port, connect = require('connect'), ui, ssl, sslKey, sslCert) {
14 super();
15 this._watcher = watcher;
16 this._builder = watcher.builder;
17 this._host = host;
18 this._port = parseInt(port, 10);
19 this._ssl = ssl;
20 this._sslKey = sslKey;
21 this._sslCert = sslCert;
22 this._connect = connect;
23 this._url = `http${this._ssl ? 's' : ''}://${this._host}:${this._port}`;
24 this.app = this.instance = null;
25 this._boundStop = this.stop.bind(this);
26 this._started = false;
27 this.ui = ui;
28 if (watcher.constructor.name !== 'Watcher') {
29 throw new Error('Expected Watcher instance');
30 }
31 if (typeof host !== 'string') {
32 throw new Error('Expected host to bind to (e.g. "localhost")');
33 }
34 if (typeof port !== 'number' || port !== port) {
35 throw new Error('Expected port to bind to (e.g. 4200)');
36 }
37 }
38 async start() {
39 if (this._started) {
40 throw new Error('Watcher.prototype.start() must not be called more than once');
41 }
42 const promise = new Promise((resolve, reject) => {
43 this.app = this._connect().use(middleware_1.default(this._watcher));
44 if (this._ssl) {
45 let sslOptions;
46 try {
47 sslOptions = {
48 key: fs_1.default.readFileSync(this._sslKey),
49 cert: fs_1.default.readFileSync(this._sslCert),
50 };
51 }
52 catch (err) {
53 throw new Error(`SSL key and certificate files should be present at ${path_1.default.join(process.cwd(), this._sslKey)} and ${path_1.default.join(process.cwd(), this._sslCert)} respectively.`);
54 }
55 this.instance = https_1.default.createServer(sslOptions, this.app);
56 }
57 else {
58 this.instance = http_1.default.createServer(this.app);
59 }
60 this.instance.listen(this._port, this._host);
61 this.instance.on('listening', () => {
62 this.ui.writeLine(`Serving on ${this._url}\n`);
63 resolve(this._watcher.start());
64 });
65 this.instance.on('error', (error) => {
66 if (error.code !== 'EADDRINUSE') {
67 throw error;
68 }
69 let message = `Oh snap 😫. It appears a server is already running on ${this._url}\n`;
70 message += `Are you perhaps already running serve in another terminal window?\n`;
71 reject(new Error(message));
72 });
73 process.addListener('SIGINT', this._boundStop);
74 process.addListener('SIGTERM', this._boundStop);
75 this._watcher.on('buildSuccess', () => {
76 this.emit('buildSuccess');
77 messages_1.default.onBuildSuccess(this._builder, this.ui);
78 });
79 this._watcher.on('buildFailure', (err) => {
80 this.emit('buildFailure');
81 this.ui.writeLine('build failure', 'ERROR');
82 this.ui.writeError(err);
83 });
84 });
85 try {
86 await promise;
87 }
88 finally {
89 await this.stop();
90 }
91 }
92 _detachListeners() {
93 process.removeListener('SIGINT', this._boundStop);
94 process.removeListener('SIGTERM', this._boundStop);
95 }
96 async stop() {
97 this._detachListeners();
98 if (this.instance) {
99 this.instance.close();
100 }
101 await this._watcher.quit();
102 await this._builder.cleanup();
103 }
104}
105function serve(watcher, host, port, _connect = require('connect'), _process = process, ui, ssl, sslKey, sslCert) {
106 const server = new Server(watcher, host, port, _connect, ui, ssl, sslKey, sslCert);
107 return server
108 .start()
109 .then(() => _process.exit(0))
110 .catch(err => {
111 ui.writeLine('Broccoli Cleanup error:', 'ERROR');
112 ui.writeError(err);
113 _process.exit(1);
114 });
115}
116;
117module.exports = {
118 Server,
119 serve
120};
121//# sourceMappingURL=server.js.map
\No newline at end of file