@jsenv/server 12.3.3 → 12.5.0

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/main.js CHANGED
@@ -7,7 +7,6 @@
7
7
  export { startServer } from "./src/startServer.js"
8
8
  export { composeServices } from "./src/service_composition/service_composition.js"
9
9
  export { setupRoutes } from "./src/service_composition/routing.js"
10
- export { jsenvServerInternalErrorToResponse } from "./src/jsenvServerInternalErrorToResponse.js"
11
10
  export { readRequestBody } from "./src/readRequestBody.js"
12
11
  export { fetchFileSystem } from "./src/fetch_filesystem.js"
13
12
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/server",
3
- "version": "12.3.3",
3
+ "version": "12.5.0",
4
4
  "description": "Write your Node.js server using pure functions",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -34,9 +34,9 @@
34
34
  "importmap": "node ./script/importmap/importmap.mjs",
35
35
  "eslint": "node ./node_modules/eslint/bin/eslint.js . --ext=.js,.mjs",
36
36
  "performance": "node --expose-gc ./script/performance/performance.mjs --log",
37
+ "snapshot": "node ./test/internal_error/generate_html_snapshot_files.mjs",
37
38
  "test": "node ./script/test/test.mjs",
38
39
  "test-with-coverage": "npm run test -- --coverage",
39
- "generate-html-snapshots": "node ./test/internal_error/generate_html_snapshot_files.mjs",
40
40
  "prettier": "prettier --write .",
41
41
  "certificate-install": "node ./script/certificate/certificate_install.mjs",
42
42
  "playwright-install": "npx playwright install-deps && npx playwright install"
@@ -44,27 +44,27 @@
44
44
  "dependencies": {
45
45
  "@jsenv/abort": "4.1.2",
46
46
  "@jsenv/logger": "4.0.1",
47
- "@jsenv/url-meta": "6.0.3",
48
- "node-fetch": "2.6.2",
47
+ "@jsenv/url-meta": "6.2.0",
48
+ "node-fetch": "2.6.7",
49
49
  "path-to-regexp": "6.2.0"
50
50
  },
51
51
  "devDependencies": {
52
- "@jsenv/assert": "2.4.1",
53
- "@jsenv/core": "25.1.0",
52
+ "@jsenv/assert": "2.5.2",
53
+ "@jsenv/core": "25.4.9",
54
54
  "@jsenv/eslint-config": "16.0.9",
55
- "@jsenv/filesystem": "2.6.1",
56
- "@jsenv/github-release-package": "1.2.3",
57
- "@jsenv/https-local": "1.0.3",
58
- "@jsenv/importmap-eslint-resolver": "5.2.2",
59
- "@jsenv/importmap-node-module": "5.1.0",
60
- "@jsenv/package-publish": "1.6.2",
61
- "@jsenv/performance-impact": "2.2.1",
55
+ "@jsenv/filesystem": "2.7.1",
56
+ "@jsenv/github-release-package": "1.3.4",
57
+ "@jsenv/https-local": "1.0.7",
58
+ "@jsenv/importmap-eslint-resolver": "5.2.5",
59
+ "@jsenv/importmap-node-module": "5.1.3",
60
+ "@jsenv/package-publish": "1.7.2",
61
+ "@jsenv/performance-impact": "2.2.7",
62
62
  "eslint": "8.7.0",
63
63
  "eslint-plugin-import": "2.25.4",
64
64
  "eventsource": "1.1.0",
65
- "fastify": "3.25.3",
65
+ "fastify": "3.27.0",
66
66
  "fastify-static": "4.5.0",
67
- "playwright": "1.17.2",
67
+ "playwright": "1.18.1",
68
68
  "prettier": "2.5.1"
69
69
  }
70
70
  }
@@ -1,14 +1,18 @@
1
1
  import { negotiateContentType } from "./content_negotiation/negotiateContentType.js"
2
2
 
