@jsenv/server 15.0.2 → 15.0.3

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.
Files changed (53) hide show
  1. package/README.md +23 -23
  2. package/package.json +3 -3
  3. package/src/content_negotiation/pick_accepted_content.js +13 -13
  4. package/src/content_negotiation/pick_content_encoding.js +25 -25
  5. package/src/content_negotiation/pick_content_language.js +35 -34
  6. package/src/content_negotiation/pick_content_type.js +29 -29
  7. package/src/fetch_filesystem.js +110 -107
  8. package/src/from_fetch_response.js +6 -6
  9. package/src/interfacing_with_node/body.js +22 -22
  10. package/src/interfacing_with_node/observable.js +80 -80
  11. package/src/interfacing_with_node/observable_from_node_stream.js +35 -35
  12. package/src/interfacing_with_node/request_factory.js +26 -26
  13. package/src/interfacing_with_node/write_node_response.js +82 -82
  14. package/src/internal/colorizeResponseStatus.js +26 -26
  15. package/src/internal/convertFileSystemErrorToResponseProperties.js +10 -10
  16. package/src/internal/dns_resolution.js +7 -7
  17. package/src/internal/etag.js +11 -11
  18. package/src/internal/filesystem.js +19 -19
  19. package/src/internal/headersFromObject.js +8 -8
  20. package/src/internal/headersFromString.js +11 -11
  21. package/src/internal/headersToObject.js +5 -5
  22. package/src/internal/headersToString.js +7 -7
  23. package/src/internal/headers_composition.js +9 -9
  24. package/src/internal/hostname_parser.js +9 -9
  25. package/src/internal/listen.js +47 -47
  26. package/src/internal/listenClientError.js +10 -10
  27. package/src/internal/listenEvent.js +5 -5
  28. package/src/internal/listenRequest.js +8 -8
  29. package/src/internal/listenServerConnectionError.js +19 -19
  30. package/src/internal/multiple-header.js +50 -50
  31. package/src/internal/normalizeHeaderName.js +4 -4
  32. package/src/internal/normalizeHeaderValue.js +2 -2
  33. package/src/internal/object_composition.js +41 -39
  34. package/src/internal/response_composition.js +6 -6
  35. package/src/internal/server-polyglot.js +42 -42
  36. package/src/internal/server_ips.js +20 -20
  37. package/src/internal/trackServerPendingConnections.js +23 -23
  38. package/src/internal/trackServerPendingRequests.js +28 -28
  39. package/src/main.js +18 -18
  40. package/src/readRequestBody.js +15 -15
  41. package/src/serve_directory.js +16 -16
  42. package/src/server_timing/timing_header.js +24 -24
  43. package/src/server_timing/timing_measure.js +14 -14
  44. package/src/service_composition/path_to_regexp.js +173 -168
  45. package/src/service_composition/routing.js +12 -12
  46. package/src/service_controller.js +77 -77
  47. package/src/services/cors/jsenv_service_cors.js +29 -29
  48. package/src/services/error_handler/jsenv_service_error_handler.js +18 -18
  49. package/src/services/request_aliases/jsenv_service_request_aliases.js +20 -20
  50. package/src/services/response_acceptance_check/jsenv_service_response_acceptance_check.js +16 -16
  51. package/src/sse/sse_room.js +117 -115
  52. package/src/start_server.js +328 -328
  53. package/src/stopReasons.js +9 -9
@@ -1,33 +1,33 @@
1
- import { isIP } from "node:net"
2
- import cluster from "node:cluster"
3
- import { createDetailedMessage, createLogger } from "@jsenv/log"
1
+ import { isIP } from "node:net";
2
+ import cluster from "node:cluster";
3
+ import { createDetailedMessage, createLogger } from "@jsenv/log";
4
4
  import {
5
5
  Abort,
6
6
  raceProcessTeardownEvents,
7
7
  createCallbackListNotifiedOnce,
8
- } from "@jsenv/abort"
9
- import { memoize } from "@jsenv/utils/src/memoize/memoize.js"
8
+ } from "@jsenv/abort";
9
+ import { memoize } from "@jsenv/utils/src/memoize/memoize.js";
10
10
 
11
- import { createServiceController } from "./service_controller.js"
12
- import { timingToServerTimingResponseHeaders } from "./server_timing/timing_header.js"
13
- import { createPolyglotServer } from "./internal/server-polyglot.js"
14
- import { trackServerPendingConnections } from "./internal/trackServerPendingConnections.js"
15
- import { trackServerPendingRequests } from "./internal/trackServerPendingRequests.js"
11
+ import { createServiceController } from "./service_controller.js";
12
+ import { timingToServerTimingResponseHeaders } from "./server_timing/timing_header.js";
13
+ import { createPolyglotServer } from "./internal/server-polyglot.js";
14
+ import { trackServerPendingConnections } from "./internal/trackServerPendingConnections.js";
15
+ import { trackServerPendingRequests } from "./internal/trackServerPendingRequests.js";
16
16
  import {
17
17
  fromNodeRequest,
18
18
  createPushRequest,
19
19
  applyRedirectionToRequest,
20
- } from "./interfacing_with_node/request_factory.js"
21
- import { writeNodeResponse } from "./interfacing_with_node/write_node_response.js"
20
+ } from "./interfacing_with_node/request_factory.js";
21
+ import { writeNodeResponse } from "./interfacing_with_node/write_node_response.js";
22
22
  import {
23
23
  statusToType,
24
24
  colorizeResponseStatus,
25
- } from "./internal/colorizeResponseStatus.js"
26
- import { listen, stopListening } from "./internal/listen.js"
27
- import { composeTwoResponses } from "./internal/response_composition.js"
28
- import { listenRequest } from "./internal/listenRequest.js"
29
- import { listenEvent } from "./internal/listenEvent.js"
30
- import { listenServerConnectionError } from "./internal/listenServerConnectionError.js"
25
+ } from "./internal/colorizeResponseStatus.js";
26
+ import { listen, stopListening } from "./internal/listen.js";
27
+ import { composeTwoResponses } from "./internal/response_composition.js";
28
+ import { listenRequest } from "./internal/listenRequest.js";
29
+ import { listenEvent } from "./internal/listenEvent.js";
30
+ import { listenServerConnectionError } from "./internal/listenServerConnectionError.js";
31
31
  import {
32
32
  STOP_REASON_INTERNAL_ERROR,
33
33
  STOP_REASON_PROCESS_SIGHUP,
@@ -36,12 +36,12 @@ import {
36
36
  STOP_REASON_PROCESS_BEFORE_EXIT,
37
37
  STOP_REASON_PROCESS_EXIT,
38
38
  STOP_REASON_NOT_SPECIFIED,
39
- } from "./stopReasons.js"
40
- import { composeTwoHeaders } from "./internal/headers_composition.js"
39
+ } from "./stopReasons.js";
40
+ import { composeTwoHeaders } from "./internal/headers_composition.js";
41
41
 
