@nodefony/http 10.0.0-alpha.8 → 10.0.0-beta.1

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 (98) hide show
  1. package/README.md +7 -0
  2. package/dist/_virtual/{_@oxc-project_runtime@0.150.0 → _@oxc-project_runtime@0.151.0}/helpers/esm/decorate.js +1 -1
  3. package/dist/_virtual/{_@oxc-project_runtime@0.150.0 → _@oxc-project_runtime@0.151.0}/helpers/esm/decorateMetadata.js +1 -1
  4. package/dist/_virtual/{_@oxc-project_runtime@0.150.0 → _@oxc-project_runtime@0.151.0}/helpers/esm/decorateParam.js +1 -1
  5. package/dist/index.js +6 -4
  6. package/dist/nodefony/command/assetsPublishCommand.js +1 -1
  7. package/dist/nodefony/command/certificatesCommand.js +1 -1
  8. package/dist/nodefony/command/networkCommand.js +1 -1
  9. package/dist/nodefony/command/proxyGenerateCommand.js +1 -1
  10. package/dist/nodefony/config/config.js +22 -1
  11. package/dist/nodefony/interfaces/IRouting.js +1 -0
  12. package/dist/nodefony/interfaces/ISecurity.js +1 -0
  13. package/dist/nodefony/service/ProfilerAdminApi.js +2 -1
  14. package/dist/nodefony/service/audit-logger.js +16 -13
  15. package/dist/nodefony/service/certificates.js +25 -13
  16. package/dist/nodefony/service/error-renderer.js +118 -5
  17. package/dist/nodefony/service/http-kernel.js +342 -165
  18. package/dist/nodefony/service/pretty-request-logger.js +3 -10
  19. package/dist/nodefony/service/servers/clientError.js +2 -2
  20. package/dist/nodefony/service/servers/server-http.js +23 -23
  21. package/dist/nodefony/service/servers/server-https.js +41 -42
  22. package/dist/nodefony/service/servers/server-static.js +13 -17
  23. package/dist/nodefony/service/servers/server-websocket-secure.js +11 -10
  24. package/dist/nodefony/service/servers/server-websocket.js +11 -10
  25. package/dist/nodefony/service/servers/wsHeartbeat.js +2 -2
  26. package/dist/nodefony/service/sessions/sessions-service.js +25 -17
  27. package/dist/nodefony/service/trace.js +1 -1
  28. package/dist/nodefony/service/upload/upload-service.js +11 -10
  29. package/dist/nodefony/src/assets/prebuiltUi.js +1 -1
  30. package/dist/nodefony/src/context/Context.js +34 -19
  31. package/dist/nodefony/src/context/forwarded.js +4 -4
  32. package/dist/nodefony/src/context/http/HttpContext.js +133 -88
  33. package/dist/nodefony/src/context/http/Request.js +93 -44
  34. package/dist/nodefony/src/context/http/Response.js +107 -51
  35. package/dist/nodefony/src/context/http/parser.js +9 -10
  36. package/dist/nodefony/src/context/http/urlFastPath.js +1 -2
  37. package/dist/nodefony/src/context/http2/Response.js +53 -25
  38. package/dist/nodefony/src/context/metaData.js +1 -1
  39. package/dist/nodefony/src/context/trustProxy.js +4 -3
  40. package/dist/nodefony/src/context/websocket/Response.js +13 -6
  41. package/dist/nodefony/src/context/websocket/WebsocketContext.js +59 -26
  42. package/dist/nodefony/src/context/websocket/wsCloseReason.js +41 -0
  43. package/dist/nodefony/src/cookies/cookie.js +3 -3
  44. package/dist/nodefony/src/errors/httpError.js +6 -6
  45. package/dist/nodefony/src/errors/thrownMessage.js +27 -0
  46. package/dist/nodefony/src/profiler/FrameProfile.js +4 -3
  47. package/dist/nodefony/src/profiler/Profiler.js +4 -4
  48. package/dist/nodefony/src/servers/kernelServers.js +29 -0
  49. package/dist/nodefony/src/servers/portBinder.js +8 -21
  50. package/dist/nodefony/src/session/session.js +18 -10
  51. package/dist/nodefony/src/session/sessionStoreFailure.js +2 -1
  52. package/dist/nodefony/src/session/storage/RevocationGuardStorage.js +24 -9
  53. package/dist/types/index.d.ts +16 -0
  54. package/dist/types/nodefony/config/config.d.ts +22 -0
  55. package/dist/types/nodefony/interfaces/IContext.d.ts +24 -7
  56. package/dist/types/nodefony/interfaces/ICookie.d.ts +18 -18
  57. package/dist/types/nodefony/interfaces/IHttpKernel.d.ts +10 -4
  58. package/dist/types/nodefony/interfaces/IResponse.d.ts +1 -1
  59. package/dist/types/nodefony/interfaces/IRouting.d.ts +87 -0
  60. package/dist/types/nodefony/interfaces/ISecurity.d.ts +45 -0
  61. package/dist/types/nodefony/interfaces/ISession.d.ts +8 -8
  62. package/dist/types/nodefony/interfaces/IUpload.d.ts +9 -9
  63. package/dist/types/nodefony/interfaces/index.d.ts +2 -0
  64. package/dist/types/nodefony/service/audit-logger.d.ts +14 -10
  65. package/dist/types/nodefony/service/certificates.d.ts +10 -10
  66. package/dist/types/nodefony/service/error-renderer.d.ts +14 -0
  67. package/dist/types/nodefony/service/http-kernel.d.ts +192 -42
  68. package/dist/types/nodefony/service/servers/server-http.d.ts +4 -1
  69. package/dist/types/nodefony/service/servers/server-https.d.ts +4 -1
  70. package/dist/types/nodefony/service/servers/server-websocket-secure.d.ts +4 -1
  71. package/dist/types/nodefony/service/servers/server-websocket.d.ts +4 -1
  72. package/dist/types/nodefony/service/sessions/sessions-service.d.ts +6 -2
  73. package/dist/types/nodefony/service/upload/upload-service.d.ts +1 -1
  74. package/dist/types/nodefony/src/context/Context.d.ts +21 -10
  75. package/dist/types/nodefony/src/context/forwarded.d.ts +3 -3
  76. package/dist/types/nodefony/src/context/http/HttpContext.d.ts +75 -18
  77. package/dist/types/nodefony/src/context/http/Request.d.ts +39 -2
  78. package/dist/types/nodefony/src/context/http/Response.d.ts +47 -7
  79. package/dist/types/nodefony/src/context/http/parser.d.ts +1 -1
  80. package/dist/types/nodefony/src/context/http2/Response.d.ts +32 -2
  81. package/dist/types/nodefony/src/context/websocket/Response.d.ts +4 -4
  82. package/dist/types/nodefony/src/context/websocket/WebsocketContext.d.ts +11 -2
  83. package/dist/types/nodefony/src/context/websocket/wsCloseReason.d.ts +21 -0
  84. package/dist/types/nodefony/src/cookies/cookie.d.ts +9 -9
  85. package/dist/types/nodefony/src/errors/httpError.d.ts +7 -7
  86. package/dist/types/nodefony/src/errors/thrownMessage.d.ts +12 -0
  87. package/dist/types/nodefony/src/profiler/Profiler.d.ts +28 -28
  88. package/dist/types/nodefony/src/servers/kernelServers.d.ts +20 -0
  89. package/dist/types/nodefony/src/servers/portBinder.d.ts +6 -19
  90. package/dist/types/nodefony/src/session/session.d.ts +12 -12
  91. package/dist/types/nodefony/src/session/storage/RevocationGuardStorage.d.ts +1 -1
  92. package/docs/cookies.md +25 -25
  93. package/docs/observabilite.md +30 -30
  94. package/docs/rate-limit.md +22 -22
  95. package/docs/servers.md +61 -61
  96. package/docs/session.md +82 -77
  97. package/docs/upload.md +43 -37
  98. package/package.json +11 -11