3
- export const jsenvServerInternalErrorToResponse = (
3
+ export const applyDefaultErrorToResponse = (
4
4
  serverInternalError,
5
- { request, sendServerInternalErrorDetails = false },
5
+ { request, sendErrorDetails = false },
6
6
  ) => {
7
7
  const serverInternalErrorIsAPrimitive =
8
8
  serverInternalError === null ||
9
9
  (typeof serverInternalError !== "object" &&
10
10
  typeof serverInternalError !== "function")
11
11
 
12
+ if (!serverInternalErrorIsAPrimitive && serverInternalError.asResponse) {
13
+ return serverInternalError.asResponse()
14
+ }
15
+
12
16
  const dataToSend = serverInternalErrorIsAPrimitive
13
17
  ? {
14
18
  code: "VALUE_THROWED",
@@ -16,7 +20,7 @@ export const jsenvServerInternalErrorToResponse = (
16
20
  }
17
21
  : {
18
22
  code: serverInternalError.code || "UNKNOWN_ERROR",
19
- ...(sendServerInternalErrorDetails
23
+ ...(sendErrorDetails
20
24
  ? {
21
25
  stack: serverInternalError.stack,
22
26
  ...serverInternalError,
@@ -27,7 +31,7 @@ export const jsenvServerInternalErrorToResponse = (
27
31
  const availableContentTypes = {
28
32
  "text/html": () => {
29
33
  const renderHtmlForErrorWithoutDetails = () => {
30
- return `<p>Details not available: to enable them server must be started with sendServerInternalErrorDetails: true.</p>`
34
+ return `<p>Details not available: to enable them server must be started with sendErrorDetails: true.</p>`
31
35
  }
32
36
 
33
37
  const renderHtmlForErrorWithDetails = () => {
@@ -55,7 +59,7 @@ export const jsenvServerInternalErrorToResponse = (
55
59
  <details>
56
60
  <summary>See internal error details</summary>
57
61
  ${
58
- sendServerInternalErrorDetails
62
+ sendErrorDetails
59
63
  ? renderHtmlForErrorWithDetails()
60
64
  : renderHtmlForErrorWithoutDetails()
61
65
  }
@@ -1,38 +1,28 @@
1
- import { urlToMeta, normalizeStructuredMetaMap } from "@jsenv/url-meta"
1
+ import { applyAliases } from "@jsenv/url-meta"
2
2
 
3
3
  export const pluginRessourceAliases = (ressourceAliases) => {
4
- const ressourceAliasMap = {}
4
+ const aliases = {}
5
5
  Object.keys(ressourceAliases).forEach((key) => {
6
- ressourceAliasMap[ressourceAliases[key]] = key
6
+ aliases[asFileUrl(key)] = asFileUrl(ressourceAliases[key])
7
7
  })
8
- const structuredMetaMap = normalizeStructuredMetaMap(
9
- { alias: ressourceAliasMap },
10
- "file:///",
11
- )
12
-
13
- const getRessourceAlias = (pathname) => {
14
- const { alias } = urlToMeta({
15
- url: `file://${pathname}`,
16
- structuredMetaMap,
17
- })
18
- return alias
19
- }
20
-
21
8
  return {
22
9
  ressource_aliases: {
23
10
  onRequest: (request, { redirectRequest }) => {
24
- const ressourceAlias = getRessourceAlias(request.pathname)
25
- if (!ressourceAlias) {
11
+ const ressourceBeforeAlias = request.ressource
12
+ const urlAfterAliasing = applyAliases({
13
+ url: asFileUrl(request.pathname),
14
+ aliases,
15
+ })
16
+ const ressourceAfterAlias = urlAfterAliasing.slice("file://".length)
17
+ if (ressourceBeforeAlias === ressourceAfterAlias) {
26
18
  return
27
19
  }
28
-
29
- const urlObjectAfterAlias = replaceUrlRessource(
30
- request.url,
31
- ressourceAlias,
20
+ const ressource = replaceRessource(
21
+ ressourceBeforeAlias,
22
+ ressourceAfterAlias,
32
23
  )
33
- const ressource = `${urlObjectAfterAlias.pathname}${urlObjectAfterAlias.search}`
34
24
  redirectRequest({
35
- ressourceBeforeAlias: request.ressource,
25
+ ressourceBeforeAlias,
36
26
  ressource,
37
27
  })
38
28
  },
@@ -40,16 +30,15 @@ export const pluginRessourceAliases = (ressourceAliases) => {
40
30
  }
41
31
  }
42
32
 
43
- const replaceUrlRessource = (url, ressource) => {
44
- const urlObject = new URL(url)
33
+ const asFileUrl = (specifier) => new URL(specifier, "file:///").href
45
34
 
46
- const searchSeparatorIndex = ressource.indexOf("?")
47
- if (searchSeparatorIndex === -1) {
48
- urlObject.pathname = ressource
49
- return urlObject
35
+ const replaceRessource = (ressourceBeforeAlias, newValue) => {
36
+ const urlObject = new URL(ressourceBeforeAlias, "file://")
37
+ const searchSeparatorIndex = newValue.indexOf("?")
38
+ if (searchSeparatorIndex > -1) {
39
+ return newValue // let new value override search params
50
40
  }
51
-
52
- const pathname = ressource.slice(0, searchSeparatorIndex)
53
- urlObject.pathname = pathname
54
- return urlObject
41
+ urlObject.pathname = newValue
42
+ const ressource = `${urlObject.pathname}${urlObject.search}`
43
+ return ressource
55
44
  }
@@ -23,7 +23,7 @@ import { composeTwoResponses } from "./internal/response_composition.js"
23
23
  import { listenRequest } from "./internal/listenRequest.js"
24
24
  import { listenServerConnectionError } from "./internal/listenServerConnectionError.js"
25
25
  import { memoize } from "./internal/memoize.js"
26
- import { jsenvServerInternalErrorToResponse } from "./jsenvServerInternalErrorToResponse.js"
26
+ import { applyDefaultErrorToResponse } from "./error_to_response_default.js"
27
27
  import {
28
28
  STOP_REASON_INTERNAL_ERROR,
29
29
  STOP_REASON_PROCESS_SIGHUP,
@@ -62,8 +62,8 @@ export const startServer = async ({
62
62
  requestToResponse = () => null,
63
63
  plugins = {},
64
64
 
65
- sendServerInternalErrorDetails = false,
66
- serverInternalErrorToResponse = jsenvServerInternalErrorToResponse,
65
+ sendErrorDetails = false,
66
+ errorToResponse = () => null,
67
67
 
68
68
  onListenStart = () => {},
69
69
  onListenEnd = () => {},
@@ -554,13 +554,15 @@ export const startServer = async ({
554
554
  // il faudrais pouvoir stop que les autres response ?
555
555
  stop(STOP_REASON_INTERNAL_ERROR)
556
556
  }
557
- const propertiesFromError = await serverInternalErrorToResponse(
558
- error,
559
- {
557
+ const responseDescriptionFromError =
558
+ (await errorToResponse(error, {
560
559
  request,
561
- sendServerInternalErrorDetails,
562
- },
563
- )
560
+ sendErrorDetails,
561
+ })) ||
562
+ (await applyDefaultErrorToResponse(error, {
563
+ request,
564
+ sendErrorDetails,
565
+ }))
564
566
  addRequestLog(requestNode, {
565
567
  type: "error",
566
568
  value: createDetailedMessage(
@@ -580,7 +582,7 @@ export const startServer = async ({
580
582
  "content-type": "text/plain",
581
583
  },
582
584
  },
583
- propertiesFromError,
585
+ responseDescriptionFromError,
584
586
  )
585
587
  }
586
588