42
- import { createIpGetters } from "./internal/server_ips.js"
43
- import { parseHostname } from "./internal/hostname_parser.js"
44
- import { applyDnsResolution } from "./internal/dns_resolution.js"
42
+ import { createIpGetters } from "./internal/server_ips.js";
43
+ import { parseHostname } from "./internal/hostname_parser.js";
44
+ import { applyDnsResolution } from "./internal/dns_resolution.js";
45
45
 
46
46
  export const startServer = async ({
47
47
  signal = new AbortController().signal,
@@ -82,7 +82,7 @@ export const startServer = async ({
82
82
  "request headers": JSON.stringify(request.headers, null, " "),
83
83
  },
84
84
  ),
85
- )
85
+ );
86
86
  },
87
87
  // timeAllocated to start responding to a request
88
88
  // after this delay the server will respond with 504
@@ -95,28 +95,28 @@ export const startServer = async ({
95
95
  } = {}) => {
96
96
  // param validations
97
97
  {
98
- const unexpectedParamNames = Object.keys(rest)
98
+ const unexpectedParamNames = Object.keys(rest);
99
99
  if (unexpectedParamNames.length > 0) {
100
100
  throw new TypeError(
101
101
  `${unexpectedParamNames.join(",")}: there is no such param`,
102
- )
102
+ );
103
103
  }
104
104
  if (https) {
105
105
  if (typeof https !== "object") {
106
- throw new TypeError(`https must be an object, got ${https}`)
106
+ throw new TypeError(`https must be an object, got ${https}`);
107
107
  }
108
- const { certificate, privateKey } = https
108
+ const { certificate, privateKey } = https;
109
109
  if (!certificate || !privateKey) {
110
110
  throw new TypeError(
111
111
  `https must be an object with { certificate, privateKey }`,
112
- )
112
+ );
113
113
  }
114
114
  }
115
115
  if (http2 && !https) {
116
- throw new Error(`http2 needs https`)
116
+ throw new Error(`http2 needs https`);
117
117
  }
118
118
  }
119
- const logger = createLogger({ logLevel })
119
+ const logger = createLogger({ logLevel });
120
120
  // param warnings and normalization
121
121
  {
122
122
  if (
@@ -124,121 +124,121 @@ export const startServer = async ({
124
124
  https &&
125
125
  !allowHttpRequestOnHttps
126
126
  ) {
127
- redirectHttpToHttps = true
127
+ redirectHttpToHttps = true;
128
128
  }
129
129
  if (redirectHttpToHttps && !https) {
130
- logger.warn(`redirectHttpToHttps ignored because protocol is http`)
131
- redirectHttpToHttps = false
130
+ logger.warn(`redirectHttpToHttps ignored because protocol is http`);
131
+ redirectHttpToHttps = false;
132
132
  }
133
133
  if (allowHttpRequestOnHttps && redirectHttpToHttps) {
134
134
  logger.warn(
135
135
  `redirectHttpToHttps ignored because allowHttpRequestOnHttps is enabled`,
136
- )
137
- redirectHttpToHttps = false
136
+ );
137
+ redirectHttpToHttps = false;
138
138
  }
139
139
 
140
140
  if (allowHttpRequestOnHttps && !https) {
141
- logger.warn(`allowHttpRequestOnHttps ignored because protocol is http`)
142
- allowHttpRequestOnHttps = false
141
+ logger.warn(`allowHttpRequestOnHttps ignored because protocol is http`);
142
+ allowHttpRequestOnHttps = false;
143
143
  }
144
144
  }
145
145
 
146
- const server = {}
147
- const serviceController = createServiceController(services)
146
+ const server = {};
147
+ const serviceController = createServiceController(services);
148
148
  const processTeardownEvents = {
149
149
  SIGHUP: stopOnExit,
150
150
  SIGTERM: stopOnExit,
151
151
  SIGINT: stopOnSIGINT,
152
152
  beforeExit: stopOnExit,
153
153
  exit: stopOnExit,
154
- }
154
+ };
155
155
 
156
- let status = "starting"
157
- let nodeServer
158
- const startServerOperation = Abort.startOperation()
159
- const stopCallbackList = createCallbackListNotifiedOnce()
156
+ let status = "starting";
157
+ let nodeServer;
158
+ const startServerOperation = Abort.startOperation();
159
+ const stopCallbackList = createCallbackListNotifiedOnce();
160
160
  const serverOrigins = {
161
161
  local: "", // favors hostname when possible
162
- }
162
+ };
163
163
 
164
164
  try {
165
- startServerOperation.addAbortSignal(signal)
165
+ startServerOperation.addAbortSignal(signal);
166
166
  startServerOperation.addAbortSource((abort) => {
167
167
  return raceProcessTeardownEvents(processTeardownEvents, ({ name }) => {
168
- logger.info(`process teardown (${name}) -> aborting start server`)
169
- abort()
170
- })
171
- })
172
- startServerOperation.throwIfAborted()
168
+ logger.info(`process teardown (${name}) -> aborting start server`);
169
+ abort();
170
+ });
171
+ });
172
+ startServerOperation.throwIfAborted();
173
173
  nodeServer = await createNodeServer({
174
174
  https,
175
175
  redirectHttpToHttps,
176
176
  allowHttpRequestOnHttps,
177
177
  http2,
178
178
  http1Allowed,
179
- })
180
- startServerOperation.throwIfAborted()
179
+ });
180
+ startServerOperation.throwIfAborted();
181
181
 
182
182
  // https://nodejs.org/api/net.html#net_server_unref
183
183
  if (!keepProcessAlive) {
184
- nodeServer.unref()
184
+ nodeServer.unref();
185
185
  }
186
186
 
187
187
  const createOrigin = (hostname) => {
188
- const protocol = https ? "https" : "http"
188
+ const protocol = https ? "https" : "http";
189
189
  if (isIP(hostname) === 6) {
190
- return `${protocol}://[${hostname}]`
190
+ return `${protocol}://[${hostname}]`;
191
191
  }
192
- return `${protocol}://${hostname}`
193
- }
192
+ return `${protocol}://${hostname}`;
193
+ };
194
194
 
