@jsenv/server 15.0.2 → 15.0.4

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 +4 -4
  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,32 +1,32 @@
1
1
  export const readRequestBody = (request, { as = "string" } = {}) => {
2
2
  return new Promise((resolve, reject) => {
3
- const bufferArray = []
3
+ const bufferArray = [];
4
4
  request.body.subscribe({
5
5
  error: reject,
6
6
  next: (buffer) => {
7
- bufferArray.push(buffer)
7
+ bufferArray.push(buffer);
8
8
  },
9
9
  complete: () => {
10
- const bodyAsBuffer = Buffer.concat(bufferArray)
10
+ const bodyAsBuffer = Buffer.concat(bufferArray);
11
11
 
12
12
  if (as === "buffer") {
13
- resolve(bodyAsBuffer)
14
- return
13
+ resolve(bodyAsBuffer);
14
+ return;
15
15
  }
16
16
 
17
17
  if (as === "string") {
18
- const bodyAsString = bodyAsBuffer.toString()
19
- resolve(bodyAsString)
20
- return
18
+ const bodyAsString = bodyAsBuffer.toString();
19
+ resolve(bodyAsString);
20
+ return;
21
21
  }
22
22
 
23
23
  if (as === "json") {
24
- const bodyAsString = bodyAsBuffer.toString()
25
- const bodyAsJSON = JSON.parse(bodyAsString)
26
- resolve(bodyAsJSON)
27
- return
24
+ const bodyAsString = bodyAsBuffer.toString();
25
+ const bodyAsJSON = JSON.parse(bodyAsString);
26
+ resolve(bodyAsJSON);
27
+ return;
28
28
  }
29
29
  },
30
- })
31
- })
32
- }
30
+ });
31
+ });
32
+ };
@@ -1,17 +1,17 @@
1
- import { readdirSync } from "node:fs"
1
+ import { readdirSync } from "node:fs";
2
2
 
3
- import { pickContentType } from "./content_negotiation/pick_content_type.js"
3
+ import { pickContentType } from "./content_negotiation/pick_content_type.js";
4
4
 
5
5
  export const serveDirectory = (
6
6
  url,
7
7
  { headers = {}, rootDirectoryUrl } = {},
8
8
  ) => {
9
- url = String(url)
10
- url = url[url.length - 1] === "/" ? url : `${url}/`
11
- const directoryContentArray = readdirSync(new URL(url))
9
+ url = String(url);
10
+ url = url[url.length - 1] === "/" ? url : `${url}/`;
11
+ const directoryContentArray = readdirSync(new URL(url));
12
12
  const responseProducers = {
13
13
  "application/json": () => {
14
- const directoryContentJson = JSON.stringify(directoryContentArray)
14
+ const directoryContentJson = JSON.stringify(directoryContentArray);
15
15
  return {
16
16
  status: 200,
17
17
  headers: {
@@ -19,7 +19,7 @@ export const serveDirectory = (
19
19
  "content-length": directoryContentJson.length,
20
20
  },
21
21
  body: directoryContentJson,
22
- }
22
+ };
23
23
  },
24
24
  "text/html": () => {
25
25
  const directoryAsHtml = `<!DOCTYPE html>
@@ -34,18 +34,18 @@ export const serveDirectory = (
34
34
  <h1>Content of directory ${url}</h1>
35
35
  <ul>
36
36
  ${directoryContentArray.map((filename) => {
37
- const fileUrl = String(new URL(filename, url))
37
+ const fileUrl = String(new URL(filename, url));
38
38
  const fileUrlRelativeToServer = fileUrl.slice(
39
39
  String(rootDirectoryUrl).length,
40
- )
40
+ );
41
41
  return `<li>
42
42
  <a href="/${fileUrlRelativeToServer}">${fileUrlRelativeToServer}</a>
43
- </li>`
43
+ </li>`;
44
44
  }).join(`
45
45
  `)}
46
46
  </ul>
47
47
  </body>
48
- </html>`
48
+ </html>`;
49
49
 
50
50
  return {
51
51
  status: 200,
@@ -54,12 +54,12 @@ export const serveDirectory = (
54
54
  "content-length": Buffer.byteLength(directoryAsHtml),
55
55
  },
56
56
  body: directoryAsHtml,
57
- }
57
+ };
58
58
  },
59
- }
59
+ };
60
60
  const bestContentType = pickContentType(
61
61
  { headers },
62
62
  Object.keys(responseProducers),
63
- )
64
- return responseProducers[bestContentType || "application/json"]()
65
- }
63
+ );
64
+ return responseProducers[bestContentType || "application/json"]();
65
+ };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  parseMultipleHeader,
3
3
  stringifyMultipleHeader,
4
- } from "../internal/multiple-header.js"
4
+ } from "../internal/multiple-header.js";
5
5
 
6
6
  // to predict order in chrome devtools we should put a,b,c,d,e or something
7
7
  // because in chrome dev tools they are shown in alphabetic order