@@ -1,6 +1,5 @@
1
- import { severityFromStatus } from "./audit-logger.js";
1
+ import { computeDurationMs, severityFromStatus } from "./audit-logger.js";
2
2
  import { logColor } from "nodefony";
3
- import { performance } from "node:perf_hooks";
4
3
  //#region nodefony/service/pretty-request-logger.ts
5
4
  /**
6
5
  * Pretty single-line logger for dev (P3.2) — the biggest gain for humans.
@@ -28,7 +27,7 @@ var PrettyRequestLogger = class {
28
27
  const method = ctx.method ?? "?";
29
28
  const duration = computeDurationMs(ctx.phases);
30
29
  return {
31
- text: `${logColor.cyan(method.padEnd(4))} ${colorizeStatus(status)} ${ctx.url} ${logColor.blackBright(formatDuration(duration))} ${logColor.blackBright(ctx.remoteAddress ?? "-")} ${logColor.magenta(`[${shortId(ctx.requestId)}]`)}` + (err ? ` ${logColor.red(err.message)}` : ""),
30
+ text: `${logColor.cyan(method.padEnd(4))} ${colorizeStatus(status)} ${ctx.url} ${logColor.blackBright(formatDuration(duration))} ${logColor.blackBright(ctx.remoteAddress ?? "-")} ` + logColor.magenta(`[${shortId(ctx.requestId)}]`) + (err ? ` ${logColor.red(err.message)}` : ""),
32
31
  severity: severityFromStatus(status),
33
32
  msgid: "req"
34
33
  };
@@ -39,7 +38,7 @@ var PrettyRequestLogger = class {
39
38
  const duration = computeDurationMs(ctx.phases);
40
39
  const proto = acceptedProtocol ? `[${acceptedProtocol}]` : "";
41
40
  return {
42
- text: `${logColor.cyan("WS ")} ${colorizeStatus(status)} ${ctx.url} ${logColor.blackBright(proto)} ${logColor.blackBright(formatDuration(duration))} ${logColor.blackBright(ctx.remoteAddress ?? "-")} ${logColor.magenta(`[${shortId(ctx.requestId)}]`)}` + (error ? ` ${logColor.red(error.message)}` : ""),
41
+ text: `${logColor.cyan("WS ")} ${colorizeStatus(status)} ${ctx.url} ${logColor.blackBright(proto)} ${logColor.blackBright(formatDuration(duration))} ${logColor.blackBright(ctx.remoteAddress ?? "-")} ` + logColor.magenta(`[${shortId(ctx.requestId)}]`) + (error ? ` ${logColor.red(error.message)}` : ""),
43
42
  severity: error ? "ERROR" : "INFO",
44
43
  msgid: "req"
45
44
  };
@@ -62,11 +61,5 @@ function formatDuration(ms) {
62
61
  function shortId(id) {
63
62
  return id.length > 8 ? id.slice(0, 8) : id;
64
63
  }
65
- function computeDurationMs(phases) {
66
- if (!phases.length) return null;
67
- const first = phases[0];
68
- if (typeof first.startMs !== "number") return null;
69
- return performance.now() - first.startMs;
70
- }
71
64
  //#endregion
72
65
  export { PrettyRequestLogger as default };
@@ -12,8 +12,8 @@
12
12
  * @param socket - flux client brut (l'event `clientError` fournit un `Duplex`).
13
13
  */