195
- const ipGetters = createIpGetters()
196
- let hostnameToListen
195
+ const ipGetters = createIpGetters();
196
+ let hostnameToListen;
197
197
  if (acceptAnyIp) {
198
- const firstInternalIp = ipGetters.getFirstInternalIp({ preferIpv6 })
199
- serverOrigins.local = createOrigin(firstInternalIp)
200
- serverOrigins.localip = createOrigin(firstInternalIp)
201
- const firstExternalIp = ipGetters.getFirstExternalIp({ preferIpv6 })
202
- serverOrigins.externalip = createOrigin(firstExternalIp)
203
- hostnameToListen = preferIpv6 ? "::" : "0.0.0.0"
198
+ const firstInternalIp = ipGetters.getFirstInternalIp({ preferIpv6 });
199
+ serverOrigins.local = createOrigin(firstInternalIp);
200
+ serverOrigins.localip = createOrigin(firstInternalIp);
201
+ const firstExternalIp = ipGetters.getFirstExternalIp({ preferIpv6 });
202
+ serverOrigins.externalip = createOrigin(firstExternalIp);
203
+ hostnameToListen = preferIpv6 ? "::" : "0.0.0.0";
204
204
  } else {
205
- hostnameToListen = hostname
205
+ hostnameToListen = hostname;
206
206
  }
207
- const hostnameInfo = parseHostname(hostname)
207
+ const hostnameInfo = parseHostname(hostname);
208
208
  if (hostnameInfo.type === "ip") {
209
209
  if (acceptAnyIp) {
210
210
  throw new Error(
211
211
  `hostname cannot be an ip when acceptAnyIp is enabled, got ${hostname}`,
212
- )
212
+ );
213
213
  }
214
214
 
215
- preferIpv6 = hostnameInfo.version === 6
216
- const firstInternalIp = ipGetters.getFirstInternalIp({ preferIpv6 })
217
- serverOrigins.local = createOrigin(firstInternalIp)
218
- serverOrigins.localip = createOrigin(firstInternalIp)
215
+ preferIpv6 = hostnameInfo.version === 6;
216
+ const firstInternalIp = ipGetters.getFirstInternalIp({ preferIpv6 });
217
+ serverOrigins.local = createOrigin(firstInternalIp);
218
+ serverOrigins.localip = createOrigin(firstInternalIp);
219
219
  if (hostnameInfo.label === "unspecified") {
220
- const firstExternalIp = ipGetters.getFirstExternalIp({ preferIpv6 })
221
- serverOrigins.externalip = createOrigin(firstExternalIp)
220
+ const firstExternalIp = ipGetters.getFirstExternalIp({ preferIpv6 });
221
+ serverOrigins.externalip = createOrigin(firstExternalIp);
222
222
  } else if (hostnameInfo.label === "loopback") {
223
223
  // nothing
224
224
  } else {
225
- serverOrigins.local = createOrigin(hostname)
225
+ serverOrigins.local = createOrigin(hostname);
226
226
  }
227
227
  } else {
228
228
  const hostnameDnsResolution = await applyDnsResolution(hostname, {
229
229
  verbatim: true,
230
- })
230
+ });
231
231
  if (hostnameDnsResolution) {
232
- const hostnameIp = hostnameDnsResolution.address
233
- serverOrigins.localip = createOrigin(hostnameIp)
234
- serverOrigins.local = createOrigin(hostname)
232
+ const hostnameIp = hostnameDnsResolution.address;
233
+ serverOrigins.localip = createOrigin(hostnameIp);
234
+ serverOrigins.local = createOrigin(hostname);
235
235
  } else {
236
- const firstInternalIp = ipGetters.getFirstInternalIp({ preferIpv6 })
236
+ const firstInternalIp = ipGetters.getFirstInternalIp({ preferIpv6 });
237
237
  // fallback to internal ip because there is no ip
238
238
  // associated to this hostname on operating system (in hosts file)
239
- hostname = firstInternalIp
240
- hostnameToListen = firstInternalIp
241
- serverOrigins.local = createOrigin(firstInternalIp)
239
+ hostname = firstInternalIp;
240
+ hostnameToListen = firstInternalIp;
241
+ serverOrigins.local = createOrigin(firstInternalIp);
242
242
  }
243
243
  }
244
244
 
@@ -248,20 +248,20 @@ export const startServer = async ({
248
248
  port,
249
249
  portHint,
250
250
  hostname: hostnameToListen,
251
- })
251
+ });
252
252
 
253
253
  // normalize origins (remove :80 when port is 80 for instance)
254
254
  Object.keys(serverOrigins).forEach((key) => {
255
- serverOrigins[key] = new URL(`${serverOrigins[key]}:${port}`).origin
256
- })
255
+ serverOrigins[key] = new URL(`${serverOrigins[key]}:${port}`).origin;
256
+ });
257
257
 
258
- serviceController.callHooks("serverListening", { port })
258
+ serviceController.callHooks("serverListening", { port });
259
259
  startServerOperation.addAbortCallback(async () => {
260
- await stopListening(nodeServer)
261
- })
262
- startServerOperation.throwIfAborted()
260
+ await stopListening(nodeServer);
261
+ });
262
+ startServerOperation.throwIfAborted();
263
263
  } finally {
264
- await startServerOperation.end()
264
+ await startServerOperation.end();
265
265
  }
266
266
 
267
267
  // the main server origin
@@ -274,116 +274,116 @@ export const startServer = async ({
274
274
  // for hostnames, not for ips
275
275
  // so we prefer https://locahost or https://local_hostname
276
276
  // over the ip
277
- const serverOrigin = serverOrigins.local
277
+ const serverOrigin = serverOrigins.local;
278
278
 
279
279
  // now the server is started (listening) it cannot be aborted anymore
280
280
  // (otherwise an AbortError is thrown to the code calling "startServer")
281
281
  // we can proceed to create a stop function to stop it gacefully
282
282
  // and add a request handler
283
283
  stopCallbackList.add(({ reason }) => {
284
- logger.info(`${serverName} stopping server (reason: ${reason})`)
285
- })
284
+ logger.info(`${serverName} stopping server (reason: ${reason})`);
285
+ });
286
286
  stopCallbackList.add(async () => {
287
- await stopListening(nodeServer)
288
- })
289
- let stoppedResolve
287
+ await stopListening(nodeServer);
288
+ });
289
+ let stoppedResolve;
290
290
  const stoppedPromise = new Promise((resolve) => {
291
- stoppedResolve = resolve
292
- })
291
+ stoppedResolve = resolve;
292
+ });
293
293
  const stop = memoize(async (reason = STOP_REASON_NOT_SPECIFIED) => {
294
- status = "stopping"
295
- await Promise.all(stopCallbackList.notify({ reason }))
296
- serviceController.callHooks("serverStopped", { reason })
297
- status = "stopped"
298
- stoppedResolve(reason)
299
- })
294
+ status = "stopping";
295
+ await Promise.all(stopCallbackList.notify({ reason }));
296
+ serviceController.callHooks("serverStopped", { reason });
297
+ status = "stopped";
298
+ stoppedResolve(reason);
299
+ });
300
300
 
