@authuser/nest 0.2.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,63 @@ This project uses [Semantic Versioning](https://semver.org/).
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [1.1.0] - 2026-09-03
9
+
10
+ ### Added
11
+
12
+ - Add optional RFC 9457 Problem Details responses through
13
+ `errors.format: 'problem-details'`.
14
+ - Allow applications to disable the built-in exception filter or supply their own
15
+ `ExceptionFilter` without giving up the remaining HTTP defaults.
16
+ - Detect repeated `configureHttpApp` calls and non-Fastify Nest applications with
17
+ actionable errors.
18
+
19
+ ### Security
20
+
21
+ - Validate configuration at runtime for JavaScript and dynamically loaded settings,
22
+ including presets, callbacks, logger formats, compression encodings and booleans.
23
+ - Reject missing readiness checks, dynamic internal route patterns, control
24
+ characters in application names and reserved correlation-response headers.
25
+ - Validate root modules, network objects and trusted-proxy values before bootstrap.
26
+
27
+ ### Changed
28
+
29
+ - Append the application duration to an existing `Server-Timing` header instead of
30
+ overwriting timings produced by controllers or other instrumentation.
31
+ - Clarify that browser preflight is installed only when CORS is explicitly enabled.
32
+ - Make the example shutdown smoke test distinguish exit codes from signal exits.
33
+
34
+ ## [1.0.0] - 2026-09-03
35
+
36
+ ### Added
37
+
38
+ - Establish and document the stable 1.x public API contract.
39
+ - Add dynamic liveness and dependency-readiness checks with safe 503 failures.
40
+ - Return validated correlation IDs through a configurable response header.
41
+ - Verify the packed artifact from clean ESM and CommonJS consumers.
42
+ - Add cross-platform CI, release automation, contribution policies, a threat model,
43
+ and a production checklist.
44
+
45
+ ### Security
46
+
47
+ - Hide every 5xx exception message and log the original cause server-side.
48
+ - Remove query strings from error paths and request logs by default.
49
+ - Validate incoming request IDs instead of trusting Fastify's header passthrough.
50
+ - Reject invalid internal paths, overlapping Swagger routes, and invalid correlation
51
+ header names.
52
+ - Add tests for JSON prototype/constructor poisoning, body limits, handler deadlines,
53
+ shared rate-limit stores, and sensitive-data exposure.
54
+
55
+ ### Changed
56
+
57
+ - Make Nest and Fastify logging independently configurable. Setting
58
+ `observability.logger: false` no longer disables the Nest logger; use
59
+ `nest.logger: false` for that behavior.
60
+ - Add an explicit CommonJS export condition while retaining the native ESM build.
61
+ - Mark the entry point side effect so bundlers preserve `reflect-metadata` setup.
62
+ - Raise enforced coverage thresholds to 95% statements/lines/functions and 85%
63
+ branches.
64
+
8
65
  ## [0.2.2] - 2026-09-03
9
66
 
10
67
  ### Added
package/README.md CHANGED
@@ -6,6 +6,7 @@
6
6
  <p align="center">
7
7
  <a href="https://www.npmjs.com/package/@authuser/nest"><img alt="npm" src="https://img.shields.io/npm/v/%40authuser%2Fnest?style=flat-square"></a>
8
8
  <a href="https://www.npmjs.com/package/@authuser/nest"><img alt="downloads" src="https://img.shields.io/npm/dm/%40authuser%2Fnest?style=flat-square"></a>
9
+ <a href="https://github.com/authuser-org/nest/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/authuser-org/nest/actions/workflows/ci.yml/badge.svg"></a>
9
10
  <img alt="Node 22.12+" src="https://img.shields.io/badge/node-%3E%3D22.12-339933?style=flat-square&logo=node.js&logoColor=white">
10
11
  <img alt="NestJS 12" src="https://img.shields.io/badge/NestJS-12-E0234E?style=flat-square&logo=nestjs&logoColor=white">
11
12
  <img alt="Fastify 5" src="https://img.shields.io/badge/Fastify-5-black?style=flat-square&logo=fastify">
@@ -30,7 +31,12 @@ intact while removing repetitive bootstrap code.
30
31
  rate limiting.
31
32
  - Finite request, handler, header and connection timeouts.
32
33
  - Sensitive authorization, cookie and set-cookie log fields are redacted by default.
34
+ - Query strings are omitted from logs and error paths unless explicitly enabled.
33
35
  - JSON logging by default, with an optional standard Nest console format.
36
+ - Correlated request IDs are validated and returned in `x-request-id`.
37
+ - Dynamic liveness and readiness checks fail closed with HTTP 503.
38
+ - Safe errors support the package contract, RFC 9457 Problem Details, or an
39
+ application-provided exception filter.
34
40
  - OpenAPI is optional at runtime. Its code is dynamically imported only when enabled.
35
41
  - HTTP QUERY (RFC 10008) passes through Nest 12/Fastify 5 and is included in CORS defaults.
36
42
  - Native ESM, strict declarations and a TypeScript 7 toolchain.
@@ -84,6 +90,9 @@ That application has Helmet, rate limiting, safe request IDs, strict validation,
84
90
  a 1 MiB body limit, finite timeouts and graceful shutdown hooks. Cross-origin
85
91
  requests are not enabled implicitly.
86
92
 
93
+ `1.x` follows Semantic Versioning: documented public exports and option behavior only
94
+ change incompatibly in a new major version. See the [API stability policy](https://github.com/authuser-org/nest/blob/main/docs/api-stability.md).
95
+
87
96
  ## Presets
88
97
 
89
98
  | Preset | Intended use | Enabled by default |
@@ -138,6 +147,41 @@ openApi: { enabled: true, preHandler: protectInternalRoute },
138
147
  health: { enabled: true, preHandler: protectInternalRoute },
139
148
  ```
140
149
 
150
+ ### Liveness and readiness
151
+
152
+ ```ts
153
+ health: {
154
+ enabled: true,
155
+ check: () => ({ status: 'live' }),
156
+ readiness: {
157
+ path: '/ready',
158
+ check: async () => {
159
+ await database.ping();
160
+ return { status: 'ready' };
161
+ },
162
+ },
163
+ }
164
+ ```
165
+
166
+ A thrown health check is logged internally and returned as a generic HTTP 503. Do
167
+ not include credentials, topology or personal data in successful health responses.
168
+
169
+ ### Error responses
170
+
171
+ The built-in error contract hides all 5xx details and includes the request ID. RFC
172
+ 9457 Problem Details is available without replacing the filter:
173
+
174
+ ```ts
175
+ const app = await createApp({
176
+ rootModule: AppModule,
177
+ errors: { format: 'problem-details' },
178
+ });
179
+ ```
180
+
181
+ Applications with an established contract can use `errors: false` to keep their
182
+ existing global filters, or `errors: { filter }` to install a custom Nest
183
+ `ExceptionFilter`.
184
+
141
185
  ## Configuration examples
142
186
 
143
187
  ### CORS allowlist
@@ -179,7 +223,8 @@ await configureHttpApp(app, {
179
223
  ```
180
224
 
181
225
  Call `configureHttpApp` before `app.init()` or `app.listen()` so Fastify can register
182
- its plugins and routes.
226
+ its plugins and routes. When supplying your own adapter, request-ID generation and
227
+ network limits remain adapter responsibilities; `createApp` configures those safely.
183
228
 
184
229
  ## Public API
185
230
 
@@ -187,13 +232,17 @@ its plugins and routes.
187
232
  - `configureHttpApp(app, options)` — configure an existing Fastify-based Nest app.
188
233
  - `Public()` and `Roles(...roles)` — metadata helpers for your own guards.
189
234
  - `HttpExceptionFilter` — the default safe JSON exception filter.
235
+ - Public TypeScript contracts for configuration, health checks and error responses.
236
+ - Optional `HttpErrorResponse` and RFC 9457 `ProblemDetailsResponse` contracts.
190
237
 
191
238
  The decorators intentionally do not provide authentication. Authentication policy
192
239
  belongs to the consuming application; pretending otherwise would create a dangerous
193
240
  security boundary.
194
241
 
195
242
  See the [complete option reference](https://github.com/authuser-org/nest/blob/main/docs/configuration.md), the
196
- [security model](https://github.com/authuser-org/nest/blob/main/docs/security.md), and the [performance guide](https://github.com/authuser-org/nest/blob/main/docs/performance.md).
243
+ [security model](https://github.com/authuser-org/nest/blob/main/docs/security.md), the
244
+ [production checklist](https://github.com/authuser-org/nest/blob/main/docs/production.md), and the
245
+ [performance guide](https://github.com/authuser-org/nest/blob/main/docs/performance.md).
197
246
 
198
247
  ## Performance notes
199
248
 
@@ -225,6 +274,8 @@ required integrations as normal dependencies. See the
225
274
  ```bash
226
275
  npm install
227
276
  npm run check
277
+ npm run test:coverage
278
+ npm run test:package
228
279
  ```
229
280
 
230
281
  An executable API and an importable Postman collection are available in the
package/SECURITY.md ADDED
@@ -0,0 +1,17 @@
1
+ # Security policy
2
+
3
+ ## Supported versions
4
+
5
+ Security fixes are provided for the latest minor release. Until version 1.0, a
6
+ security fix may include a documented breaking change when that is the safest
7
+ course.
8
+
9
+ Only maintained Node.js release lines accepted by `package.json` are supported.
10
+
11
+ ## Report a vulnerability
12
+
13
+ Do not open a public issue. Send a private report to `security@authuser.es` with
14
+ the affected version, reproduction steps and expected impact. You should receive
15
+ an acknowledgement within three business days.
16
+
17
+ Never include production credentials or personal data in a report.
package/SUPPORT.md ADDED
@@ -0,0 +1,11 @@
1
+ # Support
2
+
3
+ The latest `1.x` minor release receives bug and security fixes. Supported Node, Nest
4
+ and Fastify ranges are declared in `package.json`.
5
+
6
+ Use GitHub Issues for reproducible bugs and focused feature proposals. Include the
7
+ package version, Node version, package manager, minimal reproduction and relevant
8
+ sanitized logs. General Nest or Fastify usage questions should use their respective
9
+ community support channels.
10
+
11
+ Report vulnerabilities privately according to [SECURITY.md](./SECURITY.md).
@@ -1 +1 @@
1
- {"version":3,"file":"configure-http-app.d.ts","sourceRoot":"","sources":["../src/configure-http-app.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAKvE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAE1D,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,sBAAsB,EAC3B,KAAK,GAAE,uBAA4B,GAClC,OAAO,CAAC,sBAAsB,CAAC,CAgEjC"}
1
+ {"version":3,"file":"configure-http-app.d.ts","sourceRoot":"","sources":["../src/configure-http-app.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAKvE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAK1D,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,sBAAsB,EAC3B,KAAK,GAAE,uBAA4B,GAClC,OAAO,CAAC,sBAAsB,CAAC,CA+FjC"}
@@ -2,9 +2,19 @@ import { ValidationPipe, VersioningType } from '@nestjs/common';
2
2
  import { HttpExceptionFilter } from './http-exception.filter.js';
3
3
  import { registerOpenApi } from './openapi.js';
4
4
  import { resolveOptions } from './options.js';
5
+ const CONFIGURED = Symbol.for('@authuser/nest:configured');
5
6
  export async function configureHttpApp(app, input = {}) {
7
+ const state = app;
8
+ if (state[CONFIGURED]) {
9
+ throw new Error('This Nest application has already been configured by @authuser/nest');
10
+ }
11
+ const adapter = app.getHttpAdapter();
12
+ if (adapter.getType() !== 'fastify') {
13
+ throw new TypeError('@authuser/nest requires a Nest application using FastifyAdapter');
14
+ }
6
15
  const options = resolveOptions(input);
7
- const fastify = app.getHttpAdapter().getInstance();
16
+ Object.defineProperty(state, CONFIGURED, { value: true });
17
+ const fastify = adapter.getInstance();
8
18
  if (options.security.helmet) {
9
19
  const { default: helmet } = await import('@fastify/helmet');
10
20
  await fastify.register(helmet, {
@@ -37,7 +47,9 @@ export async function configureHttpApp(app, input = {}) {
37
47
  }
38
48
  if (options.validation !== false)
39
49
  app.useGlobalPipes(new ValidationPipe(options.validation));
40
- app.useGlobalFilters(new HttpExceptionFilter());
50
+ if (options.errors !== false) {
51
+ app.useGlobalFilters(options.errors.filter ?? new HttpExceptionFilter(options.errors.format));
52
+ }
41
53
  if (options.shutdownHooks)
42
54
  app.enableShutdownHooks();
43
55
  if (options.observability.responseTimeHeader) {
@@ -48,18 +60,51 @@ export async function configureHttpApp(app, input = {}) {
48
60
  fastify.addHook('onSend', async (request, reply, payload) => {
49
61
  const start = startTimes.get(request);
50
62
  if (typeof start === 'bigint') {
51
- reply.header('server-timing', `app;dur=${(Number(process.hrtime.bigint() - start) / 1e6).toFixed(2)}`);
63
+ appendHeader(reply, 'server-timing', `app;dur=${(Number(process.hrtime.bigint() - start) / 1e6).toFixed(2)}`);
52
64
  }
53
65
  return payload;
54
66
  });
55
67
  }
68
+ if (options.observability.requestIdResponseHeader !== false) {
69
+ const header = options.observability.requestIdResponseHeader;
70
+ fastify.addHook('onRequest', async (request, reply) => {
71
+ reply.header(header, request.id);
72
+ });
73
+ }
56
74
  if (options.health.enabled) {
57
75
  fastify.get(options.health.path, {
58
76
  config: { rateLimit: false },
59
77
  ...(options.health.preHandler ? { preHandler: options.health.preHandler } : {}),
60
- }, async (_request, reply) => reply.send(options.health.response));
78
+ }, healthHandler(options.health.check, options.health.response));
79
+ }
80
+ if (options.health.readiness !== false) {
81
+ const readiness = options.health.readiness;
82
+ fastify.get(readiness.path, {
83
+ config: { rateLimit: false },
84
+ ...(readiness.preHandler ? { preHandler: readiness.preHandler } : {}),
85
+ }, healthHandler(readiness.check, { status: 'ready' }));
61
86
  }
62
87
  await registerOpenApi(app, fastify, options.openApi);
63
88
  return app;
64
89
  }
90
+ function appendHeader(reply, name, value) {
91
+ const current = reply.getHeader(name);
92
+ if (current === undefined) {
93
+ reply.header(name, value);
94
+ return;
95
+ }
96
+ const existing = Array.isArray(current) ? current.join(', ') : String(current);
97
+ reply.header(name, `${existing}, ${value}`);
98
+ }
99
+ function healthHandler(check, fallback) {
100
+ return async (request, reply) => {
101
+ try {
102
+ return reply.send(check ? await check(request) : fallback);
103
+ }
104
+ catch (error) {
105
+ request.log.error({ err: error }, 'Health check failed');
106
+ return reply.status(503).send({ status: 'unavailable' });
107
+ }
108
+ };
109
+ }
65
110
  //# sourceMappingURL=configure-http-app.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"configure-http-app.js","sourceRoot":"","sources":["../src/configure-http-app.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"configure-http-app.js","sourceRoot":"","sources":["../src/configure-http-app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGhE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAI9C,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;AAE3D,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,GAA2B,EAC3B,KAAK,GAA4B,EAAE;IAEnC,MAAM,KAAK,GAAG,GAA0D,CAAC;IACzE,IAAI,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,qEAAqE,CAAC,CAAC;IACzF,CAAC;IACD,MAAM,OAAO,GAAG,GAAG,CAAC,cAAc,EAAE,CAAC;IACrC,IAAI,OAAO,CAAC,OAAO,EAAE,KAAK,SAAS,EAAE,CAAC;QACpC,MAAM,IAAI,SAAS,CAAC,iEAAiE,CAAC,CAAC;IACzF,CAAC;IACD,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACtC,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAE1D,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,EAAqB,CAAC;IAEzD,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC5B,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;QAC5D,MAAM,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE;YAC7B,MAAM,EAAE,IAAI;YACZ,qBAAqB,EAAE,OAAO,CAAC,QAAQ,CAAC,qBAAqB;SAC9D,CAAC,CAAC;IACL,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QACpC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC;QACxD,MAAM,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACtD,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,CAAC,SAAS,KAAK,KAAK,IAAI,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;QAC/E,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;QACnE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,gBAAgB,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC9E,MAAM,OAAO,CAAC,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;IACtD,CAAC;IAED,IAAI,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;QAChC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;QAChE,MAAM,OAAO,CAAC,QAAQ,CAAC,QAAQ,EAAE;YAC/B,SAAS,EAAE,OAAO,CAAC,WAAW,CAAC,SAAS;YACxC,SAAS,EAAE,OAAO,CAAC,WAAW,CAAC,SAAS;SACzC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,OAAO,CAAC,SAAS;QAAE,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAC9D,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACvB,GAAG,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAU,KAAK,IAAI;YAC9C,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,GAAG,EAAE;YAC9B,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC1B,CAAC;IACD,IAAI,OAAO,CAAC,UAAU,KAAK,KAAK;QAAE,GAAG,CAAC,cAAc,CAAC,IAAI,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IAC7F,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QAC7B,GAAG,CAAC,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,mBAAmB,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IAChG,CAAC;IACD,IAAI,OAAO,CAAC,aAAa;QAAE,GAAG,CAAC,mBAAmB,EAAE,CAAC;IAErD,IAAI,OAAO,CAAC,aAAa,CAAC,kBAAkB,EAAE,CAAC;QAC7C,MAAM,UAAU,GAAG,IAAI,OAAO,EAAkB,CAAC;QACjD,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YAC7C,UAAU,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YAC1D,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACtC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC9B,YAAY,CACV,KAAK,EACL,eAAe,EACf,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CACxE,CAAC;YACJ,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,OAAO,CAAC,aAAa,CAAC,uBAAuB,KAAK,KAAK,EAAE,CAAC;QAC5D,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,uBAAuB,CAAC;QAC7D,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YACpD,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE;YAC/B,MAAM,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE;YAC5B,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChF,EAAE,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,CAAC,SAAS,KAAK,KAAK,EAAE,CAAC;QACvC,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE;YAC1B,MAAM,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE;YAC5B,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,SAAS,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACtE,EAAE,aAAa,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACrD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,YAAY,CAAC,KAAmB,EAAE,IAAY,EAAE,KAAa;IACpE,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC1B,OAAO;IACT,CAAC;IACD,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/E,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,QAAQ,KAAK,KAAK,EAAE,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,aAAa,CACpB,KAA8B,EAC9B,QAA2C;IAE3C,OAAO,KAAK,EAAE,OAAuB,EAAE,KAAmB,EAAE,EAAE;QAC5D,IAAI,CAAC;YACH,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC7D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,qBAAqB,CAAC,CAAC;YACzD,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"create-app.d.ts","sourceRoot":"","sources":["../src/create-app.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,0BAA0B,CAAC;AAIlC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAInD,wBAAsB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAuC1F"}
1
+ {"version":3,"file":"create-app.d.ts","sourceRoot":"","sources":["../src/create-app.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,0BAA0B,CAAC;AAIlC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAInD,wBAAsB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAkD1F"}
@@ -8,11 +8,19 @@ import { resolveOptions } from './options.js';
8
8
  const SAFE_REQUEST_ID = /^[A-Za-z0-9._:-]{1,128}$/;
9
9
  export async function createApp(options) {
10
10
  const resolved = resolveOptions(options);
11
+ if (typeof options.rootModule !== 'function') {
12
+ throw new TypeError('rootModule must be a Nest module class');
13
+ }
14
+ if (options.network !== undefined && (typeof options.network !== 'object'
15
+ || options.network === null
16
+ || Array.isArray(options.network))) {
17
+ throw new TypeError('network must be an object');
18
+ }
11
19
  const network = options.network ?? {};
12
20
  validateNetworkOptions(network);
13
21
  const loggerOptions = resolved.observability.loggerFormat === 'nest'
14
22
  && resolved.observability.logger !== false
15
- ? { loggerInstance: new NestFastifyLogger(resolved.appName) }
23
+ ? { loggerInstance: new NestFastifyLogger(resolved.appName, resolved.observability.includeQueryString) }
16
24
  : { logger: resolved.observability.logger };
17
25
  const adapter = new FastifyAdapter({
18
26
  ...loggerOptions,
@@ -30,17 +38,22 @@ export async function createApp(options) {
30
38
  return503OnClosing: true,
31
39
  onProtoPoisoning: 'error',
32
40
  onConstructorPoisoning: 'error',
33
- requestIdHeader: 'x-request-id',
41
+ // Fastify trusts requestIdHeader verbatim; validate it ourselves in genReqId.
42
+ requestIdHeader: false,
34
43
  genReqId: safeRequestId,
35
44
  });
36
45
  adapter.getInstance().server.headersTimeout = network.headersTimeout ?? 30_000;
37
- const nestOptions = resolved.observability.logger === false
38
- ? { ...options.nest, logger: false }
39
- : { ...options.nest };
40
- const app = await NestFactory.create(options.rootModule, adapter, nestOptions);
46
+ const app = await NestFactory.create(options.rootModule, adapter, options.nest ?? {});
41
47
  return configureHttpApp(app, options);
42
48
  }
43
49
  function validateNetworkOptions(network) {
50
+ const trustProxy = network.trustProxy;
51
+ if (trustProxy !== undefined
52
+ && typeof trustProxy !== 'boolean'
53
+ && typeof trustProxy !== 'string'
54
+ && (!Array.isArray(trustProxy) || trustProxy.some((entry) => typeof entry !== 'string'))) {
55
+ throw new TypeError('Network option trustProxy must be a boolean, string, or string array');
56
+ }
44
57
  const values = {
45
58
  bodyLimit: network.bodyLimit,
46
59
  maxParamLength: network.maxParamLength,
@@ -1 +1 @@
1
- {"version":3,"file":"create-app.js","sourceRoot":"","sources":["../src/create-app.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"create-app.js","sourceRoot":"","sources":["../src/create-app.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,8 @@
1
1
  import { ArgumentsHost, type ExceptionFilter } from '@nestjs/common';
2
+ import type { ErrorResponseFormat } from './types.js';
2
3
  export declare class HttpExceptionFilter implements ExceptionFilter {
4
+ private readonly format;
5
+ constructor(format?: ErrorResponseFormat);
3
6
  catch(exception: unknown, host: ArgumentsHost): void;
4
7
  }
5
8
  //# sourceMappingURL=http-exception.filter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"http-exception.filter.d.ts","sourceRoot":"","sources":["../src/http-exception.filter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EAIb,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;AAGxB,qBAAa,mBAAoB,YAAW,eAAe;IACzD,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI,CAqBnD;CACF"}
1
+ {"version":3,"file":"http-exception.filter.d.ts","sourceRoot":"","sources":["../src/http-exception.filter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EAIb,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EACV,mBAAmB,EAGpB,MAAM,YAAY,CAAC;AAEpB,qBAAa,mBAAoB,YAAW,eAAe;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM;IAAnC,YAA6B,MAAM,GAAE,mBAAgC,EAIpE;IAED,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI,CAuCnD;CACF"}
@@ -1,5 +1,12 @@
1
1
  import { Catch, HttpException, HttpStatus, } from '@nestjs/common';
2
2
  export class HttpExceptionFilter {
3
+ format;
4
+ constructor(format = 'authuser') {
5
+ this.format = format;
6
+ if (format !== 'authuser' && format !== 'problem-details') {
7
+ throw new TypeError('Error response format must be authuser or problem-details');
8
+ }
9
+ }
3
10
  catch(exception, host) {
4
11
  const context = host.switchToHttp();
5
12
  const reply = context.getResponse();
@@ -8,18 +15,35 @@ export class HttpExceptionFilter {
8
15
  const status = httpException?.getStatus() ?? HttpStatus.INTERNAL_SERVER_ERROR;
9
16
  const response = httpException?.getResponse();
10
17
  const details = typeof response === 'object' && response !== null ? response : {};
11
- const message = typeof response === 'string'
12
- ? response
13
- : getMessage(details) ?? (status === 500 ? 'Internal server error' : 'Request failed');
14
- if (status === 500)
18
+ const message = status >= 500
19
+ ? 'Internal server error'
20
+ : typeof response === 'string'
21
+ ? response
22
+ : getMessage(details) ?? 'Request failed';
23
+ if (status >= 500)
15
24
  request.log.error({ err: exception }, 'Unhandled request error');
16
- void reply.status(status).send({
25
+ const path = request.url.split('?', 1)[0] ?? request.url;
26
+ if (this.format === 'problem-details') {
27
+ const body = {
28
+ type: 'about:blank',
29
+ title: statusTitle(status),
30
+ status,
31
+ detail: typeof message === 'string' ? message : 'Request validation failed',
32
+ instance: path,
33
+ requestId: request.id,
34
+ ...(status < 500 && typeof message !== 'string' ? { errors: message } : {}),
35
+ };
36
+ void reply.status(status).type('application/problem+json').send(body);
37
+ return;
38
+ }
39
+ const body = {
17
40
  statusCode: status,
18
41
  error: HttpStatus[status] ?? 'Error',
19
42
  message,
20
43
  requestId: request.id,
21
- path: request.url,
22
- });
44
+ path,
45
+ };
46
+ void reply.status(status).send(body);
23
47
  }
24
48
  }
25
49
  Catch()(HttpExceptionFilter);
@@ -49,4 +73,10 @@ function getHttpException(exception) {
49
73
  function isHttpErrorStatus(value) {
50
74
  return typeof value === 'number' && Number.isInteger(value) && value >= 400 && value <= 599;
51
75
  }
76
+ function statusTitle(status) {
77
+ const name = HttpStatus[status];
78
+ if (typeof name !== 'string')
79
+ return 'Error';
80
+ return name.toLowerCase().replaceAll('_', ' ').replace(/\b\w/g, (letter) => letter.toUpperCase());
81
+ }
52
82
  //# sourceMappingURL=http-exception.filter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"http-exception.filter.js","sourceRoot":"","sources":["../src/http-exception.filter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"http-exception.filter.js","sourceRoot":"","sources":["../src/http-exception.filter.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -3,5 +3,5 @@ export { configureHttpApp } from './configure-http-app.js';
3
3
  export { createApp } from './create-app.js';
4
4
  export { Public, Roles, IS_PUBLIC_KEY, ROLES_KEY } from './decorators.js';
5
5
  export { HttpExceptionFilter } from './http-exception.filter.js';
6
- export type { CompressionOptions, ConfigureHttpAppOptions, CorsOptions, CreateAppOptions, HealthOptions, NetworkOptions, ObservabilityOptions, OpenApiOptions, RateLimitOptions, SecurityOptions, SecurityPreset, } from './types.js';
6
+ export type { CompressionOptions, ConfigureHttpAppOptions, CorsOptions, CreateAppOptions, ErrorOptions, ErrorResponseFormat, HealthCheck, HealthOptions, HttpErrorResponse, NetworkOptions, ObservabilityOptions, OpenApiOptions, ProblemDetailsResponse, RateLimitOptions, ReadinessOptions, SecurityOptions, SecurityPreset, } from './types.js';
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAE1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,YAAY,EACV,kBAAkB,EAClB,uBAAuB,EACvB,WAAW,EACX,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,cAAc,GACf,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAE1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,YAAY,EACV,kBAAkB,EAClB,uBAAuB,EACvB,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,EACnB,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,oBAAoB,EACpB,cAAc,EACd,sBAAsB,EACtB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,cAAc,GACf,MAAM,YAAY,CAAC"}
@@ -4,6 +4,7 @@ import type { Bindings } from 'pino';
4
4
  /** Adapts Fastify's structured logger contract to Nest's standard console logger. */
5
5
  export declare class NestFastifyLogger implements FastifyBaseLogger {
6
6
  private readonly context;
7
+ private readonly includeQueryString;
7
8
  private readonly bindings;
8
9
  private readonly logger;
9
10
  level: string;
@@ -14,7 +15,7 @@ export declare class NestFastifyLogger implements FastifyBaseLogger {
14
15
  readonly warn: FastifyLogFn;
15
16
  readonly trace: FastifyLogFn;
16
17
  readonly silent: FastifyLogFn;
17
- constructor(context: string, bindings?: Bindings, logger?: Logger);
18
+ constructor(context: string, includeQueryString?: boolean, bindings?: Bindings, logger?: Logger);
18
19
  child(bindings: Bindings): FastifyBaseLogger;
19
20
  private write;
20
21
  }
@@ -1 +1 @@
1
- {"version":3,"file":"nest-fastify.logger.d.ts","sourceRoot":"","sources":["../src/nest-fastify.logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAIrC,qFAAqF;AACrF,qBAAa,iBAAkB,YAAW,iBAAiB;IAYvD,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAbzB,KAAK,SAAU;IAEf,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAoD;IAC/E,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAqD;IACjF,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAqD;IACjF,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAqD;IACjF,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAoD;IAC/E,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAqD;IACjF,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAmB;IAEhD,YACmB,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,QAAa,EACvB,MAAM,SAAsB,EAC3C;IAEJ,KAAK,CAAC,QAAQ,EAAE,QAAQ,GAAG,iBAAiB,CAE3C;IAED,OAAO,CAAC,KAAK;CAsBd"}
1
+ {"version":3,"file":"nest-fastify.logger.d.ts","sourceRoot":"","sources":["../src/nest-fastify.logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAIrC,qFAAqF;AACrF,qBAAa,iBAAkB,YAAW,iBAAiB;IAYvD,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAdzB,KAAK,SAAU;IAEf,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAoD;IAC/E,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAqD;IACjF,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAqD;IACjF,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAqD;IACjF,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAoD;IAC/E,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAqD;IACjF,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAmB;IAEhD,YACmB,OAAO,EAAE,MAAM,EACf,kBAAkB,UAAQ,EAC1B,QAAQ,GAAE,QAAa,EACvB,MAAM,SAAsB,EAC3C;IAEJ,KAAK,CAAC,QAAQ,EAAE,QAAQ,GAAG,iBAAiB,CAO3C;IAED,OAAO,CAAC,KAAK;CAsBd"}
@@ -2,6 +2,7 @@ import { Logger } from '@nestjs/common';
2
2
  /** Adapts Fastify's structured logger contract to Nest's standard console logger. */
3
3
  export class NestFastifyLogger {
4
4
  context;
5
+ includeQueryString;
5
6
  bindings;
6
7
  logger;
7
8
  level = 'info';
@@ -12,16 +13,17 @@ export class NestFastifyLogger {
12
13
  warn = (...args) => this.write('warn', args);
13
14
  trace = (...args) => this.write('trace', args);
14
15
  silent = () => undefined;
15
- constructor(context, bindings = {}, logger = new Logger(context)) {
16
+ constructor(context, includeQueryString = false, bindings = {}, logger = new Logger(context)) {
16
17
  this.context = context;
18
+ this.includeQueryString = includeQueryString;
17
19
  this.bindings = bindings;
18
20
  this.logger = logger;
19
21
  }
20
22
  child(bindings) {
21
- return new NestFastifyLogger(this.context, { ...this.bindings, ...bindings }, this.logger);
23
+ return new NestFastifyLogger(this.context, this.includeQueryString, { ...this.bindings, ...bindings }, this.logger);
22
24
  }
23
25
  write(level, args) {
24
- const message = formatLogMessage(args, this.bindings);
26
+ const message = formatLogMessage(args, this.bindings, this.includeQueryString);
25
27
  switch (level) {
26
28
  case 'error':
27
29
  this.logger.error(message);
@@ -43,7 +45,7 @@ export class NestFastifyLogger {
43
45
  }
44
46
  }
45
47
  }
46
- function formatLogMessage(args, bindings) {
48
+ function formatLogMessage(args, bindings, includeQueryString) {
47
49
  const data = isRecord(args[0]) ? args[0] : undefined;
48
50
  const text = args.find((value) => typeof value === 'string') ?? 'Fastify event';
49
51
  const details = [];
@@ -52,8 +54,9 @@ function formatLogMessage(args, bindings) {
52
54
  const error = data && isRecord(data.err) ? data.err : undefined;
53
55
  if (typeof request?.method === 'string')
54
56
  details.push(request.method);
55
- if (typeof request?.url === 'string')
56
- details.push(request.url);
57
+ if (typeof request?.url === 'string') {
58
+ details.push(includeQueryString ? request.url : request.url.split('?', 1)[0] ?? '');
59
+ }
57
60
  if (typeof response?.statusCode === 'number')
58
61
  details.push(`status=${response.statusCode}`);
59
62
  if (typeof data?.responseTime === 'number')
@@ -1 +1 @@
1
- {"version":3,"file":"nest-fastify.logger.js","sourceRoot":"","sources":["../src/nest-fastify.logger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"nest-fastify.logger.js","sourceRoot":"","sources":["../src/nest-fastify.logger.ts"],"names":[],"mappings":"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"}
package/dist/options.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { CompressionOptions, ConfigureHttpAppOptions, CorsOptions, HealthOptions, OpenApiOptions, RateLimitOptions, SecurityPreset } from './types.js';
1
+ import type { CompressionOptions, ConfigureHttpAppOptions, CorsOptions, ErrorOptions, ErrorResponseFormat, HealthOptions, HealthCheck, OpenApiOptions, RateLimitOptions, SecurityPreset } from './types.js';
2
2
  export interface ResolvedOptions {
3
3
  appName: string;
4
4
  preset: SecurityPreset;
@@ -13,8 +13,23 @@ export interface ResolvedOptions {
13
13
  };
14
14
  compression: Required<CompressionOptions>;
15
15
  openApi: Required<Omit<OpenApiOptions, 'preHandler'>> & Pick<OpenApiOptions, 'preHandler'>;
16
- health: Required<Omit<HealthOptions, 'preHandler'>> & Pick<HealthOptions, 'preHandler'>;
16
+ health: {
17
+ enabled: boolean;
18
+ path: string;
19
+ response: Readonly<Record<string, unknown>>;
20
+ check?: HealthCheck;
21
+ preHandler?: HealthOptions['preHandler'];
22
+ readiness: false | {
23
+ path: string;
24
+ check: HealthCheck;
25
+ preHandler?: HealthOptions['preHandler'];
26
+ };
27
+ };
17
28
  observability: Required<NonNullable<ConfigureHttpAppOptions['observability']>>;
29
+ errors: false | {
30
+ format: ErrorResponseFormat;
31
+ filter?: ErrorOptions['filter'];
32
+ };
18
33
  shutdownHooks: boolean;
19
34
  }
20
35
  export declare function resolveOptions(options: ConfigureHttpAppOptions): ResolvedOptions;