@atlaspack/reporter-dev-server 2.14.18-unified-f92fba5b6.0 → 2.14.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/lib/HMRServer.js +263 -0
- package/lib/Server.js +459 -0
- package/lib/ServerReporter.js +137 -17456
- package/lib/serverErrors.js +17 -0
- package/package.json +7 -8
- package/LICENSE +0 -201
- package/lib/ServerReporter.js.map +0 -1
package/lib/Server.js
ADDED
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = exports.SOURCES_ENDPOINT = void 0;
|
|
7
|
+
exports.setHeaders = setHeaders;
|
|
8
|
+
function _assert() {
|
|
9
|
+
const data = _interopRequireDefault(require("assert"));
|
|
10
|
+
_assert = function () {
|
|
11
|
+
return data;
|
|
12
|
+
};
|
|
13
|
+
return data;
|
|
14
|
+
}
|
|
15
|
+
function _path() {
|
|
16
|
+
const data = _interopRequireDefault(require("path"));
|
|
17
|
+
_path = function () {
|
|
18
|
+
return data;
|
|
19
|
+
};
|
|
20
|
+
return data;
|
|
21
|
+
}
|
|
22
|
+
function _url() {
|
|
23
|
+
const data = _interopRequireWildcard(require("url"));
|
|
24
|
+
_url = function () {
|
|
25
|
+
return data;
|
|
26
|
+
};
|
|
27
|
+
return data;
|
|
28
|
+
}
|
|
29
|
+
function _utils() {
|
|
30
|
+
const data = require("@atlaspack/utils");
|
|
31
|
+
_utils = function () {
|
|
32
|
+
return data;
|
|
33
|
+
};
|
|
34
|
+
return data;
|
|
35
|
+
}
|
|
36
|
+
var _serverErrors = _interopRequireDefault(require("./serverErrors"));
|
|
37
|
+
function _fs() {
|
|
38
|
+
const data = _interopRequireDefault(require("fs"));
|
|
39
|
+
_fs = function () {
|
|
40
|
+
return data;
|
|
41
|
+
};
|
|
42
|
+
return data;
|
|
43
|
+
}
|
|
44
|
+
function _ejs() {
|
|
45
|
+
const data = _interopRequireDefault(require("ejs"));
|
|
46
|
+
_ejs = function () {
|
|
47
|
+
return data;
|
|
48
|
+
};
|
|
49
|
+
return data;
|
|
50
|
+
}
|
|
51
|
+
function _connect() {
|
|
52
|
+
const data = _interopRequireDefault(require("connect"));
|
|
53
|
+
_connect = function () {
|
|
54
|
+
return data;
|
|
55
|
+
};
|
|
56
|
+
return data;
|
|
57
|
+
}
|
|
58
|
+
function _serveHandler() {
|
|
59
|
+
const data = _interopRequireDefault(require("serve-handler"));
|
|
60
|
+
_serveHandler = function () {
|
|
61
|
+
return data;
|
|
62
|
+
};
|
|
63
|
+
return data;
|
|
64
|
+
}
|
|
65
|
+
function _httpProxyMiddleware() {
|
|
66
|
+
const data = require("http-proxy-middleware");
|
|
67
|
+
_httpProxyMiddleware = function () {
|
|
68
|
+
return data;
|
|
69
|
+
};
|
|
70
|
+
return data;
|
|
71
|
+
}
|
|
72
|
+
function _launchEditor() {
|
|
73
|
+
const data = _interopRequireDefault(require("launch-editor"));
|
|
74
|
+
_launchEditor = function () {
|
|
75
|
+
return data;
|
|
76
|
+
};
|
|
77
|
+
return data;
|
|
78
|
+
}
|
|
79
|
+
function _fresh() {
|
|
80
|
+
const data = _interopRequireDefault(require("fresh"));
|
|
81
|
+
_fresh = function () {
|
|
82
|
+
return data;
|
|
83
|
+
};
|
|
84
|
+
return data;
|
|
85
|
+
}
|
|
86
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
87
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
88
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
89
|
+
function setHeaders(res) {
|
|
90
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
91
|
+
res.setHeader('Access-Control-Allow-Methods', 'GET, HEAD, PUT, PATCH, POST, DELETE');
|
|
92
|
+
res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Content-Type');
|
|
93
|
+
res.setHeader('Cache-Control', 'max-age=0, must-revalidate');
|
|
94
|
+
}
|
|
95
|
+
const SLASH_REGEX = /\//g;
|
|
96
|
+
const SOURCES_ENDPOINT = exports.SOURCES_ENDPOINT = '/__parcel_source_root';
|
|
97
|
+
const EDITOR_ENDPOINT = '/__parcel_launch_editor';
|
|
98
|
+
const TEMPLATE_404 = _fs().default.readFileSync(_path().default.join(__dirname, '..', 'templates/404.html'), 'utf8');
|
|
99
|
+
const TEMPLATE_500 = _fs().default.readFileSync(_path().default.join(__dirname, '..', 'templates/500.html'), 'utf8');
|
|
100
|
+
class Server {
|
|
101
|
+
constructor(options) {
|
|
102
|
+
this.options = options;
|
|
103
|
+
try {
|
|
104
|
+
this.rootPath = new (_url().URL)(options.publicUrl).pathname;
|
|
105
|
+
} catch (e) {
|
|
106
|
+
this.rootPath = options.publicUrl;
|
|
107
|
+
}
|
|
108
|
+
this.pending = true;
|
|
109
|
+
this.pendingRequests = [];
|
|
110
|
+
this.middleware = [];
|
|
111
|
+
this.bundleGraph = null;
|
|
112
|
+
this.requestBundle = null;
|
|
113
|
+
this.errors = null;
|
|
114
|
+
}
|
|
115
|
+
buildStart() {
|
|
116
|
+
this.pending = true;
|
|
117
|
+
}
|
|
118
|
+
buildSuccess(bundleGraph, requestBundle) {
|
|
119
|
+
this.bundleGraph = bundleGraph;
|
|
120
|
+
this.requestBundle = requestBundle;
|
|
121
|
+
this.errors = null;
|
|
122
|
+
this.pending = false;
|
|
123
|
+
if (this.pendingRequests.length > 0) {
|
|
124
|
+
let pendingRequests = this.pendingRequests;
|
|
125
|
+
this.pendingRequests = [];
|
|
126
|
+
for (let [req, res] of pendingRequests) {
|
|
127
|
+
this.respond(req, res);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
async buildError(options, diagnostics) {
|
|
132
|
+
this.pending = false;
|
|
133
|
+
this.errors = await Promise.all(diagnostics.map(async d => {
|
|
134
|
+
let ansiDiagnostic = await (0, _utils().prettyDiagnostic)(d, options);
|
|
135
|
+
return {
|
|
136
|
+
message: (0, _utils().ansiHtml)(ansiDiagnostic.message),
|
|
137
|
+
stack: ansiDiagnostic.stack ? (0, _utils().ansiHtml)(ansiDiagnostic.stack) : null,
|
|
138
|
+
frames: ansiDiagnostic.frames.map(f => ({
|
|
139
|
+
location: f.location,
|
|
140
|
+
code: (0, _utils().ansiHtml)(f.code)
|
|
141
|
+
})),
|
|
142
|
+
hints: ansiDiagnostic.hints.map(hint => (0, _utils().ansiHtml)(hint)),
|
|
143
|
+
documentation: d.documentationURL ?? ''
|
|
144
|
+
};
|
|
145
|
+
}));
|
|
146
|
+
}
|
|
147
|
+
respond(req, res) {
|
|
148
|
+
if (this.middleware.some(handler => handler(req, res))) return;
|
|
149
|
+
let {
|
|
150
|
+
pathname,
|
|
151
|
+
search
|
|
152
|
+
} = _url().default.parse(req.originalUrl || req.url);
|
|
153
|
+
if (pathname == null) {
|
|
154
|
+
pathname = '/';
|
|
155
|
+
}
|
|
156
|
+
if (pathname.startsWith(EDITOR_ENDPOINT) && search) {
|
|
157
|
+
let query = new (_url().URLSearchParams)(search);
|
|
158
|
+
let file = query.get('file');
|
|
159
|
+
if (file) {
|
|
160
|
+
// File location might start with /__parcel_source_root if it came from a source map.
|
|
161
|
+
if (file.startsWith(SOURCES_ENDPOINT)) {
|
|
162
|
+
file = file.slice(SOURCES_ENDPOINT.length + 1);
|
|
163
|
+
}
|
|
164
|
+
(0, _launchEditor().default)(file);
|
|
165
|
+
}
|
|
166
|
+
res.end();
|
|
167
|
+
} else if (this.errors) {
|
|
168
|
+
return this.send500(req, res);
|
|
169
|
+
} else if (_path().default.extname(pathname) === '') {
|
|
170
|
+
// If the URL doesn't start with the public path, or the URL doesn't
|
|
171
|
+
// have a file extension, send the main HTML bundle.
|
|
172
|
+
return this.sendIndex(req, res);
|
|
173
|
+
} else if (pathname.startsWith(SOURCES_ENDPOINT)) {
|
|
174
|
+
req.url = pathname.slice(SOURCES_ENDPOINT.length);
|
|
175
|
+
return this.serve(this.options.inputFS, this.options.projectRoot, req, res, () => this.send404(req, res));
|
|
176
|
+
} else if (pathname.startsWith(this.rootPath)) {
|
|
177
|
+
// Otherwise, serve the file from the dist folder
|
|
178
|
+
req.url = this.rootPath === '/' ? pathname : pathname.slice(this.rootPath.length);
|
|
179
|
+
if (req.url[0] !== '/') {
|
|
180
|
+
req.url = '/' + req.url;
|
|
181
|
+
}
|
|
182
|
+
return this.serveBundle(req, res, () => this.sendIndex(req, res));
|
|
183
|
+
} else {
|
|
184
|
+
return this.send404(req, res);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
sendIndex(req, res) {
|
|
188
|
+
if (this.bundleGraph) {
|
|
189
|
+
// If the main asset is an HTML file, serve it
|
|
190
|
+
let htmlBundleFilePaths = this.bundleGraph.getBundles().filter(bundle => _path().default.posix.extname(bundle.name) === '.html').map(bundle => {
|
|
191
|
+
return `/${(0, _utils().relativePath)(this.options.distDir, bundle.filePath, false)}`;
|
|
192
|
+
});
|
|
193
|
+
let indexFilePath = null;
|
|
194
|
+
let {
|
|
195
|
+
pathname: reqURL
|
|
196
|
+
} = _url().default.parse(req.originalUrl || req.url);
|
|
197
|
+
if (!reqURL) {
|
|
198
|
+
reqURL = '/';
|
|
199
|
+
}
|
|
200
|
+
if (htmlBundleFilePaths.length === 1) {
|
|
201
|
+
indexFilePath = htmlBundleFilePaths[0];
|
|
202
|
+
} else {
|
|
203
|
+
var _bestMatch;
|
|
204
|
+
let bestMatch = null;
|
|
205
|
+
for (let bundle of htmlBundleFilePaths) {
|
|
206
|
+
let bundleDir = _path().default.posix.dirname(bundle);
|
|
207
|
+
let bundleDirSubdir = bundleDir === '/' ? bundleDir : bundleDir + '/';
|
|
208
|
+
let withoutExtension = _path().default.posix.basename(bundle, _path().default.posix.extname(bundle));
|
|
209
|
+
let isIndex = withoutExtension === 'index';
|
|
210
|
+
let matchesIsIndex = null;
|
|
211
|
+
if (isIndex && (reqURL.startsWith(bundleDirSubdir) || reqURL === bundleDir)) {
|
|
212
|
+
// bundle is /bar/index.html and (/bar or something inside of /bar/** was requested was requested)
|
|
213
|
+
matchesIsIndex = true;
|
|
214
|
+
} else if (reqURL == _path().default.posix.join(bundleDir, withoutExtension)) {
|
|
215
|
+
// bundle is /bar/foo.html and /bar/foo was requested
|
|
216
|
+
matchesIsIndex = false;
|
|
217
|
+
}
|
|
218
|
+
if (matchesIsIndex != null) {
|
|
219
|
+
var _bundle$match;
|
|
220
|
+
let depth = ((_bundle$match = bundle.match(SLASH_REGEX)) === null || _bundle$match === void 0 ? void 0 : _bundle$match.length) ?? 0;
|
|
221
|
+
if (bestMatch == null ||
|
|
222
|
+
// This one is more specific (deeper)
|
|
223
|
+
bestMatch.depth < depth ||
|
|
224
|
+
// This one is just as deep, but the bundle name matches and not just index.html
|
|
225
|
+
bestMatch.depth === depth && bestMatch.isIndex) {
|
|
226
|
+
bestMatch = {
|
|
227
|
+
bundle,
|
|
228
|
+
depth,
|
|
229
|
+
isIndex: matchesIsIndex
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
indexFilePath = ((_bestMatch = bestMatch) === null || _bestMatch === void 0 ? void 0 : _bestMatch['bundle']) ?? htmlBundleFilePaths[0];
|
|
235
|
+
}
|
|
236
|
+
if (indexFilePath) {
|
|
237
|
+
req.url = indexFilePath;
|
|
238
|
+
this.serveBundle(req, res, () => this.send404(req, res));
|
|
239
|
+
} else {
|
|
240
|
+
this.send404(req, res);
|
|
241
|
+
}
|
|
242
|
+
} else {
|
|
243
|
+
this.send404(req, res);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
async serveBundle(req, res, next) {
|
|
247
|
+
let bundleGraph = this.bundleGraph;
|
|
248
|
+
if (bundleGraph) {
|
|
249
|
+
let {
|
|
250
|
+
pathname
|
|
251
|
+
} = _url().default.parse(req.url);
|
|
252
|
+
if (!pathname) {
|
|
253
|
+
this.send500(req, res);
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
let requestedPath = _path().default.normalize(pathname.slice(1));
|
|
257
|
+
let bundle = bundleGraph.getBundles().find(b => _path().default.relative(this.options.distDir, b.filePath) === requestedPath);
|
|
258
|
+
if (!bundle) {
|
|
259
|
+
this.serveDist(req, res, next);
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
(0, _assert().default)(this.requestBundle != null);
|
|
263
|
+
try {
|
|
264
|
+
await this.requestBundle(bundle);
|
|
265
|
+
} catch (err) {
|
|
266
|
+
this.send500(req, res);
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
this.serveDist(req, res, next);
|
|
270
|
+
} else {
|
|
271
|
+
this.send404(req, res);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
serveDist(req, res, next) {
|
|
275
|
+
return this.serve(this.options.outputFS, this.options.distDir, req, res, next);
|
|
276
|
+
}
|
|
277
|
+
async serve(fs, root, req, res, next) {
|
|
278
|
+
if (req.method !== 'GET' && req.method !== 'HEAD') {
|
|
279
|
+
// method not allowed
|
|
280
|
+
res.statusCode = 405;
|
|
281
|
+
res.setHeader('Allow', 'GET, HEAD');
|
|
282
|
+
res.setHeader('Content-Length', '0');
|
|
283
|
+
res.end();
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
try {
|
|
287
|
+
var filePath = _url().default.parse(req.url).pathname || '';
|
|
288
|
+
filePath = decodeURIComponent(filePath);
|
|
289
|
+
} catch (err) {
|
|
290
|
+
return this.sendError(res, 400);
|
|
291
|
+
}
|
|
292
|
+
filePath = _path().default.normalize('.' + _path().default.sep + filePath);
|
|
293
|
+
|
|
294
|
+
// malicious path
|
|
295
|
+
if (filePath.includes(_path().default.sep + '..' + _path().default.sep)) {
|
|
296
|
+
return this.sendError(res, 403);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// join / normalize from the root dir
|
|
300
|
+
if (!_path().default.isAbsolute(filePath)) {
|
|
301
|
+
filePath = _path().default.normalize(_path().default.join(root, filePath));
|
|
302
|
+
}
|
|
303
|
+
try {
|
|
304
|
+
var stat = await fs.stat(filePath);
|
|
305
|
+
} catch (err) {
|
|
306
|
+
if (err.code === 'ENOENT') {
|
|
307
|
+
return next(req, res);
|
|
308
|
+
}
|
|
309
|
+
return this.sendError(res, 500);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Fall back to next handler if not a file
|
|
313
|
+
if (!stat || !stat.isFile()) {
|
|
314
|
+
return next(req, res);
|
|
315
|
+
}
|
|
316
|
+
if ((0, _fresh().default)(req.headers, {
|
|
317
|
+
'last-modified': stat.mtime.toUTCString()
|
|
318
|
+
})) {
|
|
319
|
+
res.statusCode = 304;
|
|
320
|
+
res.end();
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
return (0, _serveHandler().default)(req, res, {
|
|
324
|
+
public: root,
|
|
325
|
+
cleanUrls: false
|
|
326
|
+
}, {
|
|
327
|
+
lstat: path => fs.stat(path),
|
|
328
|
+
realpath: path => fs.realpath(path),
|
|
329
|
+
createReadStream: (path, options) => fs.createReadStream(path, options),
|
|
330
|
+
readdir: path => fs.readdir(path)
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
sendError(res, statusCode) {
|
|
334
|
+
res.statusCode = statusCode;
|
|
335
|
+
res.end();
|
|
336
|
+
}
|
|
337
|
+
send404(req, res) {
|
|
338
|
+
res.statusCode = 404;
|
|
339
|
+
res.end(TEMPLATE_404);
|
|
340
|
+
}
|
|
341
|
+
send500(req, res) {
|
|
342
|
+
res.setHeader('Content-Type', 'text/html; charset=utf-8');
|
|
343
|
+
res.writeHead(500);
|
|
344
|
+
if (this.errors) {
|
|
345
|
+
return res.end(_ejs().default.render(TEMPLATE_500, {
|
|
346
|
+
errors: this.errors,
|
|
347
|
+
hmrOptions: this.options.hmrOptions
|
|
348
|
+
}));
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
logAccessIfVerbose(req) {
|
|
352
|
+
this.options.logger.verbose({
|
|
353
|
+
message: `Request: ${req.headers.host}${req.originalUrl || req.url}`
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Load proxy table from package.json and apply them.
|
|
359
|
+
*/
|
|
360
|
+
async applyProxyTable(app) {
|
|
361
|
+
// avoid skipping project root
|
|
362
|
+
const fileInRoot = _path().default.join(this.options.projectRoot, 'index');
|
|
363
|
+
const configFilePath = await (0, _utils().resolveConfig)(this.options.inputFS, fileInRoot, ['.proxyrc.cts', '.proxyrc.mts', '.proxyrc.ts', '.proxyrc.cjs', '.proxyrc.mjs', '.proxyrc.js', '.proxyrc', '.proxyrc.json'], this.options.projectRoot);
|
|
364
|
+
if (!configFilePath) {
|
|
365
|
+
return this;
|
|
366
|
+
}
|
|
367
|
+
const filename = _path().default.basename(configFilePath);
|
|
368
|
+
if (filename === '.proxyrc' || filename === '.proxyrc.json') {
|
|
369
|
+
let conf = await (0, _utils().readConfig)(this.options.inputFS, configFilePath);
|
|
370
|
+
if (!conf) {
|
|
371
|
+
return this;
|
|
372
|
+
}
|
|
373
|
+
let cfg = conf.config;
|
|
374
|
+
if (typeof cfg !== 'object') {
|
|
375
|
+
this.options.logger.warn({
|
|
376
|
+
message: "Proxy table in '.proxyrc' should be of object type. Skipping..."
|
|
377
|
+
});
|
|
378
|
+
return this;
|
|
379
|
+
}
|
|
380
|
+
for (const [context, options] of Object.entries(cfg)) {
|
|
381
|
+
// each key is interpreted as context, and value as middleware options
|
|
382
|
+
app.use((0, _httpProxyMiddleware().createProxyMiddleware)(context, options));
|
|
383
|
+
}
|
|
384
|
+
} else {
|
|
385
|
+
let cfg = await this.options.packageManager.require(configFilePath, fileInRoot);
|
|
386
|
+
if (
|
|
387
|
+
// $FlowFixMe
|
|
388
|
+
Object.prototype.toString.call(cfg) === '[object Module]') {
|
|
389
|
+
cfg = cfg.default;
|
|
390
|
+
}
|
|
391
|
+
if (typeof cfg !== 'function') {
|
|
392
|
+
this.options.logger.warn({
|
|
393
|
+
message: `Proxy configuration file '${filename}' should export a function. Skipping...`
|
|
394
|
+
});
|
|
395
|
+
return this;
|
|
396
|
+
}
|
|
397
|
+
cfg(app);
|
|
398
|
+
}
|
|
399
|
+
return this;
|
|
400
|
+
}
|
|
401
|
+
async start() {
|
|
402
|
+
const finalHandler = (req, res) => {
|
|
403
|
+
this.logAccessIfVerbose(req);
|
|
404
|
+
|
|
405
|
+
// Wait for the parcelInstance to finish bundling if needed
|
|
406
|
+
if (this.pending) {
|
|
407
|
+
this.pendingRequests.push([req, res]);
|
|
408
|
+
} else {
|
|
409
|
+
this.respond(req, res);
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
const app = (0, _connect().default)();
|
|
413
|
+
app.use((req, res, next) => {
|
|
414
|
+
setHeaders(res);
|
|
415
|
+
next();
|
|
416
|
+
});
|
|
417
|
+
app.use((req, res, next) => {
|
|
418
|
+
if (req.url === '/__parcel_healthcheck') {
|
|
419
|
+
res.statusCode = 200;
|
|
420
|
+
res.write(`${Date.now()}`);
|
|
421
|
+
res.end();
|
|
422
|
+
} else {
|
|
423
|
+
next();
|
|
424
|
+
}
|
|
425
|
+
});
|
|
426
|
+
await this.applyProxyTable(app);
|
|
427
|
+
app.use(finalHandler);
|
|
428
|
+
let {
|
|
429
|
+
server,
|
|
430
|
+
stop
|
|
431
|
+
} = await (0, _utils().createHTTPServer)({
|
|
432
|
+
cacheDir: this.options.cacheDir,
|
|
433
|
+
https: this.options.https,
|
|
434
|
+
inputFS: this.options.inputFS,
|
|
435
|
+
listener: app,
|
|
436
|
+
outputFS: this.options.outputFS,
|
|
437
|
+
host: this.options.host
|
|
438
|
+
});
|
|
439
|
+
this.stopServer = stop;
|
|
440
|
+
server.listen(this.options.port, this.options.host);
|
|
441
|
+
return new Promise((resolve, reject) => {
|
|
442
|
+
server.once('error', err => {
|
|
443
|
+
this.options.logger.error({
|
|
444
|
+
message: (0, _serverErrors.default)(err, this.options.port)
|
|
445
|
+
});
|
|
446
|
+
reject(err);
|
|
447
|
+
});
|
|
448
|
+
server.once('listening', () => {
|
|
449
|
+
resolve(server);
|
|
450
|
+
});
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
async stop() {
|
|
454
|
+
(0, _assert().default)(this.stopServer != null);
|
|
455
|
+
await this.stopServer();
|
|
456
|
+
this.stopServer = null;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
exports.default = Server;
|