301
301
  const cancelProcessTeardownRace = raceProcessTeardownEvents(
302
302
  processTeardownEvents,
303
303
  (winner) => {
304
- stop(PROCESS_TEARDOWN_EVENTS_MAP[winner.name])
304
+ stop(PROCESS_TEARDOWN_EVENTS_MAP[winner.name]);
305
305
  },
306
- )
307
- stopCallbackList.add(cancelProcessTeardownRace)
306
+ );
307
+ stopCallbackList.add(cancelProcessTeardownRace);
308
308
 
309
309
  const onError = (error) => {
310
310
  if (status === "stopping" && error.code === "ECONNRESET") {
311
- return
311
+ return;
312
312
  }
313
- throw error
314
- }
313
+ throw error;
314
+ };
315
315
 
316
- status = "opened"
316
+ status = "opened";
317
317
 
318
318
  const removeConnectionErrorListener = listenServerConnectionError(
319
319
  nodeServer,
320
320
  onError,
321
- )
322
- stopCallbackList.add(removeConnectionErrorListener)
321
+ );
322
+ stopCallbackList.add(removeConnectionErrorListener);
323
323
 
324
324
  const connectionsTracker = trackServerPendingConnections(nodeServer, {
325
325
  http2,
326
- })
326
+ });
327
327
  // opened connection must be shutdown before the close event is emitted
328
- stopCallbackList.add(connectionsTracker.stop)
328
+ stopCallbackList.add(connectionsTracker.stop);
329
329
 
330
330
  const pendingRequestsTracker = trackServerPendingRequests(nodeServer, {
331
331
  http2,
332
- })
332
+ });
333
333
  // ensure pending requests got a response from the server
334
334
  stopCallbackList.add((reason) => {
335
335
  pendingRequestsTracker.stop({
336
336
  status: reason === STOP_REASON_INTERNAL_ERROR ? 500 : 503,
337
337
  reason,
338
- })
339
- })
338
+ });
339
+ });
340
340
 
341
341
  request: {
342
342
  const requestCallback = async (nodeRequest, nodeResponse) => {
343
343
  // pause the stream to let a chance to "requestToResponse"
344
344
  // to call "requestRequestBody". Without this the request body readable stream
345
345
  // might be closed when we'll try to attach "data" and "end" listeners to it
346
- nodeRequest.pause()
346
+ nodeRequest.pause();
347
347
  if (!nagle) {
348
- nodeRequest.connection.setNoDelay(true)
348
+ nodeRequest.connection.setNoDelay(true);
349
349
  }
350
350
  if (redirectHttpToHttps && !nodeRequest.connection.encrypted) {
351
351
  nodeResponse.writeHead(301, {
352
352
  location: `${serverOrigin}${nodeRequest.url}`,
353
- })
354
- nodeResponse.end()
355
- return
353
+ });
354
+ nodeResponse.end();
355
+ return;
356
356
  }
357
357
 
358
- const receiveRequestOperation = Abort.startOperation()
358
+ const receiveRequestOperation = Abort.startOperation();
359
359
  receiveRequestOperation.addAbortSource((abort) => {
360
360
  const closeEventCallback = () => {
361
361
  if (nodeRequest.complete) {
362
- receiveRequestOperation.end()
362
+ receiveRequestOperation.end();
363
363
  } else {
364
- nodeResponse.destroy()
365
- abort()
364
+ nodeResponse.destroy();
365
+ abort();
366
366
  }
367
- }
368
- nodeRequest.once("close", closeEventCallback)
367
+ };
368
+ nodeRequest.once("close", closeEventCallback);
369
369
  return () => {
370
- nodeRequest.removeListener("close", closeEventCallback)
371
- }
372
- })
370
+ nodeRequest.removeListener("close", closeEventCallback);
371
+ };
372
+ });
373
373
  receiveRequestOperation.addAbortSource((abort) => {
374
- return stopCallbackList.add(abort)
375
- })
374
+ return stopCallbackList.add(abort);
375
+ });
376
376
 
377
- const sendResponseOperation = Abort.startOperation()
378
- sendResponseOperation.addAbortSignal(receiveRequestOperation.signal)
377
+ const sendResponseOperation = Abort.startOperation();
378
+ sendResponseOperation.addAbortSignal(receiveRequestOperation.signal);
379
379
  sendResponseOperation.addAbortSource((abort) => {
380
- return stopCallbackList.add(abort)
381
- })
380
+ return stopCallbackList.add(abort);
381
+ });
382
382
 
383
383
  const request = fromNodeRequest(nodeRequest, {
384
384
  serverOrigin,
385
385
  signal: receiveRequestOperation.signal,
386
- })
386
+ });
387
387
 
388
388
  // Handling request is asynchronous, we buffer logs for that request
389
389
  // until we know what happens with that request
@@ -392,67 +392,67 @@ export const startServer = async ({
392
392
  const rootRequestNode = {
393
393
  logs: [],
394
394
  children: [],
395
- }
395
+ };
396
396
  const addRequestLog = (node, { type, value }) => {
397
- node.logs.push({ type, value })
398
- }
397
+ node.logs.push({ type, value });
398
+ };
399
399
  const onRequestHandled = (node) => {
400
400
  if (node !== rootRequestNode) {
401
401
  // keep buffering until root request write logs for everyone
402
- return
402
+ return;
403
403
  }
404
404
  const prefixLines = (string, prefix) => {
405
- return string.replace(/^(?!\s*$)/gm, prefix)
406
- }
405
+ return string.replace(/^(?!\s*$)/gm, prefix);
406
+ };
407
407
  const writeLog = (
408
408
  { type, value },
409
409
  { someLogIsError, someLogIsWarn, depth },
410
410
  ) => {
411
411
  if (depth > 0) {
412
- value = prefixLines(value, " ".repeat(depth))
412
+ value = prefixLines(value, " ".repeat(depth));
413
413
  }
414
414
  if (type === "info") {
415
415
  if (someLogIsError) {
416
- type = "error"
416
+ type = "error";
417
417
  } else if (someLogIsWarn) {
418
- type = "warn"
418
+ type = "warn";
419
419
  }
420
420
  }
421
- logger[type](value)
422
- }
421
+ logger[type](value);
422
+ };
423
423
  const visitRequestNodeToLog = (requestNode, depth) => {
424
- let someLogIsError = false
425
- let someLogIsWarn = false
424
+ let someLogIsError = false;
425
+ let someLogIsWarn = false;
426
426
  requestNode.logs.forEach((log) => {
427
427
  if (log.type === "error") {
428
- someLogIsError = true
428
+ someLogIsError = true;
429
429
  }
430
430
  if (log.type === "warn") {
431
- someLogIsWarn = true
431
+ someLogIsWarn = true;
432
432
  }
433
- })
433
+ });
434
434
 