@@ -10,19 +10,19 @@ import {
10
10
  // so response can return a new timing object
11
11
  // yes it's awful, feel free to PR with a better approach :)
12
12
  export const timingToServerTimingResponseHeaders = (timing) => {
13
- const serverTimingHeader = {}
13
+ const serverTimingHeader = {};
14
14
  Object.keys(timing).forEach((key, index) => {
15
- const name = letters[index] || "zz"
15
+ const name = letters[index] || "zz";
16
16
  serverTimingHeader[name] = {
17
17
  desc: key,
18
18
  dur: timing[key],
19
- }
20
- })
19
+ };
20
+ });
21
21
  const serverTimingHeaderString =
22
- stringifyServerTimingHeader(serverTimingHeader)
22
+ stringifyServerTimingHeader(serverTimingHeader);
23
23
 
24
- return { "server-timing": serverTimingHeaderString }
25
- }
24
+ return { "server-timing": serverTimingHeaderString };
25
+ };
26
26
 
27
27
  export const parseServerTimingHeader = (serverTimingHeaderString) => {
28
28
  const serverTimingHeaderObject = parseMultipleHeader(
@@ -30,27 +30,27 @@ export const parseServerTimingHeader = (serverTimingHeaderString) => {
30
30
  {
31
31
  validateName: validateServerTimingName,
32
32
  validateProperty: ({ name }) => {
33
- return name === "desc" || name === "dur"
33
+ return name === "desc" || name === "dur";
34
34
  },
35
35
  },
36
- )
36
+ );
37
37
 
38
- const serverTiming = {}
38
+ const serverTiming = {};
39
39
  Object.keys(serverTimingHeaderObject).forEach((key) => {
40
- const { desc, dur } = serverTimingHeaderObject[key]
40
+ const { desc, dur } = serverTimingHeaderObject[key];
41
41
  serverTiming[key] = {
42
42
  ...(desc ? { description: desc } : {}),
43
43
  ...(dur ? { duration: dur } : {}),
44
- }
45
- })
46
- return serverTiming
47
- }
44
+ };
45
+ });
46
+ return serverTiming;
47
+ };
48
48
 
49
49
  export const stringifyServerTimingHeader = (serverTimingHeader) => {
50
50
  return stringifyMultipleHeader(serverTimingHeader, {
51
51
  validateName: validateServerTimingName,
52
- })
53
- }
52
+ });
53
+ };
54
54
 
55
55
  // (),/:;<=>?@[\]{}" Don't allowed
56
56
  // Minimal length is one symbol
@@ -59,13 +59,13 @@ export const stringifyServerTimingHeader = (serverTimingHeader) => {
59
59
  // https://www.w3.org/TR/2019/WD-server-timing-20190307/#the-server-timing-header-field
60
60
  // https://tools.ietf.org/html/rfc7230#section-3.2.6
61
61
  const validateServerTimingName = (name) => {
62
- const valid = /^[!#$%&'*+\-.^_`|~0-9a-z]+$/gi.test(name)
62
+ const valid = /^[!#$%&'*+\-.^_`|~0-9a-z]+$/gi.test(name);
63
63
  if (!valid) {
64
- console.warn(`server timing contains invalid symbols`)
65
- return false
64
+ console.warn(`server timing contains invalid symbols`);
65
+ return false;
66
66
  }
67
- return true
68
- }
67
+ return true;
68
+ };
69
69
 
70
70
  const letters = [
71
71
  "a",
@@ -94,4 +94,4 @@ const letters = [
94
94
  "x",
95
95
  "y",
96
96
  "z",
97
- ]
97
+ ];
@@ -1,26 +1,26 @@
1
- import { performance } from "node:perf_hooks"
1
+ import { performance } from "node:perf_hooks";
2
2
 
3
3
  export const timeStart = (name) => {
4
4
  // as specified in https://w3c.github.io/server-timing/#the-performanceservertiming-interface
5
5
  // duration is a https://www.w3.org/TR/hr-time-2/#sec-domhighrestimestamp
6
- const startTimestamp = performance.now()
6
+ const startTimestamp = performance.now();
7
7
  const timeEnd = () => {
8
- const endTimestamp = performance.now()
8
+ const endTimestamp = performance.now();
9
9
  const timing = {
10
10
  [name]: endTimestamp - startTimestamp,
11
- }
12
- return timing
13
- }
14
- return timeEnd
15
- }
11
+ };
12
+ return timing;
13
+ };
14
+ return timeEnd;
15
+ };
16
16
 
17
17
  export const timeFunction = (name, fn) => {
18
- const timeEnd = timeStart(name)
19
- const returnValue = fn()
18
+ const timeEnd = timeStart(name);
19
+ const returnValue = fn();
20
20
  if (returnValue && typeof returnValue.then === "function") {
21
21
  return returnValue.then((value) => {
22
- return [timeEnd(), value]
23
- })
22
+ return [timeEnd(), value];
23
+ });
24
24
  }
25
- return [timeEnd(), returnValue]
26
- }
25
+ return [timeEnd(), returnValue];
26
+ };