14
14
  function handleClientError(error, socket) {
15
- if (error?.code === "ECONNRESET" || !socket.writable) return;
16
- const statusLine = error?.code === "HPE_HEADER_OVERFLOW" ? "431 Request Header Fields Too Large" : "400 Bad Request";
15
+ if (error.code === "ECONNRESET" || !socket.writable) return;
16
+ const statusLine = error.code === "HPE_HEADER_OVERFLOW" ? "431 Request Header Fields Too Large" : "400 Bad Request";
17
17
  socket.end(`HTTP/1.1 ${statusLine}\r\nConnection: close\r\n\r\n`);
18
18
  }
19
19
  //#endregion
@@ -1,10 +1,11 @@
1
- import __decorateMetadata from "../../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateMetadata.js";
2
- import __decorate from "../../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorate.js";
1
+ import { asServersConfig, configuredServerPort } from "../../src/servers/kernelServers.js";
2
+ import __decorateMetadata from "../../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
3
+ import __decorate from "../../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
3
4
  import http_kernel_default from "../http-kernel.js";
4
5
  import { handleClientError } from "./clientError.js";
5
6
  import { createDrainTerminator } from "./serverShutdown.js";
6
7
  import { bindWithFallback, buildBindPlan } from "../../src/servers/portBinder.js";
7
- import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateParam.js";
8
+ import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateParam.js";
8
9
  import { Module, Service, extend, inject, nodefonyError } from "nodefony";
9
10
  import http from "node:http";
10
11
  //#region nodefony/service/servers/server-http.ts
@@ -27,13 +28,12 @@ let ServerHttp = class ServerHttp extends Service {
27
28
  super("server-http", module.container, module.notificationsCenter, module.options.http);
28
29
  this.httpKernel = httpKernel;
29
30
  this.module = module;
30
- this.active = !!module.kernel?.options.servers.http;
31
+ this.active = !!asServersConfig(module.kernel?.options.servers)?.http;
31
32
  this.port = this.setPort();
32
33
  this.domain = this.module.kernel?.domain;
33
34
  }
34
35
  setPort() {
35
- if (this.module.kernel?.options.servers?.http) return this.module.kernel?.options.servers?.http?.port || 0;
36
- return 0;
36
+ return configuredServerPort(asServersConfig(this.module.kernel?.options.servers), "http") ?? 0;
37
37
  }