435
- const firstLog = requestNode.logs.shift()
436
- const lastLog = requestNode.logs.pop()
437
- const middleLogs = requestNode.logs
435
+ const firstLog = requestNode.logs.shift();
436
+ const lastLog = requestNode.logs.pop();
437
+ const middleLogs = requestNode.logs;
438
438
 
439
- writeLog(firstLog, { someLogIsError, someLogIsWarn, depth })
439
+ writeLog(firstLog, { someLogIsError, someLogIsWarn, depth });
440
440
  middleLogs.forEach((log) => {
441
- writeLog(log, { someLogIsError, someLogIsWarn, depth })
442
- })
441
+ writeLog(log, { someLogIsError, someLogIsWarn, depth });
442
+ });
443
443
  requestNode.children.forEach((child) => {
444
- visitRequestNodeToLog(child, depth + 1)
445
- })
444
+ visitRequestNodeToLog(child, depth + 1);
445
+ });
446
446
  if (lastLog) {
447
447
  writeLog(lastLog, {
448
448
  someLogIsError,
449
449
  someLogIsWarn,
450
450
  depth: depth + 1,
451
- })
451
+ });
452
452
  }
453
- }
454
- visitRequestNodeToLog(rootRequestNode, 0)
455
- }
453
+ };
454
+ visitRequestNodeToLog(rootRequestNode, 0);
455
+ };
456
456
  nodeRequest.on("error", (error) => {
457
457
  if (error.message === "aborted") {
458
458
  addRequestLog(rootRequestNode, {
@@ -460,7 +460,7 @@ export const startServer = async ({
460
460
  value: createDetailedMessage(`request aborted by client`, {
461
461
  "error message": error.message,
462
462
  }),
463
- })
463
+ });
464
464
  } else {
465
465
  // I'm not sure this can happen but it's here in case
466
466
  addRequestLog(rootRequestNode, {
@@ -468,12 +468,12 @@ export const startServer = async ({
468
468
  value: createDetailedMessage(`"error" event emitted on request`, {
469
469
  "error stack": error.stack,
470
470
  }),
471
- })
471
+ });
472
472
  }
473
- })
473
+ });
474
474
 
475
475
  const pushResponse = async ({ path, method }, { requestNode }) => {
476
- const http2Stream = nodeResponse.stream
476
+ const http2Stream = nodeResponse.stream;
477
477
 
478
478
  // being able to push a stream is nice to have
479
479
  // so when it fails it's not critical
@@ -486,12 +486,12 @@ export const startServer = async ({
486
486
  "error stack": e.stack,
487
487
  },
488
488
  ),
489
- })
490
- }
489
+ });
490
+ };
491
491
 
492
492
  // not aborted, let's try to push a stream into that response
493
493
  // https://nodejs.org/docs/latest-v16.x/api/http2.html#http2streampushstreamheaders-options-callback
494
- let pushStream
494
+ let pushStream;
495
495
  try {
496
496
  pushStream = await new Promise((resolve, reject) => {
497
497
  http2Stream.pushStream(
@@ -505,55 +505,55 @@ export const startServer = async ({
505
505
  // headers
506
506
  ) => {
507
507
  if (error) {
508
- reject(error)
508
+ reject(error);
509
509
  }
510
- resolve(pushStream)
510
+ resolve(pushStream);
511
511
  },
512
- )
513
- })
512
+ );
513
+ });
514
514
  } catch (e) {
515
- onPushStreamError(e)
516
- return
515
+ onPushStreamError(e);
516
+ return;
517
517
  }
518
518
 
519
- const abortController = new AbortController()
519
+ const abortController = new AbortController();
520
520
  // It's possible to get NGHTTP2_REFUSED_STREAM errors here
521
521
  // https://github.com/nodejs/node/issues/20824
522
522
  const pushErrorCallback = (error) => {
523
- onPushStreamError(error)
524
- abortController.abort()
525
- }
526
- pushStream.on("error", pushErrorCallback)
523
+ onPushStreamError(error);
524
+ abortController.abort();
525
+ };
526
+ pushStream.on("error", pushErrorCallback);
527
527
  sendResponseOperation.addEndCallback(() => {
528
- pushStream.removeListener("error", onPushStreamError)
529
- })
528
+ pushStream.removeListener("error", onPushStreamError);
529
+ });
530
530
 
531
531
  await sendResponseOperation.withSignal(async (signal) => {
532
- const pushResponseOperation = Abort.startOperation()
533
- pushResponseOperation.addAbortSignal(signal)
534
- pushResponseOperation.addAbortSignal(abortController.signal)
532
+ const pushResponseOperation = Abort.startOperation();
533
+ pushResponseOperation.addAbortSignal(signal);
534
+ pushResponseOperation.addAbortSignal(abortController.signal);
535
535
 
536
536
  const pushRequest = createPushRequest(request, {
537
537
  signal: pushResponseOperation.signal,
538
538
  pathname: path,
539
539
  method,
540
- })
540
+ });
541
541
 
542
542
  try {
543
543
  const responseProperties = await handleRequest(pushRequest, {
544
544
  requestNode,
545
- })
545
+ });
546
546
  if (!abortController.signal.aborted) {
547
547
  if (pushStream.destroyed) {
548
- abortController.abort()
548
+ abortController.abort();
549
549
  } else if (!http2Stream.pushAllowed) {
550
- abortController.abort()
550
+ abortController.abort();
551
551
  } else if (responseProperties.requestAborted) {
552
552
  } else {
553
553
  const responseLength =
554
- responseProperties.headers["content-length"] || 0
554
+ responseProperties.headers["content-length"] || 0;
555
555
  const { effectiveRecvDataLength, remoteWindowSize } =
556
- http2Stream.session.state
556
+ http2Stream.session.state;
557
557
  if (
558
558
  effectiveRecvDataLength + responseLength >
559
559
  remoteWindowSize
@@ -561,8 +561,8 @@ export const startServer = async ({
561
561
  addRequestLog(requestNode, {
562
562
  type: "debug",
563
563
  value: `Aborting stream to prevent exceeding remoteWindowSize`,
564
- })
565
- abortController.abort()
564
+ });
565
+ abortController.abort();
566
566
  }
567
567
  }
568
568
  }
@@ -572,37 +572,37 @@ export const startServer = async ({
572
572
  requestNode,
573
573
  responseStream: pushStream,
574
574
  responseProperties,
575
- })
575
+ });
576
576
  } finally {
577
- await pushResponseOperation.end()
577
+ await pushResponseOperation.end();
578
578
  }
579
- })
580
- }
579
+ });
580
+ };
581
581
 
