@bymax-one/nest-logger 1.4.0 → 1.4.2
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 +102 -5
- package/README.md +43 -1
- package/dist/server/index.cjs +58 -0
- package/dist/server/index.d.cts +81 -1
- package/dist/server/index.d.ts +81 -1
- package/dist/server/index.mjs +59 -1
- package/dist/shared/index.cjs +1 -0
- package/dist/shared/index.d.cts +3 -1
- package/dist/shared/index.d.ts +3 -1
- package/dist/shared/index.mjs +1 -0
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -11,6 +11,92 @@ heading here.
|
|
|
11
11
|
|
|
12
12
|
## [Unreleased]
|
|
13
13
|
|
|
14
|
+
## [1.4.2] - 2026-10-30
|
|
15
|
+
|
|
16
|
+
No breaking changes. Dependency and build-tooling maintenance only. No source file under `src/` changes and the
|
|
17
|
+
runtime JavaScript in `dist/` is byte-identical to `1.4.1`.
|
|
18
|
+
|
|
19
|
+
### Security
|
|
20
|
+
|
|
21
|
+
- Raise the pnpm override floors for transitive devDependencies that resolved to versions
|
|
22
|
+
with new advisories: `body-parser` `^2.4.0` (GHSA-27r3-jxmh-p828, DoS on trailing bytes after a
|
|
23
|
+
compressed body), `multer` `^2.5.0` (GHSA-q7qp-rjg7-q26m, DoS from a pending async
|
|
24
|
+
`fileFilter`), `qs` `^6.16.1` (GHSA-6pq8-jhm2-2vcw, `qs.stringify` DoS) and `zod` `^4.6.6`
|
|
25
|
+
(GHSA-mrhx-c7xc-m3w5, memory exhaustion on oversized collections). Dev-only: the published
|
|
26
|
+
package has zero runtime dependencies.
|
|
27
|
+
- Ignore GHSA-gcqx-w48m-w2h4 (`deepmerge` <= 4.3.1, prototype poisoning in `mergeObject`) in
|
|
28
|
+
`osv-scanner.toml` until 2027-01-27. No patched release exists, and `deepmerge` is reached
|
|
29
|
+
only through `jest-config`, a devDependency. Remove the entry when a fixed `deepmerge` ships
|
|
30
|
+
or jest drops it.
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
|
|
34
|
+
- Build with `tsup` 9 (devDependency, was 8.5). The published `.mjs` and `.cjs` bundles are
|
|
35
|
+
byte-identical; the `.d.ts` and `.d.cts` files re-emit type exports as a separate
|
|
36
|
+
`export type { … }` statement instead of inline `type` modifiers, which declares the same
|
|
37
|
+
public surface. `attw` reports no problems and the bundle-size budgets hold.
|
|
38
|
+
- Resolve `@opentelemetry/api` to 1.10.0 in the lockfile (was 1.9.1), so the test suite runs
|
|
39
|
+
against the current API release. The `^1.9.0` range in `package.json`, devDependency and peer
|
|
40
|
+
alike, is unchanged.
|
|
41
|
+
- Bump `github/codeql-action/upload-sarif` to 4.39.1 in the Scorecard workflow. CI only; nothing
|
|
42
|
+
ships.
|
|
43
|
+
|
|
44
|
+
### Documentation
|
|
45
|
+
|
|
46
|
+
- The runtime bundles are unchanged, and the type declarations were regenerated by `tsup` 9.
|
|
47
|
+
- The 1.0.1 and 1.0.8 release notes are corrected: 1.0.8 now records the id-safe charset
|
|
48
|
+
validation of inbound `x-request-id` and tenant ids that it already shipped.
|
|
49
|
+
|
|
50
|
+
#### Apply to a consumer
|
|
51
|
+
|
|
52
|
+
No action required. There is no new public API, no peer range changed, and the runtime JavaScript
|
|
53
|
+
is byte-identical to `1.4.1`; only the grouping of type exports in the declaration files differs.
|
|
54
|
+
|
|
55
|
+
## [1.4.1] - 2026-10-23
|
|
56
|
+
|
|
57
|
+
No breaking changes.
|
|
58
|
+
|
|
59
|
+
### Added
|
|
60
|
+
|
|
61
|
+
- **`PinoUnexpectedErrorSink` — the cause of a nest-core `500`, logged.** When nest-core's exception
|
|
62
|
+
filter turns an unexpected error into `500 BYMAX_INTERNAL_ERROR`, the access-log line carries the
|
|
63
|
+
cause only when this package's HTTP interceptor saw the error. An error raised before it (in a
|
|
64
|
+
guard or a middleware), or any error with HTTP logging off, left a synthetic
|
|
65
|
+
`Error("GET /url → 500")` or no line at all. nest-core 1.6.2 adds an
|
|
66
|
+
optional `BYMAX_UNEXPECTED_ERROR_SINK` token. This class implements it: one `error` entry per
|
|
67
|
+
unexpected error, keyed `HTTP_UNEXPECTED_ERROR`, with the original error's type, message, stack
|
|
68
|
+
and cause chain, plus `method`, the route template (`route`, never the raw URL) and
|
|
69
|
+
`correlationId`. It adds nothing else from the request — no body, headers or query string — and
|
|
70
|
+
`record()` never throws. The error keeps its own enumerable fields, as on every `err` entry, so
|
|
71
|
+
request data an error object carries itself is logged under the usual key-name redaction.
|
|
72
|
+
|
|
73
|
+
This package still does not depend on nest-core. The class matches nest-core's contract by
|
|
74
|
+
shape, and the types it implements are exported as `IUnexpectedErrorSink` and
|
|
75
|
+
`UnexpectedErrorReport`.
|
|
76
|
+
|
|
77
|
+
`HTTP_UNEXPECTED_ERROR` joins `RESERVED_LOG_KEYS`. An application that already writes that key
|
|
78
|
+
for its own events should rename them, or its queries will mix the two.
|
|
79
|
+
|
|
80
|
+
#### Apply to a derived backend
|
|
81
|
+
|
|
82
|
+
Requires `@bymax-one/nest-core` 1.6.2 or later. Nothing changes until you bind the sink: the token
|
|
83
|
+
is optional and unbound by default. Bind it from a `@Global()` module imported next to
|
|
84
|
+
`BymaxLoggerModule`:
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
@Global()
|
|
88
|
+
@Module({
|
|
89
|
+
providers: [{ provide: BYMAX_UNEXPECTED_ERROR_SINK, useClass: PinoUnexpectedErrorSink }],
|
|
90
|
+
exports: [BYMAX_UNEXPECTED_ERROR_SINK]
|
|
91
|
+
})
|
|
92
|
+
export class UnexpectedErrorSinkModule {}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
`BYMAX_UNEXPECTED_ERROR_SINK` comes from `@bymax-one/nest-core` and `PinoUnexpectedErrorSink` from
|
|
96
|
+
`@bymax-one/nest-logger`. To verify, make a route throw a plain `Error`: the response stays
|
|
97
|
+
`500 BYMAX_INTERNAL_ERROR`, and the log gains one `HTTP_UNEXPECTED_ERROR` line next to the
|
|
98
|
+
access-log line.
|
|
99
|
+
|
|
14
100
|
## [1.4.0] - 2026-08-30
|
|
15
101
|
|
|
16
102
|
No breaking changes. Nothing you have wired stops working, and no export was renamed.
|
|
@@ -1654,8 +1740,9 @@ identical to `1.0.8`, and nothing changed but the version number.
|
|
|
1654
1740
|
|
|
1655
1741
|
## [1.0.8] - 2026-08-10
|
|
1656
1742
|
|
|
1657
|
-
Remediation of a local audit's redaction, attribution and correlation-id findings.
|
|
1658
|
-
|
|
1743
|
+
Remediation of a local audit's redaction, attribution and correlation-id findings. The public
|
|
1744
|
+
API is unchanged; the fixes are in the default redact set, the acting-user resolution, the
|
|
1745
|
+
correlation-id validation and the docs.
|
|
1659
1746
|
|
|
1660
1747
|
### Fixed
|
|
1661
1748
|
|
|
@@ -1667,6 +1754,14 @@ changed; the fixes are in the default redact set, the acting-user resolution and
|
|
|
1667
1754
|
exception filter now resolve the acting user as `sub ?? id`, so a JWT principal (every
|
|
1668
1755
|
`@bymax-one/nest-auth` token) is attributed to its subject rather than an ORM `id` when a
|
|
1669
1756
|
principal carries both.
|
|
1757
|
+
- **Inbound correlation and tenant ids are confined to an id-safe charset.** The inbound
|
|
1758
|
+
`x-request-id` and tenant-id header values are now accepted only when they are drawn from an
|
|
1759
|
+
id-safe character set and fit the length bound; anything else (control bytes, whitespace,
|
|
1760
|
+
markup characters) is rejected. A rejected request id is replaced by a generated one (when
|
|
1761
|
+
`shouldGenerateRequestId` is on) and a rejected tenant id is omitted. The request id is echoed
|
|
1762
|
+
on the `x-request-id` response header and both ids are stored in the log context, so this keeps
|
|
1763
|
+
a client from planting a control byte or markup fragment in the logs and the header of every
|
|
1764
|
+
request it makes.
|
|
1670
1765
|
|
|
1671
1766
|
### Documentation
|
|
1672
1767
|
|
|
@@ -1911,11 +2006,11 @@ published `dist/` is identical — no runtime behaviour changes for consumers.
|
|
|
1911
2006
|
Dev-only: the published package has zero runtime dependencies.
|
|
1912
2007
|
- Force `qs` to `^6.15.3` (via `pnpm.overrides`) to clear GHSA-q8mj-m7cp-5q26
|
|
1913
2008
|
(`qs.stringify` DoS). `typed-rest-client`, pulled in by Stryker, pins `qs` at
|
|
1914
|
-
the affected `6.15.1` exactly, so no dependency refresh could resolve it
|
|
2009
|
+
the affected `6.15.1` exactly, so no dependency refresh could resolve it.
|
|
1915
2010
|
- Pin every third-party and GitHub-owned action to a full commit SHA, with the
|
|
1916
2011
|
release tag kept as a trailing comment so Dependabot can still bump them. The
|
|
1917
2012
|
org's own `bymaxone/.github` reusable workflows and composite action stay on
|
|
1918
|
-
the `@v1` moving tag by design, so shared-pipeline fixes keep propagating
|
|
2013
|
+
the `@v1` moving tag by design, so shared-pipeline fixes keep propagating.
|
|
1919
2014
|
|
|
1920
2015
|
### Changed
|
|
1921
2016
|
|
|
@@ -1981,7 +2076,9 @@ published `dist/` is identical — no runtime behaviour changes for consumers.
|
|
|
1981
2076
|
- Professional CI suite: `ci.yml`, `bench.yml`, `codeql.yml`, `scorecard.yml`,
|
|
1982
2077
|
`release.yml`, Dependabot, and issue templates
|
|
1983
2078
|
|
|
1984
|
-
[Unreleased]: https://github.com/bymaxone/nest-logger/compare/v1.4.
|
|
2079
|
+
[Unreleased]: https://github.com/bymaxone/nest-logger/compare/v1.4.2...HEAD
|
|
2080
|
+
[1.4.2]: https://github.com/bymaxone/nest-logger/compare/v1.4.1...v1.4.2
|
|
2081
|
+
[1.4.1]: https://github.com/bymaxone/nest-logger/compare/v1.4.0...v1.4.1
|
|
1985
2082
|
[1.4.0]: https://github.com/bymaxone/nest-logger/compare/v1.3.1...v1.4.0
|
|
1986
2083
|
[1.3.1]: https://github.com/bymaxone/nest-logger/compare/v1.3.0...v1.3.1
|
|
1987
2084
|
[1.3.0]: https://github.com/bymaxone/nest-logger/compare/v1.2.9...v1.3.0
|
package/README.md
CHANGED
|
@@ -411,6 +411,48 @@ flushed** is reported as the success it was — the server completed and flushed
|
|
|
411
411
|
peer read it is not knowable from the server side. What this catches is the case that matters
|
|
412
412
|
operationally: the slow upstream, the load-balancer timeout, the cancelled request.
|
|
413
413
|
|
|
414
|
+
#### Unexpected errors behind `@bymax-one/nest-core`
|
|
415
|
+
|
|
416
|
+
When nest-core's exception filter answers, an unexpected error becomes a fixed
|
|
417
|
+
`500 BYMAX_INTERNAL_ERROR`. The access-log line for that response carries the cause only when this
|
|
418
|
+
package's HTTP interceptor saw the error, which it does not for an error raised before it (in a
|
|
419
|
+
guard or a middleware) or with HTTP logging off. nest-core 1.6.2 adds an optional sink token, `BYMAX_UNEXPECTED_ERROR_SINK`, and
|
|
420
|
+
`PinoUnexpectedErrorSink` is a ready implementation of it. Bind it from a global module:
|
|
421
|
+
|
|
422
|
+
```typescript
|
|
423
|
+
import { Global, Module } from '@nestjs/common'
|
|
424
|
+
import { BYMAX_UNEXPECTED_ERROR_SINK } from '@bymax-one/nest-core'
|
|
425
|
+
import { PinoUnexpectedErrorSink } from '@bymax-one/nest-logger'
|
|
426
|
+
|
|
427
|
+
@Global()
|
|
428
|
+
@Module({
|
|
429
|
+
providers: [{ provide: BYMAX_UNEXPECTED_ERROR_SINK, useClass: PinoUnexpectedErrorSink }],
|
|
430
|
+
exports: [BYMAX_UNEXPECTED_ERROR_SINK]
|
|
431
|
+
})
|
|
432
|
+
export class UnexpectedErrorSinkModule {}
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
Import it next to `BymaxLoggerModule`. The binding resolves `PinoLoggerService` because
|
|
436
|
+
`BymaxLoggerModule` is global by default; with `isGlobal: false`, add the same `forRoot`/`forRootAsync` result the
|
|
437
|
+
application imports to the sink module's `imports`. Keep it in a constant: calling `forRoot` a
|
|
438
|
+
second time builds a second logger. Each unexpected error then produces one `error` entry with the key
|
|
439
|
+
`HTTP_UNEXPECTED_ERROR`:
|
|
440
|
+
|
|
441
|
+
| Field | Content |
|
|
442
|
+
| --------------- | ------------------------------------------------------------------------------------------------------- |
|
|
443
|
+
| `err` | The original error through the `err` serializer: type, message, scrubbed stack, cause chain, own fields |
|
|
444
|
+
| `method` | HTTP method |
|
|
445
|
+
| `route` | Matched route template (`/invoices/:id`), or `<unmatched>` before routing — never the raw URL |
|
|
446
|
+
| `correlationId` | nest-core's correlation id, when one resolved |
|
|
447
|
+
|
|
448
|
+
The sink adds nothing from the request beyond `method`, `route` and `correlationId`: no body,
|
|
449
|
+
headers or query string. The error is serialized as on every `err` entry, own enumerable fields
|
|
450
|
+
included, so an error object that itself carries request data (a `url` with a query string, a copy
|
|
451
|
+
of the headers) brings that data along, under the same key-name redaction. The trace id comes from the trace mixin, as on every other entry. `record()`
|
|
452
|
+
never throws, so a failing destination cannot change the response. This package does not import
|
|
453
|
+
nest-core: the class matches nest-core's contract by shape, and `IUnexpectedErrorSink` /
|
|
454
|
+
`UnexpectedErrorReport` are exported for reference.
|
|
455
|
+
|
|
414
456
|
### 6. OpenTelemetry correlation
|
|
415
457
|
|
|
416
458
|
Initialize the OTel SDK **before** importing NestJS — this is critical:
|
|
@@ -729,7 +771,7 @@ function assertValidLogKey(key: string) {
|
|
|
729
771
|
|
|
730
772
|
The following keys are used internally by the library — do not reuse them in application code:
|
|
731
773
|
|
|
732
|
-
`LOGGER_BOOTSTRAP_OK` · `LOGGER_BOOTSTRAP_WARNING` · `LOGGER_SHUTDOWN_OK` · `HTTP_REQUEST_START` · `HTTP_REQUEST_SUCCESS` · `HTTP_REQUEST_REDIRECT` · `HTTP_REQUEST_CLIENT_ERROR` · `HTTP_REQUEST_SERVER_ERROR` · `HTTP_REQUEST_ABORTED` · `HTTP_REQUEST_COMPLETED` · `HTTP_EXCEPTION_HANDLED` · `HTTP_EXCEPTION_UNHANDLED` · `METHOD_EXECUTION` · `METHOD_SLOW_EXECUTION` · `LOGGER_DESTINATION_INIT_FAILED` · `LOGGER_DESTINATION_WRITE_FAILED` · `LOGGER_ENTRY_TRUNCATED` · `LOGGER_REDACTION_FAILED`
|
|
774
|
+
`LOGGER_BOOTSTRAP_OK` · `LOGGER_BOOTSTRAP_WARNING` · `LOGGER_SHUTDOWN_OK` · `HTTP_REQUEST_START` · `HTTP_REQUEST_SUCCESS` · `HTTP_REQUEST_REDIRECT` · `HTTP_REQUEST_CLIENT_ERROR` · `HTTP_REQUEST_SERVER_ERROR` · `HTTP_REQUEST_ABORTED` · `HTTP_REQUEST_COMPLETED` · `HTTP_EXCEPTION_HANDLED` · `HTTP_EXCEPTION_UNHANDLED` · `HTTP_UNEXPECTED_ERROR` · `METHOD_EXECUTION` · `METHOD_SLOW_EXECUTION` · `LOGGER_DESTINATION_INIT_FAILED` · `LOGGER_DESTINATION_WRITE_FAILED` · `LOGGER_ENTRY_TRUNCATED` · `LOGGER_REDACTION_FAILED`
|
|
733
775
|
|
|
734
776
|
All reserved keys are exported as the `RESERVED_LOG_KEYS` constant from `@bymax-one/nest-logger/shared`.
|
|
735
777
|
|
package/dist/server/index.cjs
CHANGED
|
@@ -185,6 +185,7 @@ var RESERVED_LOG_KEYS = Object.freeze({
|
|
|
185
185
|
HTTP_REQUEST_ABORTED: "HTTP_REQUEST_ABORTED",
|
|
186
186
|
HTTP_EXCEPTION_HANDLED: "HTTP_EXCEPTION_HANDLED",
|
|
187
187
|
HTTP_EXCEPTION_UNHANDLED: "HTTP_EXCEPTION_UNHANDLED",
|
|
188
|
+
HTTP_UNEXPECTED_ERROR: "HTTP_UNEXPECTED_ERROR",
|
|
188
189
|
METHOD_EXECUTION: "METHOD_EXECUTION",
|
|
189
190
|
METHOD_SLOW_EXECUTION: "METHOD_SLOW_EXECUTION",
|
|
190
191
|
LOGGER_DESTINATION_INIT_FAILED: "LOGGER_DESTINATION_INIT_FAILED",
|
|
@@ -2909,6 +2910,63 @@ var ALL_ROUTES = "/";
|
|
|
2909
2910
|
function applyRequestIdMiddleware(consumer, routes = ALL_ROUTES) {
|
|
2910
2911
|
consumer.apply(exports.RequestIdMiddleware, exports.HttpAccessLogMiddleware).forRoutes(routes);
|
|
2911
2912
|
}
|
|
2913
|
+
exports.PinoUnexpectedErrorSink = class PinoUnexpectedErrorSink {
|
|
2914
|
+
/**
|
|
2915
|
+
* @param logger - The structured logger the entry is written to. Injected by
|
|
2916
|
+
* token explicitly: the package is bundled without `emitDecoratorMetadata`,
|
|
2917
|
+
* so implicit class-type injection would not resolve.
|
|
2918
|
+
*/
|
|
2919
|
+
constructor(logger) {
|
|
2920
|
+
this.logger = logger;
|
|
2921
|
+
}
|
|
2922
|
+
/**
|
|
2923
|
+
* Write one `error` entry for an unexpected error. Never throws.
|
|
2924
|
+
*
|
|
2925
|
+
* The entry carries `err` (name, message, scrubbed stack, cause chain and own
|
|
2926
|
+
* fields, through the configured `err` serializer), `method`, `route` and,
|
|
2927
|
+
* when present, `correlationId`. It deliberately carries nothing else from
|
|
2928
|
+
* the request: the report has no body, headers or query to leak, and this
|
|
2929
|
+
* method adds none.
|
|
2930
|
+
*
|
|
2931
|
+
* `report.traceId` is not written. The trace mixin already stamps the active
|
|
2932
|
+
* span's trace id under the configured `otel.traceIdField` — the same span
|
|
2933
|
+
* nest-core read it from — and writing it here would override that field and
|
|
2934
|
+
* ignore `otel.shouldAutoInjectTraceContext: false`.
|
|
2935
|
+
*
|
|
2936
|
+
* @param report - The error and its request coordinates, from nest-core.
|
|
2937
|
+
* @example
|
|
2938
|
+
* sink.record({ error: new TypeError('x is undefined'), method: 'GET', route: '/invoices/:id', correlationId: 'req-1' })
|
|
2939
|
+
* // → { level: 'error', logKey: 'HTTP_UNEXPECTED_ERROR', msg: 'x is undefined',
|
|
2940
|
+
* // err: { type: 'TypeError', message: 'x is undefined', stack: '…' },
|
|
2941
|
+
* // method: 'GET', route: '/invoices/:id', correlationId: 'req-1' }
|
|
2942
|
+
*/
|
|
2943
|
+
record(report) {
|
|
2944
|
+
try {
|
|
2945
|
+
const metadata = { method: report.method, route: report.route };
|
|
2946
|
+
if (report.correlationId !== void 0) {
|
|
2947
|
+
metadata["correlationId"] = report.correlationId;
|
|
2948
|
+
}
|
|
2949
|
+
this.logger.errorStructured(
|
|
2950
|
+
RESERVED_LOG_KEYS.HTTP_UNEXPECTED_ERROR,
|
|
2951
|
+
toLoggableError(report.error),
|
|
2952
|
+
void 0,
|
|
2953
|
+
metadata
|
|
2954
|
+
);
|
|
2955
|
+
} catch {
|
|
2956
|
+
}
|
|
2957
|
+
}
|
|
2958
|
+
};
|
|
2959
|
+
exports.PinoUnexpectedErrorSink = __decorateClass([
|
|
2960
|
+
common.Injectable(),
|
|
2961
|
+
__decorateParam(0, common.Inject(exports.PinoLoggerService))
|
|
2962
|
+
], exports.PinoUnexpectedErrorSink);
|
|
2963
|
+
function toLoggableError(value) {
|
|
2964
|
+
try {
|
|
2965
|
+
return isErrorLike(value) ? value : sanitizeError(value);
|
|
2966
|
+
} catch {
|
|
2967
|
+
return sanitizeError(value);
|
|
2968
|
+
}
|
|
2969
|
+
}
|
|
2912
2970
|
var INJECT_LOGGER_CONTEXT_METADATA_KEY = "bymax_logger:context";
|
|
2913
2971
|
function InjectLogger(context) {
|
|
2914
2972
|
return (target, propertyKey, parameterIndex) => {
|
package/dist/server/index.d.cts
CHANGED
|
@@ -572,6 +572,7 @@ declare const RESERVED_LOG_KEYS: Readonly<{
|
|
|
572
572
|
readonly HTTP_REQUEST_ABORTED: "HTTP_REQUEST_ABORTED";
|
|
573
573
|
readonly HTTP_EXCEPTION_HANDLED: "HTTP_EXCEPTION_HANDLED";
|
|
574
574
|
readonly HTTP_EXCEPTION_UNHANDLED: "HTTP_EXCEPTION_UNHANDLED";
|
|
575
|
+
readonly HTTP_UNEXPECTED_ERROR: "HTTP_UNEXPECTED_ERROR";
|
|
575
576
|
readonly METHOD_EXECUTION: "METHOD_EXECUTION";
|
|
576
577
|
readonly METHOD_SLOW_EXECUTION: "METHOD_SLOW_EXECUTION";
|
|
577
578
|
readonly LOGGER_DESTINATION_INIT_FAILED: "LOGGER_DESTINATION_INIT_FAILED";
|
|
@@ -1671,6 +1672,84 @@ declare class RequestIdMiddleware implements NestMiddleware {
|
|
|
1671
1672
|
private resolveTenantId;
|
|
1672
1673
|
}
|
|
1673
1674
|
|
|
1675
|
+
/**
|
|
1676
|
+
* Structural mirror of `@bymax-one/nest-core`'s unexpected-error sink contract.
|
|
1677
|
+
*
|
|
1678
|
+
* Layer: server/interfaces — the shapes `PinoUnexpectedErrorSink` implements.
|
|
1679
|
+
* Declared here, not imported: this package has no dependency on nest-core and
|
|
1680
|
+
* does not take one. TypeScript compares the two contracts by shape, so
|
|
1681
|
+
* `PinoUnexpectedErrorSink` binds to nest-core's `BYMAX_UNEXPECTED_ERROR_SINK`
|
|
1682
|
+
* token as long as these shapes stay compatible with nest-core's.
|
|
1683
|
+
*/
|
|
1684
|
+
/**
|
|
1685
|
+
* What nest-core hands the sink for one unexpected (non-`HttpException`) error.
|
|
1686
|
+
*
|
|
1687
|
+
* It never carries the request body, headers, query string or raw URL.
|
|
1688
|
+
*/
|
|
1689
|
+
interface UnexpectedErrorReport {
|
|
1690
|
+
/** The original thrown value, by identity — not necessarily an `Error`. */
|
|
1691
|
+
readonly error: unknown;
|
|
1692
|
+
/** HTTP method, e.g. `'GET'`. */
|
|
1693
|
+
readonly method: string;
|
|
1694
|
+
/**
|
|
1695
|
+
* The matched route template, e.g. `'/invoices/:id'`, or `'<unmatched>'` when
|
|
1696
|
+
* the error was raised before routing. Never the raw URL.
|
|
1697
|
+
*/
|
|
1698
|
+
readonly route: string;
|
|
1699
|
+
/** The request's correlation id. The key is absent when none resolved. */
|
|
1700
|
+
readonly correlationId?: string;
|
|
1701
|
+
/** The active OpenTelemetry trace id. The key is absent when nothing is recording. */
|
|
1702
|
+
readonly traceId?: string;
|
|
1703
|
+
}
|
|
1704
|
+
/**
|
|
1705
|
+
* A receiver for unexpected errors, called synchronously by nest-core's
|
|
1706
|
+
* exception filter before the response is written.
|
|
1707
|
+
*/
|
|
1708
|
+
interface IUnexpectedErrorSink {
|
|
1709
|
+
/**
|
|
1710
|
+
* Record one unexpected error. Must be cheap: it runs on the response path.
|
|
1711
|
+
*
|
|
1712
|
+
* @param report - The error and its request coordinates.
|
|
1713
|
+
*/
|
|
1714
|
+
record(report: UnexpectedErrorReport): void;
|
|
1715
|
+
}
|
|
1716
|
+
|
|
1717
|
+
/**
|
|
1718
|
+
* Writes each unexpected error nest-core reports as one `HTTP_UNEXPECTED_ERROR`
|
|
1719
|
+
* entry at `error` level.
|
|
1720
|
+
*/
|
|
1721
|
+
declare class PinoUnexpectedErrorSink implements IUnexpectedErrorSink {
|
|
1722
|
+
private readonly logger;
|
|
1723
|
+
/**
|
|
1724
|
+
* @param logger - The structured logger the entry is written to. Injected by
|
|
1725
|
+
* token explicitly: the package is bundled without `emitDecoratorMetadata`,
|
|
1726
|
+
* so implicit class-type injection would not resolve.
|
|
1727
|
+
*/
|
|
1728
|
+
constructor(logger: PinoLoggerService);
|
|
1729
|
+
/**
|
|
1730
|
+
* Write one `error` entry for an unexpected error. Never throws.
|
|
1731
|
+
*
|
|
1732
|
+
* The entry carries `err` (name, message, scrubbed stack, cause chain and own
|
|
1733
|
+
* fields, through the configured `err` serializer), `method`, `route` and,
|
|
1734
|
+
* when present, `correlationId`. It deliberately carries nothing else from
|
|
1735
|
+
* the request: the report has no body, headers or query to leak, and this
|
|
1736
|
+
* method adds none.
|
|
1737
|
+
*
|
|
1738
|
+
* `report.traceId` is not written. The trace mixin already stamps the active
|
|
1739
|
+
* span's trace id under the configured `otel.traceIdField` — the same span
|
|
1740
|
+
* nest-core read it from — and writing it here would override that field and
|
|
1741
|
+
* ignore `otel.shouldAutoInjectTraceContext: false`.
|
|
1742
|
+
*
|
|
1743
|
+
* @param report - The error and its request coordinates, from nest-core.
|
|
1744
|
+
* @example
|
|
1745
|
+
* sink.record({ error: new TypeError('x is undefined'), method: 'GET', route: '/invoices/:id', correlationId: 'req-1' })
|
|
1746
|
+
* // → { level: 'error', logKey: 'HTTP_UNEXPECTED_ERROR', msg: 'x is undefined',
|
|
1747
|
+
* // err: { type: 'TypeError', message: 'x is undefined', stack: '…' },
|
|
1748
|
+
* // method: 'GET', route: '/invoices/:id', correlationId: 'req-1' }
|
|
1749
|
+
*/
|
|
1750
|
+
record(report: UnexpectedErrorReport): void;
|
|
1751
|
+
}
|
|
1752
|
+
|
|
1674
1753
|
/**
|
|
1675
1754
|
* Inject a logger into a constructor parameter.
|
|
1676
1755
|
*
|
|
@@ -1865,4 +1944,5 @@ interface LogEntry {
|
|
|
1865
1944
|
*/
|
|
1866
1945
|
declare const LOG_KEYS_CONVENTION_REGEX: RegExp;
|
|
1867
1946
|
|
|
1868
|
-
export { BymaxLoggerModule,
|
|
1947
|
+
export { BymaxLoggerModule, DEFAULT_REDACT_PATHS, DefaultStdoutDestination, HttpAccessLogMiddleware, HttpExceptionFilter, HttpLoggingInterceptor, InjectLogger, LOGGER_DESTINATIONS_TOKEN, LOGGER_OPTIONS_TOKEN, LOGGER_PINO_INSTANCE_TOKEN, LOG_CONTEXT_METADATA_KEY, LOG_CONTEXT_TOKEN, LOG_KEYS_CONVENTION_REGEX, LogContext, LogContextService, LogPerformance, PINO_LEVEL_NAMES, PINO_LEVEL_NUMBERS, PinoLoggerService, PinoUnexpectedErrorSink, PrettyDevDestination, RESERVED_LOG_KEYS, RESERVED_LOG_KEYS_NOT_EMITTED, RequestIdMiddleware, applyAccessLog, applyRequestIdMiddleware };
|
|
1948
|
+
export type { BymaxLoggerModuleAsyncOptions, BymaxLoggerModuleOptions, BymaxLoggerModuleOptionsFactory, EmittedDeploymentResource, EmittedServiceResource, HttpOptions, ILogDestination, IUnexpectedErrorSink, IncomingHeaders, LogContext$1 as LogContextBag, LogEntry, LogLevel, LoggableRequest, LoggableResponse, NextHandler, OtelOptions, PrettyViewOptions, ReservedLogKey, ResolvedBymaxLoggerModuleOptions, ResolvedServiceMetadata, ServiceMetadata, UnexpectedErrorReport };
|
package/dist/server/index.d.ts
CHANGED
|
@@ -572,6 +572,7 @@ declare const RESERVED_LOG_KEYS: Readonly<{
|
|
|
572
572
|
readonly HTTP_REQUEST_ABORTED: "HTTP_REQUEST_ABORTED";
|
|
573
573
|
readonly HTTP_EXCEPTION_HANDLED: "HTTP_EXCEPTION_HANDLED";
|
|
574
574
|
readonly HTTP_EXCEPTION_UNHANDLED: "HTTP_EXCEPTION_UNHANDLED";
|
|
575
|
+
readonly HTTP_UNEXPECTED_ERROR: "HTTP_UNEXPECTED_ERROR";
|
|
575
576
|
readonly METHOD_EXECUTION: "METHOD_EXECUTION";
|
|
576
577
|
readonly METHOD_SLOW_EXECUTION: "METHOD_SLOW_EXECUTION";
|
|
577
578
|
readonly LOGGER_DESTINATION_INIT_FAILED: "LOGGER_DESTINATION_INIT_FAILED";
|
|
@@ -1671,6 +1672,84 @@ declare class RequestIdMiddleware implements NestMiddleware {
|
|
|
1671
1672
|
private resolveTenantId;
|
|
1672
1673
|
}
|
|
1673
1674
|
|
|
1675
|
+
/**
|
|
1676
|
+
* Structural mirror of `@bymax-one/nest-core`'s unexpected-error sink contract.
|
|
1677
|
+
*
|
|
1678
|
+
* Layer: server/interfaces — the shapes `PinoUnexpectedErrorSink` implements.
|
|
1679
|
+
* Declared here, not imported: this package has no dependency on nest-core and
|
|
1680
|
+
* does not take one. TypeScript compares the two contracts by shape, so
|
|
1681
|
+
* `PinoUnexpectedErrorSink` binds to nest-core's `BYMAX_UNEXPECTED_ERROR_SINK`
|
|
1682
|
+
* token as long as these shapes stay compatible with nest-core's.
|
|
1683
|
+
*/
|
|
1684
|
+
/**
|
|
1685
|
+
* What nest-core hands the sink for one unexpected (non-`HttpException`) error.
|
|
1686
|
+
*
|
|
1687
|
+
* It never carries the request body, headers, query string or raw URL.
|
|
1688
|
+
*/
|
|
1689
|
+
interface UnexpectedErrorReport {
|
|
1690
|
+
/** The original thrown value, by identity — not necessarily an `Error`. */
|
|
1691
|
+
readonly error: unknown;
|
|
1692
|
+
/** HTTP method, e.g. `'GET'`. */
|
|
1693
|
+
readonly method: string;
|
|
1694
|
+
/**
|
|
1695
|
+
* The matched route template, e.g. `'/invoices/:id'`, or `'<unmatched>'` when
|
|
1696
|
+
* the error was raised before routing. Never the raw URL.
|
|
1697
|
+
*/
|
|
1698
|
+
readonly route: string;
|
|
1699
|
+
/** The request's correlation id. The key is absent when none resolved. */
|
|
1700
|
+
readonly correlationId?: string;
|
|
1701
|
+
/** The active OpenTelemetry trace id. The key is absent when nothing is recording. */
|
|
1702
|
+
readonly traceId?: string;
|
|
1703
|
+
}
|
|
1704
|
+
/**
|
|
1705
|
+
* A receiver for unexpected errors, called synchronously by nest-core's
|
|
1706
|
+
* exception filter before the response is written.
|
|
1707
|
+
*/
|
|
1708
|
+
interface IUnexpectedErrorSink {
|
|
1709
|
+
/**
|
|
1710
|
+
* Record one unexpected error. Must be cheap: it runs on the response path.
|
|
1711
|
+
*
|
|
1712
|
+
* @param report - The error and its request coordinates.
|
|
1713
|
+
*/
|
|
1714
|
+
record(report: UnexpectedErrorReport): void;
|
|
1715
|
+
}
|
|
1716
|
+
|
|
1717
|
+
/**
|
|
1718
|
+
* Writes each unexpected error nest-core reports as one `HTTP_UNEXPECTED_ERROR`
|
|
1719
|
+
* entry at `error` level.
|
|
1720
|
+
*/
|
|
1721
|
+
declare class PinoUnexpectedErrorSink implements IUnexpectedErrorSink {
|
|
1722
|
+
private readonly logger;
|
|
1723
|
+
/**
|
|
1724
|
+
* @param logger - The structured logger the entry is written to. Injected by
|
|
1725
|
+
* token explicitly: the package is bundled without `emitDecoratorMetadata`,
|
|
1726
|
+
* so implicit class-type injection would not resolve.
|
|
1727
|
+
*/
|
|
1728
|
+
constructor(logger: PinoLoggerService);
|
|
1729
|
+
/**
|
|
1730
|
+
* Write one `error` entry for an unexpected error. Never throws.
|
|
1731
|
+
*
|
|
1732
|
+
* The entry carries `err` (name, message, scrubbed stack, cause chain and own
|
|
1733
|
+
* fields, through the configured `err` serializer), `method`, `route` and,
|
|
1734
|
+
* when present, `correlationId`. It deliberately carries nothing else from
|
|
1735
|
+
* the request: the report has no body, headers or query to leak, and this
|
|
1736
|
+
* method adds none.
|
|
1737
|
+
*
|
|
1738
|
+
* `report.traceId` is not written. The trace mixin already stamps the active
|
|
1739
|
+
* span's trace id under the configured `otel.traceIdField` — the same span
|
|
1740
|
+
* nest-core read it from — and writing it here would override that field and
|
|
1741
|
+
* ignore `otel.shouldAutoInjectTraceContext: false`.
|
|
1742
|
+
*
|
|
1743
|
+
* @param report - The error and its request coordinates, from nest-core.
|
|
1744
|
+
* @example
|
|
1745
|
+
* sink.record({ error: new TypeError('x is undefined'), method: 'GET', route: '/invoices/:id', correlationId: 'req-1' })
|
|
1746
|
+
* // → { level: 'error', logKey: 'HTTP_UNEXPECTED_ERROR', msg: 'x is undefined',
|
|
1747
|
+
* // err: { type: 'TypeError', message: 'x is undefined', stack: '…' },
|
|
1748
|
+
* // method: 'GET', route: '/invoices/:id', correlationId: 'req-1' }
|
|
1749
|
+
*/
|
|
1750
|
+
record(report: UnexpectedErrorReport): void;
|
|
1751
|
+
}
|
|
1752
|
+
|
|
1674
1753
|
/**
|
|
1675
1754
|
* Inject a logger into a constructor parameter.
|
|
1676
1755
|
*
|
|
@@ -1865,4 +1944,5 @@ interface LogEntry {
|
|
|
1865
1944
|
*/
|
|
1866
1945
|
declare const LOG_KEYS_CONVENTION_REGEX: RegExp;
|
|
1867
1946
|
|
|
1868
|
-
export { BymaxLoggerModule,
|
|
1947
|
+
export { BymaxLoggerModule, DEFAULT_REDACT_PATHS, DefaultStdoutDestination, HttpAccessLogMiddleware, HttpExceptionFilter, HttpLoggingInterceptor, InjectLogger, LOGGER_DESTINATIONS_TOKEN, LOGGER_OPTIONS_TOKEN, LOGGER_PINO_INSTANCE_TOKEN, LOG_CONTEXT_METADATA_KEY, LOG_CONTEXT_TOKEN, LOG_KEYS_CONVENTION_REGEX, LogContext, LogContextService, LogPerformance, PINO_LEVEL_NAMES, PINO_LEVEL_NUMBERS, PinoLoggerService, PinoUnexpectedErrorSink, PrettyDevDestination, RESERVED_LOG_KEYS, RESERVED_LOG_KEYS_NOT_EMITTED, RequestIdMiddleware, applyAccessLog, applyRequestIdMiddleware };
|
|
1948
|
+
export type { BymaxLoggerModuleAsyncOptions, BymaxLoggerModuleOptions, BymaxLoggerModuleOptionsFactory, EmittedDeploymentResource, EmittedServiceResource, HttpOptions, ILogDestination, IUnexpectedErrorSink, IncomingHeaders, LogContext$1 as LogContextBag, LogEntry, LogLevel, LoggableRequest, LoggableResponse, NextHandler, OtelOptions, PrettyViewOptions, ReservedLogKey, ResolvedBymaxLoggerModuleOptions, ResolvedServiceMetadata, ServiceMetadata, UnexpectedErrorReport };
|
package/dist/server/index.mjs
CHANGED
|
@@ -182,6 +182,7 @@ var RESERVED_LOG_KEYS = Object.freeze({
|
|
|
182
182
|
HTTP_REQUEST_ABORTED: "HTTP_REQUEST_ABORTED",
|
|
183
183
|
HTTP_EXCEPTION_HANDLED: "HTTP_EXCEPTION_HANDLED",
|
|
184
184
|
HTTP_EXCEPTION_UNHANDLED: "HTTP_EXCEPTION_UNHANDLED",
|
|
185
|
+
HTTP_UNEXPECTED_ERROR: "HTTP_UNEXPECTED_ERROR",
|
|
185
186
|
METHOD_EXECUTION: "METHOD_EXECUTION",
|
|
186
187
|
METHOD_SLOW_EXECUTION: "METHOD_SLOW_EXECUTION",
|
|
187
188
|
LOGGER_DESTINATION_INIT_FAILED: "LOGGER_DESTINATION_INIT_FAILED",
|
|
@@ -2906,6 +2907,63 @@ var ALL_ROUTES = "/";
|
|
|
2906
2907
|
function applyRequestIdMiddleware(consumer, routes = ALL_ROUTES) {
|
|
2907
2908
|
consumer.apply(RequestIdMiddleware, HttpAccessLogMiddleware).forRoutes(routes);
|
|
2908
2909
|
}
|
|
2910
|
+
var PinoUnexpectedErrorSink = class {
|
|
2911
|
+
/**
|
|
2912
|
+
* @param logger - The structured logger the entry is written to. Injected by
|
|
2913
|
+
* token explicitly: the package is bundled without `emitDecoratorMetadata`,
|
|
2914
|
+
* so implicit class-type injection would not resolve.
|
|
2915
|
+
*/
|
|
2916
|
+
constructor(logger) {
|
|
2917
|
+
this.logger = logger;
|
|
2918
|
+
}
|
|
2919
|
+
/**
|
|
2920
|
+
* Write one `error` entry for an unexpected error. Never throws.
|
|
2921
|
+
*
|
|
2922
|
+
* The entry carries `err` (name, message, scrubbed stack, cause chain and own
|
|
2923
|
+
* fields, through the configured `err` serializer), `method`, `route` and,
|
|
2924
|
+
* when present, `correlationId`. It deliberately carries nothing else from
|
|
2925
|
+
* the request: the report has no body, headers or query to leak, and this
|
|
2926
|
+
* method adds none.
|
|
2927
|
+
*
|
|
2928
|
+
* `report.traceId` is not written. The trace mixin already stamps the active
|
|
2929
|
+
* span's trace id under the configured `otel.traceIdField` — the same span
|
|
2930
|
+
* nest-core read it from — and writing it here would override that field and
|
|
2931
|
+
* ignore `otel.shouldAutoInjectTraceContext: false`.
|
|
2932
|
+
*
|
|
2933
|
+
* @param report - The error and its request coordinates, from nest-core.
|
|
2934
|
+
* @example
|
|
2935
|
+
* sink.record({ error: new TypeError('x is undefined'), method: 'GET', route: '/invoices/:id', correlationId: 'req-1' })
|
|
2936
|
+
* // → { level: 'error', logKey: 'HTTP_UNEXPECTED_ERROR', msg: 'x is undefined',
|
|
2937
|
+
* // err: { type: 'TypeError', message: 'x is undefined', stack: '…' },
|
|
2938
|
+
* // method: 'GET', route: '/invoices/:id', correlationId: 'req-1' }
|
|
2939
|
+
*/
|
|
2940
|
+
record(report) {
|
|
2941
|
+
try {
|
|
2942
|
+
const metadata = { method: report.method, route: report.route };
|
|
2943
|
+
if (report.correlationId !== void 0) {
|
|
2944
|
+
metadata["correlationId"] = report.correlationId;
|
|
2945
|
+
}
|
|
2946
|
+
this.logger.errorStructured(
|
|
2947
|
+
RESERVED_LOG_KEYS.HTTP_UNEXPECTED_ERROR,
|
|
2948
|
+
toLoggableError(report.error),
|
|
2949
|
+
void 0,
|
|
2950
|
+
metadata
|
|
2951
|
+
);
|
|
2952
|
+
} catch {
|
|
2953
|
+
}
|
|
2954
|
+
}
|
|
2955
|
+
};
|
|
2956
|
+
PinoUnexpectedErrorSink = __decorateClass([
|
|
2957
|
+
Injectable(),
|
|
2958
|
+
__decorateParam(0, Inject(PinoLoggerService))
|
|
2959
|
+
], PinoUnexpectedErrorSink);
|
|
2960
|
+
function toLoggableError(value) {
|
|
2961
|
+
try {
|
|
2962
|
+
return isErrorLike(value) ? value : sanitizeError(value);
|
|
2963
|
+
} catch {
|
|
2964
|
+
return sanitizeError(value);
|
|
2965
|
+
}
|
|
2966
|
+
}
|
|
2909
2967
|
var INJECT_LOGGER_CONTEXT_METADATA_KEY = "bymax_logger:context";
|
|
2910
2968
|
function InjectLogger(context) {
|
|
2911
2969
|
return (target, propertyKey, parameterIndex) => {
|
|
@@ -2967,4 +3025,4 @@ function LogPerformance(thresholdMs = DEFAULT_THRESHOLD_MS) {
|
|
|
2967
3025
|
// src/shared/constants/log-keys-convention.constants.ts
|
|
2968
3026
|
var LOG_KEYS_CONVENTION_REGEX = /^[A-Z][A-Z0-9_]+_[A-Z][A-Z0-9_]+(_[A-Z][A-Z0-9_]+)?$/;
|
|
2969
3027
|
|
|
2970
|
-
export { BymaxLoggerModule, DEFAULT_REDACT_PATHS, DefaultStdoutDestination, HttpAccessLogMiddleware, HttpExceptionFilter, HttpLoggingInterceptor, InjectLogger, LOGGER_DESTINATIONS_TOKEN, LOGGER_OPTIONS_TOKEN, LOGGER_PINO_INSTANCE_TOKEN, LOG_CONTEXT_METADATA_KEY, LOG_CONTEXT_TOKEN, LOG_KEYS_CONVENTION_REGEX, LogContext, LogContextService, LogPerformance, PINO_LEVEL_NAMES, PINO_LEVEL_NUMBERS, PinoLoggerService, PrettyDevDestination, RESERVED_LOG_KEYS, RESERVED_LOG_KEYS_NOT_EMITTED, RequestIdMiddleware, applyAccessLog, applyRequestIdMiddleware };
|
|
3028
|
+
export { BymaxLoggerModule, DEFAULT_REDACT_PATHS, DefaultStdoutDestination, HttpAccessLogMiddleware, HttpExceptionFilter, HttpLoggingInterceptor, InjectLogger, LOGGER_DESTINATIONS_TOKEN, LOGGER_OPTIONS_TOKEN, LOGGER_PINO_INSTANCE_TOKEN, LOG_CONTEXT_METADATA_KEY, LOG_CONTEXT_TOKEN, LOG_KEYS_CONVENTION_REGEX, LogContext, LogContextService, LogPerformance, PINO_LEVEL_NAMES, PINO_LEVEL_NUMBERS, PinoLoggerService, PinoUnexpectedErrorSink, PrettyDevDestination, RESERVED_LOG_KEYS, RESERVED_LOG_KEYS_NOT_EMITTED, RequestIdMiddleware, applyAccessLog, applyRequestIdMiddleware };
|
package/dist/shared/index.cjs
CHANGED
|
@@ -17,6 +17,7 @@ var RESERVED_LOG_KEYS = Object.freeze({
|
|
|
17
17
|
HTTP_REQUEST_ABORTED: "HTTP_REQUEST_ABORTED",
|
|
18
18
|
HTTP_EXCEPTION_HANDLED: "HTTP_EXCEPTION_HANDLED",
|
|
19
19
|
HTTP_EXCEPTION_UNHANDLED: "HTTP_EXCEPTION_UNHANDLED",
|
|
20
|
+
HTTP_UNEXPECTED_ERROR: "HTTP_UNEXPECTED_ERROR",
|
|
20
21
|
METHOD_EXECUTION: "METHOD_EXECUTION",
|
|
21
22
|
METHOD_SLOW_EXECUTION: "METHOD_SLOW_EXECUTION",
|
|
22
23
|
LOGGER_DESTINATION_INIT_FAILED: "LOGGER_DESTINATION_INIT_FAILED",
|
package/dist/shared/index.d.cts
CHANGED
|
@@ -238,6 +238,7 @@ declare const RESERVED_LOG_KEYS: Readonly<{
|
|
|
238
238
|
readonly HTTP_REQUEST_ABORTED: "HTTP_REQUEST_ABORTED";
|
|
239
239
|
readonly HTTP_EXCEPTION_HANDLED: "HTTP_EXCEPTION_HANDLED";
|
|
240
240
|
readonly HTTP_EXCEPTION_UNHANDLED: "HTTP_EXCEPTION_UNHANDLED";
|
|
241
|
+
readonly HTTP_UNEXPECTED_ERROR: "HTTP_UNEXPECTED_ERROR";
|
|
241
242
|
readonly METHOD_EXECUTION: "METHOD_EXECUTION";
|
|
242
243
|
readonly METHOD_SLOW_EXECUTION: "METHOD_SLOW_EXECUTION";
|
|
243
244
|
readonly LOGGER_DESTINATION_INIT_FAILED: "LOGGER_DESTINATION_INIT_FAILED";
|
|
@@ -269,4 +270,5 @@ declare const RESERVED_LOG_KEYS_NOT_EMITTED: Readonly<{
|
|
|
269
270
|
*/
|
|
270
271
|
type ReservedLogKey = (typeof RESERVED_LOG_KEYS)[keyof typeof RESERVED_LOG_KEYS];
|
|
271
272
|
|
|
272
|
-
export {
|
|
273
|
+
export { LOG_KEYS_CONVENTION_REGEX, RESERVED_LOG_KEYS, RESERVED_LOG_KEYS_NOT_EMITTED };
|
|
274
|
+
export type { EmittedDeploymentResource, EmittedServiceResource, LogEntry, LogLevel, ReservedLogKey, ResolvedServiceMetadata, ServiceMetadata };
|
package/dist/shared/index.d.ts
CHANGED
|
@@ -238,6 +238,7 @@ declare const RESERVED_LOG_KEYS: Readonly<{
|
|
|
238
238
|
readonly HTTP_REQUEST_ABORTED: "HTTP_REQUEST_ABORTED";
|
|
239
239
|
readonly HTTP_EXCEPTION_HANDLED: "HTTP_EXCEPTION_HANDLED";
|
|
240
240
|
readonly HTTP_EXCEPTION_UNHANDLED: "HTTP_EXCEPTION_UNHANDLED";
|
|
241
|
+
readonly HTTP_UNEXPECTED_ERROR: "HTTP_UNEXPECTED_ERROR";
|
|
241
242
|
readonly METHOD_EXECUTION: "METHOD_EXECUTION";
|
|
242
243
|
readonly METHOD_SLOW_EXECUTION: "METHOD_SLOW_EXECUTION";
|
|
243
244
|
readonly LOGGER_DESTINATION_INIT_FAILED: "LOGGER_DESTINATION_INIT_FAILED";
|
|
@@ -269,4 +270,5 @@ declare const RESERVED_LOG_KEYS_NOT_EMITTED: Readonly<{
|
|
|
269
270
|
*/
|
|
270
271
|
type ReservedLogKey = (typeof RESERVED_LOG_KEYS)[keyof typeof RESERVED_LOG_KEYS];
|
|
271
272
|
|
|
272
|
-
export {
|
|
273
|
+
export { LOG_KEYS_CONVENTION_REGEX, RESERVED_LOG_KEYS, RESERVED_LOG_KEYS_NOT_EMITTED };
|
|
274
|
+
export type { EmittedDeploymentResource, EmittedServiceResource, LogEntry, LogLevel, ReservedLogKey, ResolvedServiceMetadata, ServiceMetadata };
|
package/dist/shared/index.mjs
CHANGED
|
@@ -15,6 +15,7 @@ var RESERVED_LOG_KEYS = Object.freeze({
|
|
|
15
15
|
HTTP_REQUEST_ABORTED: "HTTP_REQUEST_ABORTED",
|
|
16
16
|
HTTP_EXCEPTION_HANDLED: "HTTP_EXCEPTION_HANDLED",
|
|
17
17
|
HTTP_EXCEPTION_UNHANDLED: "HTTP_EXCEPTION_UNHANDLED",
|
|
18
|
+
HTTP_UNEXPECTED_ERROR: "HTTP_UNEXPECTED_ERROR",
|
|
18
19
|
METHOD_EXECUTION: "METHOD_EXECUTION",
|
|
19
20
|
METHOD_SLOW_EXECUTION: "METHOD_SLOW_EXECUTION",
|
|
20
21
|
LOGGER_DESTINATION_INIT_FAILED: "LOGGER_DESTINATION_INIT_FAILED",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bymax-one/nest-logger",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.2",
|
|
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",
|
|
@@ -61,8 +61,8 @@
|
|
|
61
61
|
"check:mutants": "node scripts/check-mutation-directives.mjs",
|
|
62
62
|
"check:published": "node scripts/check-published-surface.mjs",
|
|
63
63
|
"clean": "rm -rf dist coverage",
|
|
64
|
-
"lint": "eslint src",
|
|
65
|
-
"lint:fix": "eslint src --fix",
|
|
64
|
+
"lint": "eslint src scripts test bench '*.config.ts' '*.config.mjs' '*.config.cjs'",
|
|
65
|
+
"lint:fix": "eslint src scripts test bench '*.config.ts' '*.config.mjs' '*.config.cjs' --fix",
|
|
66
66
|
"mutation": "stryker run",
|
|
67
67
|
"mutation:full": "node -e \"require('node:fs').rmSync('reports/stryker-incremental.json',{force:true,recursive:true})\" && stryker run",
|
|
68
68
|
"mutation:dry-run": "stryker run --dryRunOnly",
|
|
@@ -142,7 +142,7 @@
|
|
|
142
142
|
"tinybench": "^6.0.2",
|
|
143
143
|
"ts-jest": "^29.4.9",
|
|
144
144
|
"ts-node": "^10.9.2",
|
|
145
|
-
"tsup": "^
|
|
145
|
+
"tsup": "^9.0.0",
|
|
146
146
|
"tsx": "^4.19.2",
|
|
147
147
|
"typescript": "^5.9.3"
|
|
148
148
|
},
|