@dunx/http 2.2.0 → 2.3.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.
@@ -0,0 +1,27 @@
1
+ export declare const REQUEST_ID_HEADER = "x-request-id";
2
+ /**
3
+ * The request id, and the only thing that decides a request has one.
4
+ *
5
+ * `RequestLoggingMiddleware` sets the header on a response it returns, and a
6
+ * failure is never one: `buildRoutes` and `buildFallback` catch outside the chain
7
+ * and build a fresh `Response` from the error mapper. So a guard's 401, a
8
+ * validation 400, a mapped 500 and every unmatched 404 went out with no id on
9
+ * them, which are the responses a caller most needs in order to find the log line
10
+ * the middleware just wrote.
11
+ *
12
+ * Recorded against the request rather than threaded through the mapper, because
13
+ * `ErrorMapper` is `(error, req) => Response` and an app writes its own.
14
+ * {@link stamp} then reads back whatever {@link assign} recorded, so an app that
15
+ * turned request logging off, or a path it told the middleware to ignore, is still
16
+ * answered without a header: nothing minted an id, so there is none to stamp.
17
+ */
18
+ export declare class RequestIds {
19
+ /**
20
+ * Called by `RequestLoggingMiddleware` and by nothing else. Splitting minting
21
+ * from recording would let a second caller invent an id the log line does not
22
+ * carry.
23
+ */
24
+ static assign(req: Request): string;
25
+ /** The response, with this request's id on it if it was ever given one. */
26
+ static stamp(response: Response, req: Request): Response;
27
+ }
@@ -2,7 +2,6 @@ import { Logger, RequestContext } from '@dunx/core';
2
2
  import type { BunRequest } from 'bun';
3
3
  import type { RouteContext } from './context.js';
4
4
  import type { Middleware, Next } from './middleware.js';
5
- export declare const REQUEST_ID_HEADER = "x-request-id";
6
5
  export interface RequestLoggingOptions {
7
6
  /** Bodies past this many characters are logged as a size. Default 2048. `0` omits them. */
8
7
  readonly maxBodyLength?: number;
@@ -25,6 +25,11 @@ export interface WebSocketRuntime {
25
25
  * "Consuming N job(s)" entry already set.
26
26
  */
27
27
  readonly gateways: readonly GatewaySummary[];
28
+ /**
29
+ * What `HttpFactory.create` logs at boot, the way the container logs its own
30
+ * scope warnings. Empty for a server that reports socket errors, or says it does.
31
+ */
32
+ readonly warnings: readonly string[];
28
33
  }
29
34
  export interface GatewaySummary {
30
35
  readonly name: string;
@@ -62,6 +62,8 @@ export declare class SocketLoggingMiddleware implements SocketMiddleware {
62
62
  #private;
63
63
  private readonly logger;
64
64
  private readonly context;
65
+ /** A throwing handler reaches the `Logger` here, at `errorLevel`. */
66
+ readonly reportsErrors = true;
65
67
  constructor(logger: Logger, context: RequestContext, options?: SocketLoggingOptions);
66
68
  handle(frame: SocketFrame, ctx: SocketContext, next: SocketNext): unknown;
67
69
  }
@@ -59,6 +59,21 @@ export type SocketNext = () => unknown;
59
59
  * which is an HTTP request answered by the gateway's own route.
60
60
  */
61
61
  export interface SocketMiddleware {
62
+ /**
63
+ * That a failure passing through here is reported somewhere. Default
64
+ * **`false`**.
65
+ *
66
+ * `SocketOptions.onError`'s `console.error` fallback is not installed while any
67
+ * socket middleware exists, because a middleware wraps the handler and would
68
+ * report the same failure a second time. Whether it does is something only the
69
+ * middleware knows: one that ignores a throw turns error reporting off for the
70
+ * whole server, and nothing about the wiring says so.
71
+ *
72
+ * Setting it is how a middleware says it does report. Leaving it unset with no
73
+ * `websocket.onError` beside it is what `HttpFactory.create` warns about at
74
+ * boot.
75
+ */
76
+ readonly reportsErrors?: boolean;
62
77
  handle(frame: SocketFrame, ctx: SocketContext, next: SocketNext): unknown;
63
78
  }
64
79
  /** One slot's folded chain. The handler's own arguments ride in `run`. */
@@ -35,6 +35,11 @@ export type SocketOptions = Readonly<Pick<WebSocketHandler<SocketData>, 'backpre
35
35
  * The default is **not** installed when `socketMiddleware` is non-empty: a
36
36
  * middleware wraps the handler, so it already saw the failure and a second
37
37
  * report on the console would be a duplicate.
38
+ *
39
+ * Seeing a failure and reporting it are not the same thing, so a middleware that
40
+ * reports says so with `SocketMiddleware.reportsErrors`. Middleware that sets it
41
+ * nowhere, and no `onError` here, is a boot warning: the fallback is gone and
42
+ * nothing replaced it.
38
43
  */
39
44
  readonly onError?: SocketErrorHandler;
40
45
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dunx/http",
3
- "version": "2.2.0",
3
+ "version": "2.3.0",
4
4
  "description": "Bun.serve adapter for the dunx framework: controllers, middleware and WebSocket gateways",
5
5
  "keywords": [
6
6
  "bun",
@@ -58,7 +58,7 @@
58
58
  "@dunx/core": "workspace:*"
59
59
  },
60
60
  "peerDependencies": {
61
- "@dunx/core": "^2.2.0",
61
+ "@dunx/core": "^2.3.0",
62
62
  "@types/bun": ">=1.3.0"
63
63
  },
64
64
  "peerDependenciesMeta": {