582
582
  const handleRequest = async (request, { requestNode }) => {
583
- let requestReceivedMeasure
583
+ let requestReceivedMeasure;
584
584
  if (serverTiming) {
585
- requestReceivedMeasure = performance.now()
585
+ requestReceivedMeasure = performance.now();
586
586
  }
587
587
  addRequestLog(requestNode, {
588
588
  type: "info",
589
589
  value: request.parent
590
590
  ? `Push ${request.resource}`
591
591
  : `${request.method} ${request.url}`,
592
- })
592
+ });
593
593
  const warn = (value) => {
594
594
  addRequestLog(requestNode, {
595
595
  type: "warn",
596
596
  value,
597
- })
598
- }
597
+ });
598
+ };
599
599
 
600
- let requestWaitingTimeout
600
+ let requestWaitingTimeout;
601
601
  if (requestWaitingMs) {
602
602
  requestWaitingTimeout = setTimeout(
603
603
  () => requestWaitingCallback({ request, warn, requestWaitingMs }),
604
604
  requestWaitingMs,
605
- ).unref()
605
+ ).unref();
606
606
  }
607
607
 
608
608
  serviceController.callHooks(
@@ -615,16 +615,16 @@ export const startServer = async ({
615
615
  original: request.original || request,
616
616
  previous: request,
617
617
  ...newRequestProperties,
618
- })
618
+ });
619
619
  }
620
620
  },
621
- )
621
+ );
622
622
 
623
- let handleRequestReturnValue
624
- let errorWhileHandlingRequest = null
625
- let handleRequestTimings = serverTiming ? {} : null
623
+ let handleRequestReturnValue;
624
+ let errorWhileHandlingRequest = null;
625
+ let handleRequestTimings = serverTiming ? {} : null;
626
626
 
627
- let timeout
627
+ let timeout;
628
628
  const timeoutPromise = new Promise((resolve) => {
629
629
  timeout = setTimeout(() => {
630
630
  resolve({
@@ -636,9 +636,9 @@ export const startServer = async ({
636
636
  statusText: `server timeout after ${
637
637
  responseTimeout / 1000
638
638
  }s waiting to handle request`,
639
- })
640
- }, responseTimeout)
641
- })
639
+ });
640
+ }, responseTimeout);
641
+ });
642
642
  const handleRequestPromise = serviceController.callAsyncHooksUntil(
643
643
  "handleRequest",
644
644
  request,
@@ -650,29 +650,29 @@ export const startServer = async ({
650
650
  addRequestLog(requestNode, {
651
651
  type: "warn",
652
652
  value: `response push ignored because path is invalid (must be a string starting with "/", found ${path})`,
653
- })
654
- return
653
+ });
654
+ return;
655
655
  }
656
656
  if (!request.http2) {
657
657
  addRequestLog(requestNode, {
658
658
  type: "warn",
659
659
  value: `response push ignored because request is not http2`,
660
- })
661
- return
660
+ });
661
+ return;
662
662
  }
663
- const canPushStream = testCanPushStream(nodeResponse.stream)
663
+ const canPushStream = testCanPushStream(nodeResponse.stream);
664
664
  if (!canPushStream.can) {
665
665
  addRequestLog(requestNode, {
666
666
  type: "debug",
667
667
  value: `response push ignored because ${canPushStream.reason}`,
668
- })
669
- return
668
+ });
669
+ return;
670
670
  }
671
671
 
672
- let preventedByService = null
672
+ let preventedByService = null;
673
673
  const prevent = () => {
674
- preventedByService = serviceController.getCurrentService()
675
- }
674
+ preventedByService = serviceController.getCurrentService();
675
+ };
676
676
  serviceController.callHooksUntil(
677
677
  "onResponsePush",
678
678
  { path, method },
@@ -682,44 +682,44 @@ export const startServer = async ({
682
682
  prevent,
683
683
  },
684
684
  () => preventedByService,
685
- )
685
+ );
686
686
  if (preventedByService) {
687
687
  addRequestLog(requestNode, {
688
688
  type: "debug",
689
689
  value: `response push prevented by "${preventedByService.name}" service`,
690
- })
691
- return
690
+ });
691
+ return;
692
692
  }
693
693
 
694
- const requestChildNode = { logs: [], children: [] }
695
- requestNode.children.push(requestChildNode)
694
+ const requestChildNode = { logs: [], children: [] };
695
+ requestNode.children.push(requestChildNode);
696
696
  await pushResponse(
697
697
  { path, method },
698
698
  {
699
699
  requestNode: requestChildNode,
700
700
  parentHttp2Stream: nodeResponse.stream,
701
701
  },
702
- )
702
+ );
703
703
  },
704
704
  },
705
- )
705
+ );
706
706
  try {
707
707
  handleRequestReturnValue = await Promise.race([
708
708
  timeoutPromise,
709
709
  handleRequestPromise,
710
- ])
710
+ ]);
711
711
  } catch (e) {
712
- errorWhileHandlingRequest = e
712
+ errorWhileHandlingRequest = e;
713
713
  }
714
- clearTimeout(timeout)
714
+ clearTimeout(timeout);
715
715
 
716
- let responseProperties
716
+ let responseProperties;
717
717
  if (errorWhileHandlingRequest) {
718
718
  if (
719
719
  errorWhileHandlingRequest.name === "AbortError" &&
720
720
  request.signal.aborted
721
721
  ) {
722
- responseProperties = { requestAborted: true }
722
+ responseProperties = { requestAborted: true };
723
723
  } else {
724
724
  // internal error, create 500 response
725
725
  if (
@@ -730,7 +730,7 @@ export const startServer = async ({
730
730
  stopOnInternalError
731
731
  ) {
732
732
  // il faudrais pouvoir stop que les autres response ?
733
- stop(STOP_REASON_INTERNAL_ERROR)
733
+ stop(STOP_REASON_INTERNAL_ERROR);
734
734
  }
735
735
  const handleErrorReturnValue =
736
736
  await serviceController.callAsyncHooksUntil(
@@ -740,9 +740,9 @@ export const startServer = async ({
740
740
  request,
741
741
  warn,
742
742
  },
743
- )
743
+ );
744
744
  if (!handleErrorReturnValue) {
745
- throw errorWhileHandlingRequest
745
+ throw errorWhileHandlingRequest;
746
746
  }
747
747
  addRequestLog(requestNode, {
748
748
  type: "error",
@@ -752,7 +752,7 @@ export const startServer = async ({
752
752
  "error stack": errorWhileHandlingRequest.stack,
753
753
  },
754
754
  ),
755
- })
755
+ });
756
756
  responseProperties = composeTwoResponses(
757
757
  {
758
758
  status: 500,
@@ -764,7 +764,7 @@ export const startServer = async ({
764
764
  },
765
765
  },
766
766
  handleErrorReturnValue,
767
- )
767
+ );
768
768
  }
769
769
  } else {
770
770
  const {
@@ -774,7 +774,7 @@ export const startServer = async ({
774
774
  headers = {},
775
775
  body,
776
776
  ...rest
777
- } = handleRequestReturnValue || {}
777
+ } = handleRequestReturnValue || {};
778
778
  responseProperties = {
779
779
  status,
780
780
  statusText,
@@ -782,25 +782,25 @@ export const startServer = async ({
782
782
  headers,
783
783
  body,
784
784
  ...rest,
785
- }
785
+ };
786
786
  }
787
787
 
788
788
  if (serverTiming) {
789
- const responseReadyMeasure = performance.now()
789
+ const responseReadyMeasure = performance.now();
790
790
  const timeToStartResponding =
791
- responseReadyMeasure - requestReceivedMeasure
791
+ responseReadyMeasure - requestReceivedMeasure;
792
792
  const serverTiming = {
793
793
  ...handleRequestTimings,
794
794
  ...responseProperties.timing,
795
795
  "time to start responding": timeToStartResponding,
796
- }
796
+ };
797
797
  responseProperties.headers = composeTwoHeaders(
798
798
  responseProperties.headers,
799
799
  timingToServerTimingResponseHeaders(serverTiming),
800
- )
800
+ );
801
801
  }
