@bymax-one/nest-logger 1.0.3 → 1.0.5

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/CHANGELOG.md CHANGED
@@ -11,6 +11,110 @@ heading here.
11
11
 
12
12
  ## [Unreleased]
13
13
 
14
+ ## [1.0.5] - 2026-07-30
15
+
16
+ ### Security
17
+
18
+ - **Peer floors raised to exclude known-vulnerable NestJS versions.** `@nestjs/common ^11.0.0`
19
+ admitted 11.0.0–11.0.15, carrying [GHSA-cj7v-w2c7-cp7c](https://github.com/advisories/GHSA-cj7v-w2c7-cp7c)
20
+ (remote code execution via the `Content-Type` header, patched in 11.0.16), and
21
+ `@nestjs/core ^11.0.0` admitted everything up to 11.1.17, carrying
22
+ [GHSA-36xv-jgw5-4q75](https://github.com/advisories/GHSA-36xv-jgw5-4q75) (patched in 11.1.18).
23
+
24
+ A peer range states which versions this library supports. A floor below a published
25
+ advisory told a consumer a vulnerable install was supported, and nothing in their
26
+ tooling contradicted it — the install resolved cleanly and silently. Floors are now
27
+ `^11.0.16` and `^11.1.18`.
28
+
29
+ Shipped as a patch, which is where a security fix belongs; a minor would reach the
30
+ same installs anyway, since `^1.0.4` accepts `1.1.0` as readily as `1.0.5`. No
31
+ runtime behaviour changed.
32
+
33
+ ### Fixed
34
+
35
+ - **The custom-destination examples did not compile against `ILogDestination`.**
36
+ The published interface takes a serialized line:
37
+
38
+ ```ts
39
+ write(payload: string): void | Promise<void> // newline-terminated JSON, UTF-8
40
+ ```
41
+
42
+ All three examples in the README — `LokiDestination`, `PrismaLogDestination`,
43
+ `RollingFileDestination` — and the API reference table declared
44
+ `write(entry: LogEntry): void`, so anyone following the README to build a
45
+ destination got:
46
+
47
+ ```
48
+ TS2416: Property 'write' in type 'LokiDestination' is not assignable to the
49
+ same property in base type 'ILogDestination'.
50
+ ```
51
+
52
+ `ILogDestination` is this library's extension point, so the documentation was
53
+ teaching the wrong shape for the one thing consumers are meant to implement.
54
+ `RollingFileDestination` compounded it by re-serializing a payload that already
55
+ **is** newline-terminated JSON — anyone casting past the type error would have
56
+ written double-encoded lines to disk.
57
+
58
+ Each example now does what its own job requires rather than all three doing the
59
+ same thing: Loki buffers the line verbatim, Prisma parses because it stores
60
+ individual columns, rolling-file writes it through untouched.
61
+
62
+ - **The request-id middleware typed `req` as the global DOM `Request`**, whose
63
+ `headers` is a `Headers` instance and cannot be indexed (`TS7052`). `1.0.4`
64
+ introduced `LoggableRequest` and `LoggableResponse` for exactly this and exports
65
+ them; the README never adopted them. It does now, and narrows the
66
+ `string | string[]` a repeated header produces.
67
+
68
+ ### Added
69
+
70
+ - **`pnpm check:published`** — verifies that the README's links resolve, that its
71
+ TypeScript snippets and the type tests compile against the built package, and
72
+ that every `v*.*.*` tag has a `## [x.y.z]` CHANGELOG section. It resolves the
73
+ package through its `exports` map into `dist/`, which `test:types` cannot do:
74
+ that one maps the package to `./src` through tsconfig `paths` and so never
75
+ compiles what the README claims. Both defects above were found by it.
76
+
77
+ Runs in CI, in `release.yml`, and inside `prepublishOnly`.
78
+
79
+ ## [1.0.4] - 2026-07-29
80
+
81
+ ### Fixed
82
+
83
+ - **The published declarations no longer depend on Express's types.** The HTTP
84
+ logging interceptor, the exception filter and the request-id middleware typed
85
+ their signatures with `Request` / `Response` / `NextFunction` from `express`,
86
+ so `dist/server/index.d.ts` imported from `express` and a consumer compiling
87
+ with `skipLibCheck: false` and no express types installed hit
88
+ `error TS2307: Cannot find module 'express'`. Present since 1.0.0; the imports
89
+ were `import type` only, so runtime was never affected and no express code was
90
+ ever bundled.
91
+
92
+ They are now typed by structural contracts declaring exactly the members this
93
+ package reads — `LoggableRequest` (`headers`, `method`, `url`, `ip`,
94
+ `user?.id`), `LoggableResponse` (`statusCode`, `setHeader`, `status().json()`)
95
+ and `NextHandler`. The emitted declarations import only `@nestjs/common`,
96
+ `pino` and `rxjs`, all declared peers.
97
+
98
+ **Not a breaking change:** an Express request and response satisfy the
99
+ contracts structurally, so existing call sites keep compiling with no cast —
100
+ the parameter types only widen what is accepted. The internal
101
+ `RequestWithUser` alias is gone, replaced by `LoggableRequest`; it was never
102
+ exported.
103
+
104
+ ### Added
105
+
106
+ - `LoggableRequest`, `LoggableResponse`, `NextHandler` and `IncomingHeaders` are
107
+ exported from the package root: they type `RequestIdMiddleware.use()`, so a
108
+ consumer invoking it directly (in a test, say) can name them.
109
+
110
+ ### Removed
111
+
112
+ - The `@types/express` optional peer dependency added in 1.0.3. With the
113
+ declarations self-contained it serves no purpose — nothing in the published
114
+ types names an express symbol. It stays a devDependency: the specs build
115
+ express-shaped mocks deliberately, to prove a real express request and
116
+ response still satisfy the contracts.
117
+
14
118
  ## [1.0.3] - 2026-07-29
15
119
 
16
120
  ### Fixed
@@ -148,7 +252,9 @@ published `dist/` is identical — no runtime behaviour changes for consumers.
148
252
  - Professional CI suite: `ci.yml`, `bench.yml`, `codeql.yml`, `scorecard.yml`,
149
253
  `release.yml`, Dependabot, and issue templates
150
254
 
151
- [Unreleased]: https://github.com/bymaxone/nest-logger/compare/v1.0.3...HEAD
255
+ [Unreleased]: https://github.com/bymaxone/nest-logger/compare/v1.0.5...HEAD
256
+ [1.0.5]: https://github.com/bymaxone/nest-logger/compare/v1.0.4...v1.0.5
257
+ [1.0.4]: https://github.com/bymaxone/nest-logger/compare/v1.0.3...v1.0.4
152
258
  [1.0.3]: https://github.com/bymaxone/nest-logger/compare/v1.0.2...v1.0.3
153
259
  [1.0.2]: https://github.com/bymaxone/nest-logger/compare/v1.0.1...v1.0.2
154
260
  [1.0.1]: https://github.com/bymaxone/nest-logger/compare/v1.0.0...v1.0.1
package/README.md CHANGED
@@ -144,15 +144,13 @@ pnpm add -D pino-pretty
144
144
  # Optional — OpenTelemetry trace correlation
145
145
  pnpm add @opentelemetry/api @opentelemetry/sdk-node
146
146
 
147
- # Optional — express types, only if you compile with `skipLibCheck: false`
148
- pnpm add -D @types/express
149
147
  ```
150
148
 
151
149
  > [!NOTE]
152
150
  > `@opentelemetry/api` is resolved lazily when the Pino instance is built. When it is absent the trace mixin silently steps aside — the logger never fails to start, and never warns, over an optional peer.
153
151
 
154
152
  > [!NOTE]
155
- > `@types/express` is an **optional type-only peer**. The HTTP interceptor, the exception filter and the request-id middleware type their signatures with express's `Request` / `Response` / `NextFunction`, so the published declarations import them. Nothing needs express at runtime — no express code is bundled. You only need the types installed if you compile with `skipLibCheck: false`; with the Nest CLI default (`skipLibCheck: true`), or on a non-express adapter, you can ignore it.
153
+ > The published declarations depend on no HTTP framework's types. The HTTP interceptor, the exception filter and the request-id middleware are typed by structural contracts (`LoggableRequest`, `LoggableResponse`, `NextHandler`) that an Express request and response satisfy as-is, so nothing extra is needed even when you compile with `skipLibCheck: false`. The emitted `.d.ts` imports only `@nestjs/common`, `pino` and `rxjs`.
156
154
 
157
155
  ### 2. Register the module
158
156
 
@@ -339,15 +337,21 @@ Once active, every log entry automatically carries `traceId`, `spanId`, and `tra
339
337
  ```typescript
340
338
  // request-id.middleware.ts
341
339
  import { Injectable, NestMiddleware } from '@nestjs/common'
342
- import { LogContextService } from '@bymax-one/nest-logger'
340
+ import {
341
+ LogContextService,
342
+ type LoggableRequest,
343
+ type LoggableResponse
344
+ } from '@bymax-one/nest-logger'
343
345
  import { randomUUID } from 'node:crypto'
344
346
 
345
347
  @Injectable()
346
348
  export class RequestIdMiddleware implements NestMiddleware {
347
349
  constructor(private readonly logContext: LogContextService) {}
348
350
 
349
- use(req: Request, res: Response, next: () => void) {
350
- const requestId = req.headers['x-request-id'] ?? `r_${randomUUID()}`
351
+ use(req: LoggableRequest, res: LoggableResponse, next: () => void) {
352
+ // A header can arrive repeated, so its type is `string | string[]`.
353
+ const raw = req.headers['x-request-id']
354
+ const requestId = (Array.isArray(raw) ? raw[0] : raw) ?? `r_${randomUUID()}`
351
355
  this.logContext.run({ requestId }, next)
352
356
  }
353
357
  }
@@ -441,7 +445,8 @@ export class LokiDestination implements ILogDestination {
441
445
  private readonly url: string
442
446
  private readonly headers: Record<string, string>
443
447
  private readonly labels: Record<string, string>
444
- private buffer: LogEntry[] = []
448
+ // Serialized lines, not objects — `write` receives the payload already encoded.
449
+ private buffer: string[] = []
445
450
  private flushTimer?: NodeJS.Timeout
446
451
 
447
452
  constructor(opts: {
@@ -468,8 +473,10 @@ export class LokiDestination implements ILogDestination {
468
473
  await this.flush()
469
474
  }
470
475
 
471
- write(entry: LogEntry): void {
472
- this.buffer.push(entry)
476
+ // `payload` already IS the serialized entry, newline-terminated. Buffer it as
477
+ // it arrives; parse only where a field is genuinely needed, as `flush` does.
478
+ write(payload: string): void {
479
+ this.buffer.push(payload)
473
480
  if (this.buffer.length >= 100) void this.flush()
474
481
  }
475
482
 
@@ -480,7 +487,10 @@ export class LokiDestination implements ILogDestination {
480
487
  streams: [
481
488
  {
482
489
  stream: this.labels,
483
- values: batch.map((e) => [String(BigInt(e.time) * 1_000_000n), JSON.stringify(e)])
490
+ values: batch.map((line) => [
491
+ String(BigInt((JSON.parse(line) as LogEntry).time) * 1_000_000n),
492
+ line.trimEnd()
493
+ ])
484
494
  }
485
495
  ]
486
496
  })
@@ -522,7 +532,10 @@ export class PrismaLogDestination implements ILogDestination {
522
532
 
523
533
  constructor(private readonly prisma: PrismaClient) {}
524
534
 
525
- write(entry: LogEntry): void {
535
+ write(payload: string): void {
536
+ // This destination stores individual columns, so it is one of the few that
537
+ // has to parse. A sink that forwards the line verbatim should not.
538
+ const entry = JSON.parse(payload) as LogEntry
526
539
  void this.prisma.applicationLog.create({
527
540
  data: {
528
541
  level: entry.level,
@@ -559,8 +572,9 @@ export class RollingFileDestination implements ILogDestination {
559
572
  await new Promise<void>((resolve) => this.stream?.end(resolve))
560
573
  }
561
574
 
562
- write(entry: LogEntry): void {
563
- this.stream?.write(JSON.stringify(entry) + '\n')
575
+ write(payload: string): void {
576
+ // Already newline-terminated JSON — re-serializing would double-encode it.
577
+ this.stream?.write(payload)
564
578
  }
565
579
  }
566
580
  ```
@@ -808,7 +822,8 @@ type LogEntry = {
808
822
  interface ILogDestination {
809
823
  readonly name: string
810
824
  readonly minLevel?: LogLevel
811
- write(entry: LogEntry): void
825
+ /** `payload` is a newline-terminated JSON entry, UTF-8 encoded — not an object. */
826
+ write(payload: string): void | Promise<void>
812
827
  onInit?(): Promise<void>
813
828
  onShutdown?(): Promise<void>
814
829
  }
@@ -1363,8 +1363,8 @@ exports.RequestIdMiddleware = class RequestIdMiddleware {
1363
1363
  * Echo or mint the `x-request-id`, expose it on the response, and run the
1364
1364
  * remainder of the request inside a fresh log-context scope.
1365
1365
  *
1366
- * @param req - The incoming Express request.
1367
- * @param res - The outgoing Express response.
1366
+ * @param req - The incoming request (Express satisfies the contract).
1367
+ * @param res - The outgoing response (Express satisfies the contract).
1368
1368
  * @param next - The next handler in the chain.
1369
1369
  */
1370
1370
  use(req, res, next) {
@@ -2,7 +2,6 @@ import * as _nestjs_common from '@nestjs/common';
2
2
  import { ModuleMetadata, Type, DynamicModule, INestApplication, LoggerService, OnApplicationShutdown, ExceptionFilter, ArgumentsHost, NestInterceptor, ExecutionContext, CallHandler, MiddlewareConsumer, NestMiddleware, CustomDecorator } from '@nestjs/common';
3
3
  import { Logger } from 'pino';
4
4
  import { Observable } from 'rxjs';
5
- import { Request, Response, NextFunction } from 'express';
6
5
 
7
6
  /**
8
7
  * Pino log levels (mirrored to NestJS-compatible names).
@@ -753,6 +752,66 @@ declare class HttpLoggingInterceptor implements NestInterceptor {
753
752
  */
754
753
  declare function applyRequestIdMiddleware(consumer: MiddlewareConsumer, routes?: string): void;
755
754
 
755
+ /**
756
+ * Minimal HTTP request/response contracts the logging layer reads.
757
+ *
758
+ * Layer: server/interfaces — exported structural contracts shared by the HTTP
759
+ * logging interceptor, the exception filter and the request-id middleware. They
760
+ * are part of the public API: they appear in those components' published
761
+ * signatures, so a consumer calling `RequestIdMiddleware.use()` directly needs
762
+ * to be able to name them. Declared structurally, listing only the members
763
+ * those three actually touch, so the published declarations depend on no HTTP
764
+ * framework's types. Naming Express's
765
+ * `Request`/`Response` here would make the emitted `.d.ts` import from
766
+ * `express`, forcing every consumer that compiles with `skipLibCheck: false` to
767
+ * install `@types/express` whether or not they use those signatures.
768
+ *
769
+ * The shapes mirror what the Express adapter provides — `status().json()` and
770
+ * `setHeader()` are Express/Node response methods — so this is not an
771
+ * adapter-agnostic abstraction; a Fastify adapter remains unsupported. An
772
+ * Express request and response satisfy these contracts structurally, with no
773
+ * cast at the call site.
774
+ */
775
+ /** Raw inbound headers, as the HTTP layer delivers them. */
776
+ type IncomingHeaders = Record<string, string | string[] | undefined>;
777
+ /**
778
+ * The inbound request members the logging layer reads.
779
+ *
780
+ * `user` is populated by upstream auth in the consumer app (a guard or
781
+ * middleware); only `id` is ever read, for the acting-user log field.
782
+ */
783
+ interface LoggableRequest {
784
+ /** Inbound headers — read for correlation ids and the user agent. */
785
+ readonly headers: IncomingHeaders;
786
+ /** HTTP verb, logged as-is. */
787
+ readonly method: string;
788
+ /** Request target, normalized and query-stripped before it reaches a log. */
789
+ readonly url: string;
790
+ /** Client address when the adapter resolves one. */
791
+ readonly ip?: string | undefined;
792
+ /** Authenticated principal, when upstream auth attached one. */
793
+ readonly user?: {
794
+ readonly id?: string | undefined;
795
+ } | undefined;
796
+ }
797
+ /**
798
+ * The outbound response members the logging layer writes or reads: the status
799
+ * for the terminal log entry, `setHeader` to echo the correlation id, and the
800
+ * chainable `status().json()` used by the exception filter to emit a body.
801
+ */
802
+ interface LoggableResponse {
803
+ /** Status code, read when logging the completed request. */
804
+ readonly statusCode: number;
805
+ /** Sets a response header (used for the correlation id). */
806
+ setHeader(name: string, value: string): void;
807
+ /** Selects the status code and returns the chainable body writer. */
808
+ status(code: number): {
809
+ json(body: unknown): unknown;
810
+ };
811
+ }
812
+ /** Continuation passed to a middleware; invoked with no arguments here. */
813
+ type NextHandler = () => void;
814
+
756
815
  /**
757
816
  * Reads (or generates) the correlation id and starts the per-request log
758
817
  * context scope.
@@ -783,11 +842,11 @@ declare class RequestIdMiddleware implements NestMiddleware {
783
842
  * Echo or mint the `x-request-id`, expose it on the response, and run the
784
843
  * remainder of the request inside a fresh log-context scope.
785
844
  *
786
- * @param req - The incoming Express request.
787
- * @param res - The outgoing Express response.
845
+ * @param req - The incoming request (Express satisfies the contract).
846
+ * @param res - The outgoing response (Express satisfies the contract).
788
847
  * @param next - The next handler in the chain.
789
848
  */
790
- use(req: Request, res: Response, next: NextFunction): void;
849
+ use(req: LoggableRequest, res: LoggableResponse, next: NextHandler): void;
791
850
  }
792
851
 
793
852
  /**
@@ -950,4 +1009,4 @@ declare const RESERVED_LOG_KEYS: Readonly<{
950
1009
  readonly LOGGER_ENTRY_TRUNCATED: "LOGGER_ENTRY_TRUNCATED";
951
1010
  }>;
952
1011
 
953
- export { BymaxLoggerModule, type BymaxLoggerModuleAsyncOptions, type BymaxLoggerModuleOptions, type BymaxLoggerModuleOptionsFactory, DEFAULT_REDACT_PATHS, DefaultStdoutDestination, HttpExceptionFilter, HttpLoggingInterceptor, type HttpOptions, type ILogDestination, InjectLogger, LOGGER_DESTINATIONS_TOKEN, LOGGER_OPTIONS_TOKEN, LOGGER_PINO_INSTANCE_TOKEN, LOG_CONTEXT_METADATA_KEY, LOG_CONTEXT_TOKEN, LOG_KEYS_CONVENTION_REGEX, LogContext, type LogContext$1 as LogContextBag, LogContextService, type LogEntry, type LogLevel, LogPerformance, type OtelOptions, PinoLoggerService, PrettyDevDestination, RESERVED_LOG_KEYS, RequestIdMiddleware, type ResolvedBymaxLoggerModuleOptions, type ServiceMetadata, applyRequestIdMiddleware };
1012
+ export { BymaxLoggerModule, type BymaxLoggerModuleAsyncOptions, type BymaxLoggerModuleOptions, type BymaxLoggerModuleOptionsFactory, DEFAULT_REDACT_PATHS, DefaultStdoutDestination, HttpExceptionFilter, HttpLoggingInterceptor, type HttpOptions, type ILogDestination, type IncomingHeaders, InjectLogger, LOGGER_DESTINATIONS_TOKEN, LOGGER_OPTIONS_TOKEN, LOGGER_PINO_INSTANCE_TOKEN, LOG_CONTEXT_METADATA_KEY, LOG_CONTEXT_TOKEN, LOG_KEYS_CONVENTION_REGEX, LogContext, type LogContext$1 as LogContextBag, LogContextService, type LogEntry, type LogLevel, LogPerformance, type LoggableRequest, type LoggableResponse, type NextHandler, type OtelOptions, PinoLoggerService, PrettyDevDestination, RESERVED_LOG_KEYS, RequestIdMiddleware, type ResolvedBymaxLoggerModuleOptions, type ServiceMetadata, applyRequestIdMiddleware };
@@ -2,7 +2,6 @@ import * as _nestjs_common from '@nestjs/common';
2
2
  import { ModuleMetadata, Type, DynamicModule, INestApplication, LoggerService, OnApplicationShutdown, ExceptionFilter, ArgumentsHost, NestInterceptor, ExecutionContext, CallHandler, MiddlewareConsumer, NestMiddleware, CustomDecorator } from '@nestjs/common';
3
3
  import { Logger } from 'pino';
4
4
  import { Observable } from 'rxjs';
5
- import { Request, Response, NextFunction } from 'express';
6
5
 
7
6
  /**
8
7
  * Pino log levels (mirrored to NestJS-compatible names).
@@ -753,6 +752,66 @@ declare class HttpLoggingInterceptor implements NestInterceptor {
753
752
  */
754
753
  declare function applyRequestIdMiddleware(consumer: MiddlewareConsumer, routes?: string): void;
755
754
 
755
+ /**
756
+ * Minimal HTTP request/response contracts the logging layer reads.
757
+ *
758
+ * Layer: server/interfaces — exported structural contracts shared by the HTTP
759
+ * logging interceptor, the exception filter and the request-id middleware. They
760
+ * are part of the public API: they appear in those components' published
761
+ * signatures, so a consumer calling `RequestIdMiddleware.use()` directly needs
762
+ * to be able to name them. Declared structurally, listing only the members
763
+ * those three actually touch, so the published declarations depend on no HTTP
764
+ * framework's types. Naming Express's
765
+ * `Request`/`Response` here would make the emitted `.d.ts` import from
766
+ * `express`, forcing every consumer that compiles with `skipLibCheck: false` to
767
+ * install `@types/express` whether or not they use those signatures.
768
+ *
769
+ * The shapes mirror what the Express adapter provides — `status().json()` and
770
+ * `setHeader()` are Express/Node response methods — so this is not an
771
+ * adapter-agnostic abstraction; a Fastify adapter remains unsupported. An
772
+ * Express request and response satisfy these contracts structurally, with no
773
+ * cast at the call site.
774
+ */
775
+ /** Raw inbound headers, as the HTTP layer delivers them. */
776
+ type IncomingHeaders = Record<string, string | string[] | undefined>;
777
+ /**
778
+ * The inbound request members the logging layer reads.
779
+ *
780
+ * `user` is populated by upstream auth in the consumer app (a guard or
781
+ * middleware); only `id` is ever read, for the acting-user log field.
782
+ */
783
+ interface LoggableRequest {
784
+ /** Inbound headers — read for correlation ids and the user agent. */
785
+ readonly headers: IncomingHeaders;
786
+ /** HTTP verb, logged as-is. */
787
+ readonly method: string;
788
+ /** Request target, normalized and query-stripped before it reaches a log. */
789
+ readonly url: string;
790
+ /** Client address when the adapter resolves one. */
791
+ readonly ip?: string | undefined;
792
+ /** Authenticated principal, when upstream auth attached one. */
793
+ readonly user?: {
794
+ readonly id?: string | undefined;
795
+ } | undefined;
796
+ }
797
+ /**
798
+ * The outbound response members the logging layer writes or reads: the status
799
+ * for the terminal log entry, `setHeader` to echo the correlation id, and the
800
+ * chainable `status().json()` used by the exception filter to emit a body.
801
+ */
802
+ interface LoggableResponse {
803
+ /** Status code, read when logging the completed request. */
804
+ readonly statusCode: number;
805
+ /** Sets a response header (used for the correlation id). */
806
+ setHeader(name: string, value: string): void;
807
+ /** Selects the status code and returns the chainable body writer. */
808
+ status(code: number): {
809
+ json(body: unknown): unknown;
810
+ };
811
+ }
812
+ /** Continuation passed to a middleware; invoked with no arguments here. */
813
+ type NextHandler = () => void;
814
+
756
815
  /**
757
816
  * Reads (or generates) the correlation id and starts the per-request log
758
817
  * context scope.
@@ -783,11 +842,11 @@ declare class RequestIdMiddleware implements NestMiddleware {
783
842
  * Echo or mint the `x-request-id`, expose it on the response, and run the
784
843
  * remainder of the request inside a fresh log-context scope.
785
844
  *
786
- * @param req - The incoming Express request.
787
- * @param res - The outgoing Express response.
845
+ * @param req - The incoming request (Express satisfies the contract).
846
+ * @param res - The outgoing response (Express satisfies the contract).
788
847
  * @param next - The next handler in the chain.
789
848
  */
790
- use(req: Request, res: Response, next: NextFunction): void;
849
+ use(req: LoggableRequest, res: LoggableResponse, next: NextHandler): void;
791
850
  }
792
851
 
793
852
  /**
@@ -950,4 +1009,4 @@ declare const RESERVED_LOG_KEYS: Readonly<{
950
1009
  readonly LOGGER_ENTRY_TRUNCATED: "LOGGER_ENTRY_TRUNCATED";
951
1010
  }>;
952
1011
 
953
- export { BymaxLoggerModule, type BymaxLoggerModuleAsyncOptions, type BymaxLoggerModuleOptions, type BymaxLoggerModuleOptionsFactory, DEFAULT_REDACT_PATHS, DefaultStdoutDestination, HttpExceptionFilter, HttpLoggingInterceptor, type HttpOptions, type ILogDestination, InjectLogger, LOGGER_DESTINATIONS_TOKEN, LOGGER_OPTIONS_TOKEN, LOGGER_PINO_INSTANCE_TOKEN, LOG_CONTEXT_METADATA_KEY, LOG_CONTEXT_TOKEN, LOG_KEYS_CONVENTION_REGEX, LogContext, type LogContext$1 as LogContextBag, LogContextService, type LogEntry, type LogLevel, LogPerformance, type OtelOptions, PinoLoggerService, PrettyDevDestination, RESERVED_LOG_KEYS, RequestIdMiddleware, type ResolvedBymaxLoggerModuleOptions, type ServiceMetadata, applyRequestIdMiddleware };
1012
+ export { BymaxLoggerModule, type BymaxLoggerModuleAsyncOptions, type BymaxLoggerModuleOptions, type BymaxLoggerModuleOptionsFactory, DEFAULT_REDACT_PATHS, DefaultStdoutDestination, HttpExceptionFilter, HttpLoggingInterceptor, type HttpOptions, type ILogDestination, type IncomingHeaders, InjectLogger, LOGGER_DESTINATIONS_TOKEN, LOGGER_OPTIONS_TOKEN, LOGGER_PINO_INSTANCE_TOKEN, LOG_CONTEXT_METADATA_KEY, LOG_CONTEXT_TOKEN, LOG_KEYS_CONVENTION_REGEX, LogContext, type LogContext$1 as LogContextBag, LogContextService, type LogEntry, type LogLevel, LogPerformance, type LoggableRequest, type LoggableResponse, type NextHandler, type OtelOptions, PinoLoggerService, PrettyDevDestination, RESERVED_LOG_KEYS, RequestIdMiddleware, type ResolvedBymaxLoggerModuleOptions, type ServiceMetadata, applyRequestIdMiddleware };
@@ -1357,8 +1357,8 @@ var RequestIdMiddleware = class {
1357
1357
  * Echo or mint the `x-request-id`, expose it on the response, and run the
1358
1358
  * remainder of the request inside a fresh log-context scope.
1359
1359
  *
1360
- * @param req - The incoming Express request.
1361
- * @param res - The outgoing Express response.
1360
+ * @param req - The incoming request (Express satisfies the contract).
1361
+ * @param res - The outgoing response (Express satisfies the contract).
1362
1362
  * @param next - The next handler in the chain.
1363
1363
  */
1364
1364
  use(req, res, next) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bymax-one/nest-logger",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Structured JSON logging for NestJS based on Pino 10, with optional OpenTelemetry correlation.",
5
5
  "author": "Bymax One <support@bymax.one>",
6
6
  "license": "MIT",
@@ -64,10 +64,9 @@
64
64
  },
65
65
  "dependencies": {},
66
66
  "peerDependencies": {
67
- "@nestjs/common": "^11.0.0",
68
- "@nestjs/core": "^11.0.0",
67
+ "@nestjs/common": "^11.0.16",
68
+ "@nestjs/core": "^11.1.18",
69
69
  "@opentelemetry/api": "^1.9.0",
70
- "@types/express": "^4.17.21 || ^5.0.0",
71
70
  "pino": "^10.0.0",
72
71
  "pino-pretty": "^13.0.0",
73
72
  "reflect-metadata": "^0.2.0",
@@ -77,9 +76,6 @@
77
76
  "@opentelemetry/api": {
78
77
  "optional": true
79
78
  },
80
- "@types/express": {
81
- "optional": true
82
- },
83
79
  "pino-pretty": {
84
80
  "optional": true
85
81
  }
@@ -146,23 +142,24 @@
146
142
  "registry": "https://registry.npmjs.org/"
147
143
  },
148
144
  "scripts": {
145
+ "bench": "node --expose-gc --import tsx bench/throughput.bench.ts",
149
146
  "build": "pnpm clean && tsup",
147
+ "check:exports": "attw --pack .",
148
+ "check:published": "node scripts/check-published-surface.mjs",
149
+ "clean": "rm -rf dist coverage",
150
150
  "lint": "eslint src",
151
151
  "lint:fix": "eslint src --fix",
152
- "test": "jest",
153
- "test:cov": "jest --coverage",
154
- "test:watch": "jest --watch",
155
- "test:e2e": "jest --config jest.e2e.config.ts",
156
- "test:all": "pnpm test && pnpm test:e2e",
157
- "test:cov:all": "jest --config jest.coverage.config.ts --coverage",
158
152
  "mutation": "stryker run",
159
- "mutation:incremental": "stryker run --incremental",
160
153
  "mutation:dry-run": "stryker run --dryRunOnly",
161
- "bench": "node --expose-gc --import tsx bench/throughput.bench.ts",
162
- "typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.server.json",
154
+ "mutation:incremental": "stryker run --incremental",
155
+ "release": "pnpm publish --provenance",
163
156
  "size": "node scripts/check-size.mjs",
164
- "check:exports": "attw --pack .",
165
- "clean": "rm -rf dist coverage",
166
- "release": "pnpm publish --provenance"
157
+ "test": "jest",
158
+ "test:all": "pnpm test && pnpm test:e2e",
159
+ "test:cov": "jest --coverage",
160
+ "test:cov:all": "jest --config jest.coverage.config.ts --coverage",
161
+ "test:e2e": "jest --config jest.e2e.config.ts",
162
+ "test:watch": "jest --watch",
163
+ "typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.server.json"
167
164
  }
168
165
  }