38
38
  createServer() {
39
39
  return new Promise((resolve, reject) => {
@@ -42,23 +42,19 @@ let ServerHttp = class ServerHttp extends Service {
42
42
  const opt = extend({ requestTimeout: this.options.requestTimeout });
43
43
  this.server = http.createServer(opt);
44
44
  this.httpTerminator = createDrainTerminator(this.server, this.options.shutdownTimeout);
45
- if (this.options.maxHeadersCount) {
46
- if (this.server) this.server.maxHeadersCount = this.options.maxHeadersCount;
47
- }
45
+ if (this.options.maxHeadersCount) this.server.maxHeadersCount = this.options.maxHeadersCount;
48
46
  if (this.options.timeout) {
49
- if (this.server) {
50
- this.server.setTimeout(this.options.timeout, () => {
51
- this.fire("onTimeout", this);
52
- });
53
- this.server.timeout = this.options.timeout;
54
- }
47
+ this.server.setTimeout(this.options.timeout, () => {
48
+ this.fire("onTimeout", this);
49
+ });
50
+ this.server.timeout = this.options.timeout;
55
51
  }
56
- if (this.options.keepAliveTimeout) {
57
- if (this.server) this.server.keepAliveTimeout = this.options.keepAliveTimeout;
58
- }
59
- this.server.on("request", (request, response) => this.httpKernel?.onHttpRequest(request, response, this.type).catch(() => {}));
52
+ if (this.options.keepAliveTimeout) this.server.keepAliveTimeout = this.options.keepAliveTimeout;
53
+ this.server.on("request", (request, response) => {
54
+ this.httpKernel.onHttpRequest(request, response, this.type);
55
+ });
60
56
  this.module.fire("onCreateServer", this.type, this);
61
- bindWithFallback(this.server, this.domain, buildBindPlan("http", this.module.kernel?.options.servers, this.module.kernel?.environment)).then(({ address, shiftedFrom }) => {
57
+ bindWithFallback(this.server, this.domain, buildBindPlan("http", asServersConfig(this.module.kernel?.options.servers), this.module.kernel?.environment)).then(({ address, shiftedFrom }) => {
62
58
  this.infos = address;
63
59
  this.port = address.port;
64
60
  this.address = address.address;
@@ -68,7 +64,8 @@ let ServerHttp = class ServerHttp extends Service {
68
64
  this.module.fire("onServersReady", this.type, this);
69
65
  this.attachErrorHandler();
70
66
  resolve(this.server);
71
- }).catch((error) => {
67
+ }).catch((e) => {
68
+ const error = e instanceof Error ? e : new Error(String(e));
72
69
  this.reportBindError(error);
73
70
  reject(error);
74
71
  });
@@ -87,7 +84,7 @@ let ServerHttp = class ServerHttp extends Service {
87
84
  });
88
85
  } catch (e) {
89
86
  this.log(e, "CRITIC");
90
- return reject(e);
87
+ return reject(e instanceof Error ? e : new Error(String(e)));
91
88
  }
92
89
  });
93
90
  }
@@ -120,10 +117,13 @@ let ServerHttp = class ServerHttp extends Service {
120
117
  this.log(`Port ${this.port} déjà occupé (domaine ${this.domain}) — le serveur HTTP ne peut pas écouter. Libérer le port, en choisir un autre (servers.http.port), ou autoriser le repli automatique (servers.portPolicy = "auto", défaut en développement).`, "ERROR");
121
118
  this.log(myError, "CRITIC");
122
119
  break;
120
+ case void 0:
123
121
  default: this.log(myError, "CRITIC");
124
122
  }
125
123
  this.server?.close();
126
- setTimeout(() => this.kernel?.terminate(1), 1e3);
124
+ setTimeout(() => {
125
+ this.kernel?.terminate(1);
126
+ }, 1e3);
127
127
  }
128
128
  showBanner() {
129
129
  if (this.infos) this.log(`Server Listen on ${this.scheme}://${this.infos.address}:${this.infos.port} Family: ${this.infos.family} Protocol : ${this.protocol}`);
@@ -1,10 +1,11 @@
1
- import __decorateMetadata from "../../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateMetadata.js";
2
- import __decorate from "../../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorate.js";
1
+ import { asServersConfig, configuredServerPort } from "../../src/servers/kernelServers.js";
2
+ import __decorateMetadata from "../../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
3
+ import __decorate from "../../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
3
4
  import http_kernel_default from "../http-kernel.js";
4
5
  import { handleClientError } from "./clientError.js";
5
6
  import { createDrainTerminator } from "./serverShutdown.js";
6
7
  import { bindWithFallback, buildBindPlan } from "../../src/servers/portBinder.js";
7
- import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateParam.js";
8
+ import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateParam.js";
8
9
  import { Module, Service, extend, inject, nodefonyError } from "nodefony";
9
10
  import http2 from "node:http2";
10
11
  import https from "node:https";
@@ -29,7 +30,7 @@ let ServerHttps = class ServerHttps extends Service {
29
30
  super("server-https", module.container, module.notificationsCenter, module.options.https);
30
31
  this.httpKernel = httpKernel;
31
32
  this.module = module;
32
- this.active = !!this.kernel?.options.servers.https;
33
+ this.active = !!asServersConfig(this.kernel?.options.servers)?.https;
33
34
  this.port = this.setPort();
34
35
  this.domain = this.kernel?.domain;
35
36
  }
@@ -38,45 +39,42 @@ let ServerHttps = class ServerHttps extends Service {
38
39
  throw new Error(`Server not found`);
39
40
  }
40
41
  setPort() {
41
- if (this.kernel?.options.servers?.https) return this.kernel?.options.servers?.https?.port || 0;
42
- return 0;
42
+ return configuredServerPort(asServersConfig(this.kernel?.options.servers), "https") ?? 0;
43
43
  }
44
44
  createServer() {
45
45
  return new Promise((resolve, reject) => {
46
46
  try {
47
47
  if (!this.active) return reject(/* @__PURE__ */ new Error(`Server https is not allowed in config file `));
48
- this.protocol = this.kernel?.options.servers.https.protocol;
48
+ const httpsCfg = asServersConfig(this.kernel?.options.servers)?.https;
49
+ const protocol = httpsCfg ? httpsCfg.protocol : void 0;
50
+ if (protocol) this.protocol = protocol;
49
51
  if (this.protocol === "2.0") return resolve(this.createServerH2());
50
52
  const opt = extend({
51
53
  requestTimeout: this.options.requestTimeout,
52
54
  rejectUnauthorized: this.options.rejectUnauthorized,
53
- key: this.httpKernel?.serviceCerticats?.key,
54
- cert: this.httpKernel?.serviceCerticats?.cert,
55
- ca: this.httpKernel?.serviceCerticats?.ca ? this.httpKernel?.serviceCerticats?.ca : void 0
55
+ key: this.httpKernel.serviceCerticats?.key,
56
+ cert: this.httpKernel.serviceCerticats?.cert,
57
+ ca: this.httpKernel.serviceCerticats?.ca ? this.httpKernel.serviceCerticats.ca : void 0
56
58
  });
57
- this.server = https.createServer(opt);
59
+ const server = https.createServer(opt);
60
+ this.server = server;
58
61
  this.httpTerminator = this.terminator();
59
62
  if (this.options.timeout) {
60
- if (this.server) {
61
- this.server.setTimeout(this.options.timeout, () => {
62
- this.fire("onTimeout", this);
63
- });
64
- this.server.timeout = this.options.timeout;
65
- }
66
- }
67
- if (this.options.maxHeadersCount) {
68
- if (this.server) this.server.maxHeadersCount = this.options.maxHeadersCount;
69
- }
70
- if (this.options.keepAliveTimeout) {
71
- if (this.server) this.server.keepAliveTimeout = this.options.keepAliveTimeout;
63
+ server.setTimeout(this.options.timeout, () => {
64
+ this.fire("onTimeout", this);
65
+ });
66
+ server.timeout = this.options.timeout;
72
67
  }
68
+ if (this.options.maxHeadersCount) server.maxHeadersCount = this.options.maxHeadersCount;
69
+ if (this.options.keepAliveTimeout) server.keepAliveTimeout = this.options.keepAliveTimeout;
73
70
  this.module.fire("onCreateServer", this.type, this);
74
- this.listenWithPolicy().then(() => resolve(this.server)).catch((error) => {
71
+ this.listenWithPolicy().then(() => resolve(this.server)).catch((e) => {
72
+ const error = e instanceof Error ? e : new Error(String(e));
75
73
  this.reportBindError(error);
76
74
  reject(error);
77
75
  });
78
76
  this.server.on("request", (request, response) => {
79
- this.httpKernel?.onHttpRequest(request, response, this.type).catch(() => {});
77
+ this.httpKernel.onHttpRequest(request, response, this.type);
80
78
  });
81
79
  this.kernel?.once("onTerminate", async () => {
82
80
  if (!this.server) return;
@@ -93,20 +91,20 @@ let ServerHttps = class ServerHttps extends Service {
93
91
  });
94
92
  } catch (e) {
95
93
  this.log(e, "CRITIC");
96
- return reject(e);
94
+ return reject(e instanceof Error ? e : new Error(String(e)));
97
95
  }
98
96
  });
99
97
  }
100
98
  createServerH2() {
101
99
  return new Promise((resolve, reject) => {
102
100
  try {
103
- const h2Cfg = (this.module?.options)?.http2 ?? {};
101
+ const h2Cfg = this.module.options.http2 ?? {};
104
102
  const opt = extend({
105
103
  allowHTTP1: true,
106
104
  rejectUnauthorized: this.options.rejectUnauthorized,
107
- key: this.httpKernel?.serviceCerticats?.key,
108
- cert: this.httpKernel?.serviceCerticats?.cert,
109
- ca: this.httpKernel?.serviceCerticats?.ca ? this.httpKernel?.serviceCerticats?.ca : void 0
105
+ key: this.httpKernel.serviceCerticats?.key,
106
+ cert: this.httpKernel.serviceCerticats?.cert,
107
+ ca: this.httpKernel.serviceCerticats?.ca ? this.httpKernel.serviceCerticats.ca : void 0
110
108
  });
111
109
  if (h2Cfg.maxSessionMemory) opt.maxSessionMemory = h2Cfg.maxSessionMemory;
112
110
  if (h2Cfg.maxConcurrentStreams) opt.settings = {
@@ -120,16 +118,14 @@ let ServerHttps = class ServerHttps extends Service {
120
118
  });
121
119
  this.server.on("request", (request, response) => {
122
120
  let alpnProtocol = false;
123
- if (request && request.stream && request.stream.session?.socket) {
124
- if (request.stream.session.socket instanceof TLSSocket) alpnProtocol = request.stream.session.socket.alpnProtocol;
125
- }
126
- if (request.socket) {
127
- if (request.socket instanceof TLSSocket) alpnProtocol = request.socket.alpnProtocol;
128
- }
129
- if (alpnProtocol === "h2") return this.httpKernel?.onHttpRequest(request, response, "http2").catch(() => {});
130
- else return this.httpKernel?.onHttpRequest(request, response, "https").catch(() => {});
121
+ const sessionSocket = request.stream?.session?.socket;
122
+ if (sessionSocket instanceof TLSSocket) alpnProtocol = sessionSocket.alpnProtocol;
123
+ if (request.socket instanceof TLSSocket) alpnProtocol = request.socket.alpnProtocol;
124
+ if (alpnProtocol === "h2") this.httpKernel.onHttpRequest(request, response, "http2");
125
+ else this.httpKernel.onHttpRequest(request, response, "https");
131
126
  });
132
- this.listenWithPolicy().then(() => resolve(this.server)).catch((error) => {
127
+ this.listenWithPolicy().then(() => resolve(this.server)).catch((e) => {
128
+ const error = e instanceof Error ? e : new Error(String(e));
133
129
  this.reportBindError(error);
134
130
  reject(error);
135
131
  });
@@ -149,7 +145,7 @@ let ServerHttps = class ServerHttps extends Service {
149
145
  this.log(error, "ERROR", "HTTP2 Server streamError");
150
146
  });
151
147
  } catch (e) {
152
- return reject(e);
148
+ return reject(e instanceof Error ? e : new Error(String(e)));
153
149
  }
154
150
  });
155
151
  }
@@ -161,7 +157,7 @@ let ServerHttps = class ServerHttps extends Service {
161
157
  * `EADDRINUSE` de repli, qui ne sont pas des pannes).
162
158
  */
163
159
  async listenWithPolicy() {
164
- const { address, shiftedFrom } = await bindWithFallback(this.server, this.domain, buildBindPlan("https", this.module.kernel?.options.servers, this.module.kernel?.environment));
160
+ const { address, shiftedFrom } = await bindWithFallback(this.server, this.domain, buildBindPlan("https", asServersConfig(this.module.kernel?.options.servers), this.module.kernel?.environment));
165
161
  this.infos = address;
166
162
  this.port = address.port;
167
163
  this.address = address.address;
@@ -189,10 +185,13 @@ let ServerHttps = class ServerHttps extends Service {
189
185
  this.log(`Port ${this.port} déjà occupé (domaine ${this.domain}) — le serveur HTTPS ne peut pas écouter. Libérer le port, en choisir un autre (servers.https.port), ou autoriser le repli automatique (servers.portPolicy = "auto", défaut en développement).`, "ERROR");
190
186
  this.log(myError, "CRITIC");
191
187
  break;
188
+ case void 0:
192
189
  default: this.log(myError, "CRITIC");
193
190
  }
194
191
  this.server?.close();
195
- setTimeout(() => this.kernel?.terminate(1), 1e3);
192
+ setTimeout(() => {
193
+ this.kernel?.terminate(1);
194
+ }, 1e3);
196
195
  }
197
196
  showBanner() {
198
197
  if (this.infos) this.log(`Server Listen on ${this.scheme}://${this.infos.address}:${this.infos.port} Family: ${this.infos.family} Protocol : ${this.protocol}`);
@@ -1,6 +1,6 @@
1
1
  import { Service, extend } from "nodefony";
2
- import { URL } from "node:url";
3
2
  import http from "node:http";
3
+ import { URL } from "node:url";
4
4
  import { existsSync } from "node:fs";
5
5
  import { join } from "node:path";
6
6
  import mime from "mime-types";
@@ -25,7 +25,7 @@ var Statics = class extends Service {
25
25
  enabled = true;
26
26
  defaultOptions = defaultOptions;
27
27
  constructor(module) {
28
- const container = module.container || void 0;
28
+ const container = module.container ?? void 0;
29
29
  const options = module.options.statics || {};
30
30
  let event;
31
31
  if (container) event = container.get("notificationsCenter");
@@ -68,10 +68,9 @@ var Statics = class extends Service {
68
68
  if (!modules) return;
69
69
  const frontend = this.container?.get("frontend");
70
70
  const frontManaged = frontend?.listEntries ? new Set(frontend.listEntries().map((e) => e.moduleName)) : null;
71
- for (const name in modules) {
72
- const mod = modules[name];
73
- if (!mod || mod.isApp) continue;
74
- const cfg = mod.options?.publicMount;
71
+ for (const mod of Object.values(modules)) {
72
+ if (mod.isApp) continue;
73
+ const cfg = mod.options.publicMount;
75
74
  if (cfg === false) continue;
76
75
  if (cfg == null && frontManaged?.has(mod.name)) continue;
77
76
  const dir = join(mod.path, cfg?.dir || "public");
@@ -82,10 +81,10 @@ var Statics = class extends Service {
82
81
  }
83
82
  initStaticFiles() {
84
83
  for (const staticRoot in this.options) {
85
- let Path = this.options[staticRoot].path;
86
- Path = this.kernel?.checkPath(Path);
84
+ const root = this.options[staticRoot];
85
+ const Path = this.kernel?.checkPath(root.path);
87
86
  let setHeaders = null;
88
- const opt = this.options[staticRoot].options || {};
87
+ const opt = root.options ?? {};
89
88
  if (opt.setHeaders) {
90
89
  if (typeof opt.setHeaders === "function") {
91
90
  setHeaders = opt.setHeaders;
@@ -97,7 +96,7 @@ var Statics = class extends Service {
97
96
  this.fire("onServeStatic", res, path, staticRoot, this);
98
97
  };
99
98
  if (setHeaders) this.on("onServeStatic", setHeaders);
100
- this.addDirectory(Path, opt);
99
+ this.addDirectory(Path ?? "", opt);
101
100
  }
102
101
  }
103
102
  /**
@@ -147,11 +146,11 @@ var Statics = class extends Service {
147
146
  getUrl(request) {
148
147
  let scheme, host;
149
148
  if (request instanceof http.IncomingMessage) {
150
- scheme = request.connection instanceof tls.TLSSocket && request.connection.encrypted ? "https" : "http";
149
+ scheme = request.socket instanceof tls.TLSSocket ? "https" : "http";
151
150
  host = request.headers.host;
152
151
  return scheme + "://" + host;
153
152
  } else if (request instanceof http2.Http2ServerRequest) {
154
- scheme = request.socket instanceof tls.TLSSocket && request.socket.encrypted ? "https" : "http";
153
+ scheme = request.socket instanceof tls.TLSSocket ? "https" : "http";
155
154
  host = request.headers[":authority"];
156
155
  return scheme + "://" + host;
157
156
  }
@@ -172,18 +171,15 @@ var Statics = class extends Service {
172
171
  request.url = raw;
173
172
  } catch (e) {
174
173
  request.url = raw;
175
- return Promise.reject(e);
174
+ throw e;
176
175
  }
177
176
  break;
178
177
  }
179
178
  }
180
- for (const server in this.servers) try {
181
- let ele = this.servers[server];
179
+ for (const ele of Object.values(this.servers)) {
182
180
  await this.getStatic(ele, request, response);
183
181
  const type = mime.lookup(pathname);
184
182
  response.setHeader("Content-Type", type);
185
- } catch (e) {
186
- return Promise.reject(e);
187
183
  }
188
184
  return Promise.resolve(response);
189
185
  }
@@ -1,7 +1,8 @@
1
- import __decorateMetadata from "../../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateMetadata.js";
2
- import __decorate from "../../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorate.js";
1
+ import { asServersConfig, configuredServerPort } from "../../src/servers/kernelServers.js";
2
+ import __decorateMetadata from "../../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
3
+ import __decorate from "../../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
3
4
  import http_kernel_default from "../http-kernel.js";
4
- import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateParam.js";
5
+ import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateParam.js";
5
6
  import { startHeartbeat, trackPong } from "./wsHeartbeat.js";
6
7
  import { Module, Service, inject } from "nodefony";
7
8
  import Ws, { WebSocketServer } from "ws";
@@ -30,13 +31,13 @@ let WebsocketSecure = class WebsocketSecure extends Service {
30
31
  this.ready = false;
31
32
  }
32
33
  setPort() {
33
- if (this.kernel?.options.servers?.https) return this.kernel?.options.servers?.https?.port || 0;
34
- return 0;
34
+ return configuredServerPort(asServersConfig(this.kernel?.options.servers), "https") ?? 0;
35
35
  }
36
36
  async createServer(serverHttps) {
37
37
  return new Promise((resolve, reject) => {
38
38
  try {
39
- this.infos = serverHttps.server.address();
39
+ const address = serverHttps.server.address();
40
+ this.infos = typeof address === "object" ? address : null;
40
41
  if (this.infos) {
41
42
  this.port = this.infos.port;
42
43
  this.address = this.infos.address;
@@ -44,19 +45,19 @@ let WebsocketSecure = class WebsocketSecure extends Service {
44
45
  this.protocol = serverHttps.protocol;
45
46
  }
46
47
  this.server = new WebSocketServer({
47
- ...this.options ?? {},
48
+ ...this.options,
48
49
  server: serverHttps.server,
49
50
  clientTracking: true
50
51
  });
51
52
  this.server.on("connection", this.onConnection.bind(this));
52
53
  this.heartbeatTimer = startHeartbeat(this.server, this.options);
53
54
  this.kernel?.prependOnceListener("onTerminate", this.terminate.bind(this));
54
- if (this.server) this.ready = true;
55
+ this.ready = true;
55
56
  this.module.fire("onServersReady", this.type, this);
56
57
  return resolve(this.server);
57
58
  } catch (e) {
58
59
  this.log(e, "ERROR");
59
- return reject(e);
60
+ return reject(e instanceof Error ? e : new Error(String(e)));
60
61
  }
61
62
  });
62
63
  }
@@ -86,7 +87,7 @@ let WebsocketSecure = class WebsocketSecure extends Service {
86
87
  this.log(` SHUTDOWN WEBSOCKET Server is listening on DOMAIN : ${this.domain} PORT : ${this.port}`, "INFO");
87
88
  return resolve(true);
88
89
  } catch (e) {
89
- return reject(e);
90
+ return reject(e instanceof Error ? e : new Error(String(e)));
90
91
  }
91
92
  }, 300);
92
93
  return;
@@ -1,7 +1,8 @@
1
- import __decorateMetadata from "../../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateMetadata.js";
2
- import __decorate from "../../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorate.js";
1
+ import { asServersConfig, configuredServerPort } from "../../src/servers/kernelServers.js";
2
+ import __decorateMetadata from "../../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
3
+ import __decorate from "../../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
3
4
  import http_kernel_default from "../http-kernel.js";
4
- import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateParam.js";
5
+ import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateParam.js";
5
6
  import { startHeartbeat, trackPong } from "./wsHeartbeat.js";
6
7
  import { Module, Service, inject } from "nodefony";
7
8
  import Ws, { WebSocketServer } from "ws";
@@ -30,13 +31,13 @@ let Websocket = class Websocket extends Service {
30
31
  this.ready = false;
31
32
  }
32
33
  setPort() {
33
- if (this.kernel?.options.servers?.http) return this.kernel?.options.servers?.http?.port || 0;
34
- return 0;
34
+ return configuredServerPort(asServersConfig(this.kernel?.options.servers), "http") ?? 0;
35
35
  }
36
36
  async createServer(serverHttp) {
37
37
  return new Promise((resolve, reject) => {
38
38
  try {
39
- this.infos = serverHttp.server.address();
39
+ const address = serverHttp.server.address();
40
+ this.infos = typeof address === "object" ? address : null;
40
41
  if (this.infos) {
41
42
  this.port = this.infos.port;
42
43
  this.address = this.infos.address;
@@ -44,19 +45,19 @@ let Websocket = class Websocket extends Service {
44
45
  this.protocol = serverHttp.protocol;
45
46
  }
46
47
  this.server = new WebSocketServer({
47
- ...this.options ?? {},
48
+ ...this.options,
48
49
  server: serverHttp.server,
49
50
  clientTracking: true
50
51
  });
51
52
  this.server.on("connection", this.onConnection.bind(this));
52
53
  this.heartbeatTimer = startHeartbeat(this.server, this.options);
53
54
  this.kernel?.prependOnceListener("onTerminate", this.terminate.bind(this));
54
- if (this.server) this.ready = true;
55
+ this.ready = true;
55
56
  this.module.fire("onServersReady", this.type, this);
56
57
  return resolve(this.server);
57
58
  } catch (e) {
58
59
  this.log(e, "ERROR");
59
- return reject(e);
60
+ return reject(e instanceof Error ? e : new Error(String(e)));
60
61
  }
61
62
  });
62
63
  }
@@ -86,7 +87,7 @@ let Websocket = class Websocket extends Service {
86
87
  this.log(` SHUTDOWN WEBSOCKET Server is listening on DOMAIN : ${this.domain} PORT : ${this.port}`, "INFO");
87
88
  return resolve(true);
88
89
  } catch (e) {
89
- return reject(e);
90
+ return reject(e instanceof Error ? e : new Error(String(e)));
90
91
  }
91
92
  }, 300);
92
93
  return;
@@ -46,7 +46,7 @@ const startHeartbeat = (server, options) => {
46
46
  for (const client of server.clients) {
47
47
  if (client.readyState !== Ws.OPEN) continue;
48
48
  const sock = client;
49
- if (sock._nfLastPong === void 0) sock._nfLastPong = now;
49
+ sock._nfLastPong ??= now;
50
50
  if ((sock._nfPingedAt ?? 0) > sock._nfLastPong) {
51
51
  if (now - sock._nfPingedAt > grace) client.terminate();
52
52
  continue;
@@ -57,7 +57,7 @@ const startHeartbeat = (server, options) => {
57
57
  }
58
58
  }
59
59
  }, Math.max(250, grace > 0 ? Math.min(interval, grace) : interval));
60
- timer.unref?.();
60
+ timer.unref();
61
61
  return timer;
62
62
  };
63
63
  //#endregion
@@ -1,12 +1,12 @@
1
1
  import { SESSION_FACETS } from "../../src/session/storage/sessionFilters.js";
2
- import __decorateMetadata from "../../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateMetadata.js";
3
- import __decorate from "../../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorate.js";
2
+ import __decorateMetadata from "../../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateMetadata.js";
3
+ import __decorate from "../../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorate.js";
4
4
  import http_kernel_default from "../http-kernel.js";
5
- import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateParam.js";
5
+ import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.151.0/helpers/esm/decorateParam.js";
6
6
  import Session from "../../src/session/session.js";
7
7
  import MemorySessionStorage from "../../src/session/storage/MemorySessionStorage.js";
8
8
  import RevocationGuardStorage from "../../src/session/storage/RevocationGuardStorage.js";
9
- import { AUTO_STORE, EMPTY_INFRA, GcScheduler, Module, Nodefony, RequestContext, Service, countFacets, extend, inject, injectable, readStoreLocation, resolveAutoStore, runNeedsExternalServices } from "nodefony";
9
+ import { AUTO_STORE, EMPTY_INFRA, GcScheduler, Module, Nodefony, RequestContext, Service, countFacets, extend, inject, injectable, readStoreConnector, readStoreLocation, resolveAutoStore, runNeedsExternalServices } from "nodefony";
10
10
  import { createHash, createHmac } from "node:crypto";
11
11
  //#region nodefony/service/sessions/sessions-service.ts
12
12
  var _SessionsService;
@@ -106,7 +106,8 @@ let SessionsService = class SessionsService extends Service {
106
106
  }
107
107
  /** Storage enregistré pour un store, ou `undefined`. */
108
108
  static getStorage(name) {
109
- return _SessionsService.storages.get(String(name ?? "").toLowerCase());
109
+ const key = name;
110
+ return _SessionsService.storages.get((key ?? "").toLowerCase());
110
111
  }
111
112
  /** Noms des handlers de session enregistrés. */
112
113
  static storageHandlers() {
@@ -173,11 +174,13 @@ let SessionsService = class SessionsService extends Service {
173
174
  available: _SessionsService.storageHandlers(),
174
175
  reason,
175
176
  configPath: "http.session.store",
176
- location: readStoreLocation(innerStorage)
177
+ location: readStoreLocation(innerStorage),
178
+ connector: readStoreConnector(innerStorage)
177
179
  });
178
180
  await storage.open();
181
+ const gcIntervalS = this.options.gcIntervalS;
179
182
  this.gcScheduler = new GcScheduler({
180
- intervalS: Number(this.options.gcIntervalS ?? 600),
183
+ intervalS: Number(gcIntervalS ?? 600),
181
184
  jitter: this.options.gcJitter !== false,
182
185
  run: () => this.runGc(),
183
186
  onError: (e) => this.log(e, "WARNING", "SESSION-GC")
@@ -202,8 +205,11 @@ let SessionsService = class SessionsService extends Service {
202
205
  return;
203
206
  }
204
207
  context.once("onSessionStart", (session, error) => {
205
- if (session) return resolve(session);
206
- return reject(error || /* @__PURE__ */ new Error("Bad Session"));
208
+ if (session) {
209
+ resolve(session);
210
+ return;
211
+ }
212
+ reject(error ?? /* @__PURE__ */ new Error("Bad Session"));
207
213
  });
208
214
  return;
209
215
  }
@@ -220,27 +226,29 @@ let SessionsService = class SessionsService extends Service {
220
226
  inst.readOnly = readOnly === true;
221
227
  } catch (e) {
222
228
  context.fire("onSessionStart", null, e);
223
- return reject(e);
229
+ return reject(e instanceof Error ? e : new Error(String(e)));
224
230
  }
225
231
  inst.start(context).then((session) => {
226
232
  try {
227
233
  context.session = session;
228
234
  const method = context.method;
229
235
  const request = context.request;
230
- if (method !== "WEBSOCKET" && request && request.request) request.request.session = session;
236
+ if (method !== "WEBSOCKET" && request?.request) request.request.session = session;
231
237
  context.sessionStarting = false;
232
238
  if (context.cleaned) return reject(/* @__PURE__ */ new Error("context already cleaned"));
233
239
  context.fire("onSessionStart", session, null);
234
240
  return resolve(session);
235
241
  } catch (e) {
236
- if (context.cleaned) return reject(e);
242
+ const error = e instanceof Error ? e : new Error(String(e));
243
+ if (context.cleaned) return reject(error);
237
244
  context.fire("onSessionStart", null, e);
238
- return reject(e);
245
+ return reject(error);
239
246
  }
240
247
  }).catch((err) => {
241
- if (context.cleaned) return reject(err);
248
+ const error = err instanceof Error ? err : new Error(String(err));
249
+ if (context.cleaned) return reject(error);
242
250
  context.fire("onSessionStart", null, err);
243
- return reject(err);
251
+ return reject(error);
244
252
  });
245
253
  });
246
254
  }
@@ -252,8 +260,8 @@ let SessionsService = class SessionsService extends Service {
252
260
  return session;
253
261
  }
254
262
  createSession(name, options) {
255
- options = extend({}, this.options, options);
256
- return new Session(name, options, this);
263
+ const merged = extend({}, this.options, options);
264
+ return new Session(name, merged, this);
257
265
  }
258
266
  setSessionStrategy(strategy) {
259
267
  this.sessionStrategy = strategy;