802
802
  if (requestWaitingMs) {
803
- clearTimeout(requestWaitingTimeout)
803
+ clearTimeout(requestWaitingTimeout);
804
804
  }
805
805
  if (
806
806
  request.method !== "HEAD" &&
@@ -810,7 +810,7 @@ export const startServer = async ({
810
810
  addRequestLog(requestNode, {
811
811
  type: "warn",
812
812
  value: `content-length header is ${responseProperties.headers["content-length"]} but body is empty`,
813
- })
813
+ });
814
814
  }
815
815
  serviceController.callHooks(
816
816
  "injectResponseHeaders",
@@ -824,16 +824,16 @@ export const startServer = async ({
824
824
  responseProperties.headers = composeTwoHeaders(
825
825
  responseProperties.headers,
826
826
  returnValue,
827
- )
827
+ );
828
828
  }
829
829
  },
830
- )
830
+ );
831
831
  serviceController.callHooks("responseReady", responseProperties, {
832
832
  request,
833
833
  warn,
834
- })
835
- return responseProperties
836
- }
834
+ });
835
+ return responseProperties;
836
+ };
837
837
 
838
838
  const sendResponse = async ({
839
839
  signal,
@@ -846,10 +846,10 @@ export const startServer = async ({
846
846
  // the parent response is immediatly ended. It means child responses (pushed streams)
847
847
  // won't get a chance to be pushed.
848
848
  // To let a chance to pushed streams we wait a little before sending the response
849
- const ignoreBody = request.method === "HEAD"
850
- const bodyIsEmpty = !responseProperties.body || ignoreBody
849
+ const ignoreBody = request.method === "HEAD";
850
+ const bodyIsEmpty = !responseProperties.body || ignoreBody;
851
851
  if (bodyIsEmpty && requestNode.children.length > 0) {
852
- await new Promise((resolve) => setTimeout(resolve))
852
+ await new Promise((resolve) => setTimeout(resolve));
853
853
  }
854
854
 
855
855
  await writeNodeResponse(responseStream, responseProperties, {
@@ -859,8 +859,8 @@ export const startServer = async ({
859
859
  addRequestLog(requestNode, {
860
860
  type: "info",
861
861
  value: `response aborted`,
862
- })
863
- onRequestHandled(requestNode)
862
+ });
863
+ onRequestHandled(requestNode);
864
864
  },
865
865
  onError: (error) => {
866
866
  addRequestLog(requestNode, {
@@ -871,11 +871,11 @@ export const startServer = async ({
871
871
  "error stack": error.stack,
872
872
  },
873
873
  ),
874
- })
875
- onRequestHandled(requestNode)
874
+ });
875
+ onRequestHandled(requestNode);
876
876
  },
877
877
  onHeadersSent: ({ status, statusText }) => {
878
- const statusType = statusToType(status)
878
+ const statusType = statusToType(status);
879
879
  addRequestLog(requestNode, {
880
880
  type:
881
881
  status === 404 && request.pathname === "/favicon.ico"
@@ -890,31 +890,31 @@ export const startServer = async ({
890
890
  value: `${colorizeResponseStatus(status)} ${
891
891
  responseProperties.statusMessage || statusText
892
892
  }`,
893
- })
893
+ });
894
894
  },
895
895
  onEnd: () => {
896
- onRequestHandled(requestNode)
896
+ onRequestHandled(requestNode);
897
897
  },
898
- })
899
- }
898
+ });
899
+ };
900
900
 
901
901
  try {
902
902
  if (receiveRequestOperation.signal.aborted) {
903
- return
903
+ return;
904
904
  }
905
905
  const responseProperties = await handleRequest(request, {
906
906
  requestNode: rootRequestNode,
907
- })
908
- nodeRequest.resume()
907
+ });
908
+ nodeRequest.resume();
909
909
  if (receiveRequestOperation.signal.aborted) {
910
- return
910
+ return;
911
911
  }
912
912
 
913
913
  // the node request readable stream is never closed because
914
914
  // the response headers contains "connection: keep-alive"
915
915
  // In this scenario we want to disable READABLE_STREAM_TIMEOUT warning
916
916
  if (responseProperties.headers.connection === "keep-alive") {
917
- clearTimeout(request.body.timeout)
917
+ clearTimeout(request.body.timeout);
918
918
  }
919
919
 
920
920
  await sendResponse({
@@ -923,75 +923,75 @@ export const startServer = async ({
923
923
  requestNode: rootRequestNode,
924
924
  responseStream: nodeResponse,
925
925
  responseProperties,
926
- })
926
+ });
927
927
  } finally {
928
- await sendResponseOperation.end()
928
+ await sendResponseOperation.end();
929
929
  }
930
- }
931
- const removeRequestListener = listenRequest(nodeServer, requestCallback)
930
+ };
931
+ const removeRequestListener = listenRequest(nodeServer, requestCallback);
932
932
  // ensure we don't try to handle new requests while server is stopping
933
- stopCallbackList.add(removeRequestListener)
933
+ stopCallbackList.add(removeRequestListener);
934
934
  }
935
935
 
936
936
  websocket: {
937
937
  // https://github.com/websockets/ws/blob/master/doc/ws.md#class-websocket
938
- const websocketHandlers = []
938
+ const websocketHandlers = [];
939
939
  serviceController.services.forEach((service) => {
940
- const { handleWebsocket } = service
940
+ const { handleWebsocket } = service;
941
941
  if (handleWebsocket) {
942
- websocketHandlers.push(handleWebsocket)
942
+ websocketHandlers.push(handleWebsocket);
943
943
  }
944
- })
944
+ });
945
945
  if (websocketHandlers.length > 0) {
946
- const websocketClients = new Set()
947
- const { WebSocketServer } = await import("ws")
948
- let websocketServer = new WebSocketServer({ noServer: true })
946
+ const websocketClients = new Set();
947
+ const { WebSocketServer } = await import("ws");
948
+ let websocketServer = new WebSocketServer({ noServer: true });
949
949
  const websocketOrigin = https
950
950
  ? `wss://${hostname}:${port}`
951
- : `ws://${hostname}:${port}`
952
- server.websocketOrigin = websocketOrigin
951
+ : `ws://${hostname}:${port}`;
952
+ server.websocketOrigin = websocketOrigin;
953
953
  const upgradeCallback = (nodeRequest, socket, head) => {
954
954
  websocketServer.handleUpgrade(
955
955
  nodeRequest,
956
956
  socket,
957
957
  head,
958
958
  async (websocket) => {
959
- websocketClients.add(websocket)
959
+ websocketClients.add(websocket);
960
960
  websocket.once("close", () => {
961
- websocketClients.delete(websocket)
962
- })
961
+ websocketClients.delete(websocket);
962
+ });
963
963
  const request = fromNodeRequest(nodeRequest, {
964
964
  serverOrigin: websocketOrigin,
965
965
  signal: new AbortController().signal,
966
966
  requestBodyLifetime,
967
- })
967
+ });
968
968
  serviceController.callAsyncHooksUntil(
969
969
  "handleWebsocket",
970
970
  websocket,
971
971
  {
972
972
  request,
973
973
  },
974
- )
974
+ );
975
975
  },
976
- )
977
- }
976
+ );
977
+ };
978
978
 
979
979
  // see server-polyglot.js, upgrade must be listened on https server when used
980
- const facadeServer = nodeServer._tlsServer || nodeServer
980
+ const facadeServer = nodeServer._tlsServer || nodeServer;
981
981
  const removeUpgradeCallback = listenEvent(
982
982
  facadeServer,
983
983
  "upgrade",
984
984
  upgradeCallback,
985
- )
986
- stopCallbackList.add(removeUpgradeCallback)
985
+ );
986
+ stopCallbackList.add(removeUpgradeCallback);
987
987
  stopCallbackList.add(() => {
988
988
  websocketClients.forEach((websocketClient) => {
989
- websocketClient.close()
990
- })
991
- websocketClients.clear()
992
- websocketServer.close()
993
- websocketServer = null
994
- })
989
+ websocketClient.close();
990
+ });
991
+ websocketClients.clear();
992
+ websocketServer.close();
993
+ websocketServer = null;
994
+ });
995
995
  }
996
996
  }
997
997
 
@@ -999,9 +999,9 @@ export const startServer = async ({
999
999
  if (serverOrigins.network) {
1000
1000
  logger.info(
1001
1001
  `${serverName} started at ${serverOrigins.local} (${serverOrigins.network})`,
1002
- )
1002
+ );
1003
1003
  } else {
1004
- logger.info(`${serverName} started at ${serverOrigins.local}`)
1004
+ logger.info(`${serverName} started at ${serverOrigins.local}`);
1005
1005
  }
1006
1006
  }
1007
1007
 
@@ -1015,14 +1015,14 @@ export const startServer = async ({
1015
1015
  stop,
1016
1016
  stoppedPromise,
1017
1017
  addEffect: (callback) => {
1018
- const cleanup = callback()
1018
+ const cleanup = callback();
1019
1019
  if (typeof cleanup === "function") {
1020
- stopCallbackList.add(cleanup)
1020
+ stopCallbackList.add(cleanup);
1021
1021
  }
1022
1022
  },
1023
- })
1024
- return server
1025
- }
1023
+ });
1024
+ return server;
1025
+ };
1026
1026
 
1027
1027
  const createNodeServer = async ({
1028
1028
  https,
@@ -1032,47 +1032,47 @@ const createNodeServer = async ({
1032
1032
  http1Allowed,
1033
1033
  }) => {
1034
1034
  if (https) {
1035
- const { certificate, privateKey } = https
1035
+ const { certificate, privateKey } = https;
1036
1036
  if (redirectHttpToHttps || allowHttpRequestOnHttps) {
1037
1037
  return createPolyglotServer({
1038
1038
  certificate,
1039
1039
  privateKey,
1040
1040
  http2,
1041
1041
  http1Allowed,
1042
- })
1042
+ });
1043
1043
  }
1044
- const { createServer } = await import("node:https")
1044
+ const { createServer } = await import("node:https");
1045
1045
  return createServer({
1046
1046
  cert: certificate,
1047
1047
  key: privateKey,
1048
- })
1048
+ });
1049
1049
  }
1050
- const { createServer } = await import("node:http")
1051
- return createServer()
1052
- }
1050
+ const { createServer } = await import("node:http");
1051
+ return createServer();
1052
+ };
1053
1053
 
1054
1054
  const testCanPushStream = (http2Stream) => {
1055
1055
  if (!http2Stream.pushAllowed) {
1056
1056
  return {
1057
1057
  can: false,
1058
1058
  reason: `stream.pushAllowed is false`,
1059
- }
1059
+ };
1060
1060
  }
1061
1061
 
1062
1062
  // See https://nodejs.org/dist/latest-v16.x/docs/api/http2.html#http2sessionstate
1063
1063
  // And https://github.com/google/node-h2-auto-push/blob/67a36c04cbbd6da7b066a4e8d361c593d38853a4/src/index.ts#L100-L106
1064
- const { remoteWindowSize } = http2Stream.session.state
1064
+ const { remoteWindowSize } = http2Stream.session.state;
1065
1065
  if (remoteWindowSize === 0) {
1066
1066
  return {
1067
1067
  can: false,
1068
1068
  reason: `no more remoteWindowSize`,
1069
- }
1069
+ };
1070
1070
  }
1071
1071
 
1072
1072
  return {
1073
1073
  can: true,
1074
- }
1075
- }
1074
+ };
1075
+ };
1076
1076
 
1077
1077
  const PROCESS_TEARDOWN_EVENTS_MAP = {
1078
1078
  SIGHUP: STOP_REASON_PROCESS_SIGHUP,
@@ -1080,4 +1080,4 @@ const PROCESS_TEARDOWN_EVENTS_MAP = {
1080
1080
  SIGINT: STOP_REASON_PROCESS_SIGINT,
1081
1081
  beforeExit: STOP_REASON_PROCESS_BEFORE_EXIT,
1082
1082
  exit: STOP_REASON_PROCESS_EXIT,
1083
- }
1083
+ };