@dunx/http 2.3.1 → 2.5.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/dist/index.js CHANGED
@@ -1,17 +1,21 @@
1
1
  // @bun
2
2
  import {
3
3
  HttpStatusCode,
4
+ TRACEPARENT_HEADER,
5
+ TRACESTATE_HEADER,
6
+ TraceContext,
4
7
  __decorateElement,
5
8
  __decoratorMetadata,
6
9
  __decoratorStart,
7
10
  __privateAdd,
8
11
  __privateGet,
9
12
  __runInitializers
10
- } from "./chunk-sz4pvqxy.js";
13
+ } from "./chunk-jh7jk0bn.js";
11
14
 
12
15
  // src/route/marker.ts
13
16
  var ROUTE = Symbol.for("dunx.route");
14
17
  var CONTROLLER = Symbol.for("dunx.controller");
18
+ var defaultStatusFor = (method) => method === "POST" ? HttpStatusCode.CREATED : HttpStatusCode.OK;
15
19
  var resolvePath = (path) => typeof path === "function" ? path() : path;
16
20
  var markRoute = (target, meta) => {
17
21
  Object.defineProperty(target, ROUTE, { value: meta, configurable: true });
@@ -281,6 +285,7 @@ var buildContext = (route) => {
281
285
  handler: route.handlerName,
282
286
  method: route.method,
283
287
  path: route.path,
288
+ parsesBody: route.options?.body !== undefined,
284
289
  get: (key) => record.get(key.id)
285
290
  });
286
291
  };
@@ -970,6 +975,25 @@ import {
970
975
  RequestContext as RequestContext2
971
976
  } from "@dunx/core";
972
977
 
978
+ // src/server/raw-body.ts
979
+ var WANTED = Symbol.for("dunx.http.rawBody.wanted");
980
+ var TEXT = Symbol.for("dunx.http.rawBody.text");
981
+
982
+ class RawBody {
983
+ static want(req) {
984
+ req[WANTED] = true;
985
+ }
986
+ static wanted(req) {
987
+ return req[WANTED] === true;
988
+ }
989
+ static record(req, text) {
990
+ req[TEXT] = text;
991
+ }
992
+ static read(req) {
993
+ return req[TEXT];
994
+ }
995
+ }
996
+
973
997
  // src/server/request-id.ts
974
998
  var REQUEST_ID_HEADER = "x-request-id";
975
999
  var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
@@ -1016,6 +1040,7 @@ class RequestLoggingMiddleware {
1016
1040
  #ignorePrefix;
1017
1041
  #correlateIgnored;
1018
1042
  #correlate;
1043
+ #trace;
1019
1044
  constructor(logger, context, options = {}) {
1020
1045
  this.logger = logger;
1021
1046
  this.context = context;
@@ -1026,6 +1051,7 @@ class RequestLoggingMiddleware {
1026
1051
  this.#ignorePrefix = options.ignorePrefix ?? [];
1027
1052
  this.#correlateIgnored = options.correlateIgnored ?? false;
1028
1053
  this.#correlate = options.correlate ?? true;
1054
+ this.#trace = options.trace ?? false;
1029
1055
  }
1030
1056
  #ignored(path) {
1031
1057
  if (this.#ignore.size > 0 && this.#ignore.has(path))
@@ -1051,14 +1077,22 @@ class RequestLoggingMiddleware {
1051
1077
  flow: "http",
1052
1078
  context: `${ctx.controller}.${ctx.handler}`
1053
1079
  };
1054
- return this.#correlate ? this.context.runWithContext(scope, () => this.#begin(req, url, mark, path, requestId, started, next, undefined)) : this.#begin(req, url, mark, path, requestId, started, next, scope);
1080
+ if (this.#trace) {
1081
+ const trace = TraceContext.adopt(req, requestId);
1082
+ scope.traceId = trace.traceId;
1083
+ scope.spanId = trace.spanId;
1084
+ if (trace.parentSpanId !== undefined) {
1085
+ scope.parentSpanId = trace.parentSpanId;
1086
+ }
1087
+ }
1088
+ return this.#correlate ? this.context.runWithContext(scope, () => this.#begin(req, ctx, url, mark, path, requestId, started, next, undefined)) : this.#begin(req, ctx, url, mark, path, requestId, started, next, scope);
1055
1089
  }
1056
- #begin(req, url, mark, path, requestId, started, next, scope) {
1090
+ #begin(req, ctx, url, mark, path, requestId, started, next, scope) {
1057
1091
  const request = {};
1058
1092
  if (mark !== -1) {
1059
1093
  request["query"] = Object.fromEntries(new URLSearchParams(url.slice(mark + 1)));
1060
1094
  }
1061
- const body = this.#body(req);
1095
+ const body = this.#body(req, ctx);
1062
1096
  if (body === undefined) {
1063
1097
  request["userAgent"] = req.headers.get("user-agent");
1064
1098
  return this.#dispatch(req, path, requestId, started, request, next, scope);
@@ -1070,6 +1104,18 @@ class RequestLoggingMiddleware {
1070
1104
  return this.#dispatch(req, path, requestId, started, request, next, scope);
1071
1105
  });
1072
1106
  }
1107
+ #shared(req, request) {
1108
+ if (!this.#requestBody)
1109
+ return;
1110
+ if (request["body"] !== undefined)
1111
+ return;
1112
+ const text = RawBody.read(req);
1113
+ if (text === undefined)
1114
+ return;
1115
+ const value = parse(text, this.#limit);
1116
+ if (value !== undefined)
1117
+ request["body"] = value;
1118
+ }
1073
1119
  #correlated(req, ctx, path, next) {
1074
1120
  const requestId = RequestIds.assign(req);
1075
1121
  const stamp = (response) => {
@@ -1100,6 +1146,7 @@ class RequestLoggingMiddleware {
1100
1146
  });
1101
1147
  }
1102
1148
  #failed(req, path, started, request, error, scope) {
1149
+ this.#shared(req, request);
1103
1150
  const status = error instanceof HttpError ? error.status : HttpStatusCode.INTERNAL_SERVER_ERROR;
1104
1151
  const entry = {
1105
1152
  ...scope,
@@ -1116,6 +1163,7 @@ class RequestLoggingMiddleware {
1116
1163
  }
1117
1164
  }
1118
1165
  #succeeded(req, path, requestId, started, request, response, scope) {
1166
+ this.#shared(req, request);
1119
1167
  const body = this.#responseFields(response);
1120
1168
  if (body === undefined) {
1121
1169
  this.logger.info(`${req.method} ${path} ${response.status}`, {
@@ -1139,7 +1187,7 @@ class RequestLoggingMiddleware {
1139
1187
  return response;
1140
1188
  });
1141
1189
  }
1142
- #body(req) {
1190
+ #body(req, ctx) {
1143
1191
  if (!this.#requestBody)
1144
1192
  return;
1145
1193
  if (req.method === "GET" || req.method === "HEAD")
@@ -1147,6 +1195,10 @@ class RequestLoggingMiddleware {
1147
1195
  if (!(req.headers.get("content-type") ?? "").includes("application/json")) {
1148
1196
  return;
1149
1197
  }
1198
+ if (ctx.parsesBody) {
1199
+ RawBody.want(req);
1200
+ return;
1201
+ }
1150
1202
  return req.clone().text().then((text) => parse(text, this.#limit));
1151
1203
  }
1152
1204
  #responseFields(response) {
@@ -1230,7 +1282,11 @@ var bodyFill = (schema) => (draft) => {
1230
1282
  if (parse2 === undefined) {
1231
1283
  throw new HttpError(HttpStatusCode.UNSUPPORTED_MEDIA_TYPE, `Unsupported content type "${media}". Declared bodies accept ` + "application/json, application/x-www-form-urlencoded, multipart/form-data or text/*.");
1232
1284
  }
1233
- return parse2(draft.req).then((value) => fillWith(draft, "body", schema, value), (error) => {
1285
+ const read = parse2 === asJson && RawBody.wanted(draft.req) ? draft.req.text().then((text) => {
1286
+ RawBody.record(draft.req, text);
1287
+ return JSON.parse(text);
1288
+ }) : parse2(draft.req);
1289
+ return read.then((value) => fillWith(draft, "body", schema, value), (error) => {
1234
1290
  throw new HttpError(HttpStatusCode.BAD_REQUEST, `Malformed ${media} body`, { cause: error });
1235
1291
  });
1236
1292
  };
@@ -1277,7 +1333,7 @@ var toResponse = (value, status) => {
1277
1333
  }
1278
1334
  return Response.json(value, { status });
1279
1335
  };
1280
- var statusFor = (route) => route.options?.status ?? (route.method === "POST" ? HttpStatusCode.CREATED : HttpStatusCode.OK);
1336
+ var statusFor = (route) => route.options?.status ?? defaultStatusFor(route.method);
1281
1337
  var assertNoCollisions = (discovered) => {
1282
1338
  const owners = new Map;
1283
1339
  for (const route of discovered) {
@@ -1309,6 +1365,7 @@ var unmatchedContext = (req, isPublic) => Object.freeze({
1309
1365
  handler: "(none)",
1310
1366
  method: req.method,
1311
1367
  path: new URL(req.url).pathname,
1368
+ parsesBody: false,
1312
1369
  get: (key) => {
1313
1370
  if (key.id === UNMATCHED.id)
1314
1371
  return true;
@@ -1767,6 +1824,274 @@ StaticModule = __decorateElement(_init, 0, "StaticModule", _dec, StaticModule);
1767
1824
  __runInitializers(_init, 1, StaticModule);
1768
1825
  __decoratorMetadata(_init, StaticModule);
1769
1826
  let _StaticModule = StaticModule;
1827
+ // src/compression/negotiate.ts
1828
+ var quality = (params) => {
1829
+ for (const param of params) {
1830
+ const [key, value] = param.split("=");
1831
+ if (key?.trim().toLowerCase() !== "q")
1832
+ continue;
1833
+ const q = Number.parseFloat(value ?? "");
1834
+ return Number.isFinite(q) && q >= 0 && q <= 1 ? q : 1;
1835
+ }
1836
+ return 1;
1837
+ };
1838
+ var negotiate = (header, offered) => {
1839
+ if (header === null)
1840
+ return;
1841
+ const accepted = new Map;
1842
+ for (const element of header.split(",")) {
1843
+ const [name, ...params] = element.split(";");
1844
+ const token = name?.trim().toLowerCase();
1845
+ if (token === undefined || token === "")
1846
+ continue;
1847
+ accepted.set(token, quality(params));
1848
+ }
1849
+ const wildcard = accepted.get("*");
1850
+ let best;
1851
+ let bestQuality = 0;
1852
+ for (const encoding of offered) {
1853
+ const q = accepted.get(encoding) ?? wildcard ?? 0;
1854
+ if (q > bestQuality) {
1855
+ best = encoding;
1856
+ bestQuality = q;
1857
+ }
1858
+ }
1859
+ return best;
1860
+ };
1861
+
1862
+ // src/compression/options.ts
1863
+ var CompressionEncoding = Object.freeze({
1864
+ ZSTD: "zstd",
1865
+ GZIP: "gzip"
1866
+ });
1867
+ var COMPRESSIBLE = new Set([
1868
+ "application/graphql",
1869
+ "application/graphql-response+json",
1870
+ "application/javascript",
1871
+ "application/json",
1872
+ "application/manifest+json",
1873
+ "application/wasm",
1874
+ "application/x-javascript",
1875
+ "application/x-ndjson",
1876
+ "application/xml",
1877
+ "image/svg+xml"
1878
+ ]);
1879
+ var isCompressibleType = (contentType) => {
1880
+ if (contentType === null)
1881
+ return false;
1882
+ const type = contentType.split(";")[0]?.trim().toLowerCase() ?? "";
1883
+ if (type.startsWith("text/"))
1884
+ return true;
1885
+ if (type.endsWith("+json") || type.endsWith("+xml"))
1886
+ return true;
1887
+ return COMPRESSIBLE.has(type);
1888
+ };
1889
+ var encodable = (encoding) => {
1890
+ const sync = encoding === CompressionEncoding.ZSTD ? Bun.zstdCompressSync : Bun.gzipSync;
1891
+ if (typeof sync !== "function")
1892
+ return false;
1893
+ try {
1894
+ new CompressionStream(encoding);
1895
+ return true;
1896
+ } catch {
1897
+ return false;
1898
+ }
1899
+ };
1900
+
1901
+ class CompressionOptions {
1902
+ encodings;
1903
+ threshold;
1904
+ filter;
1905
+ constructor(init = {}) {
1906
+ this.encodings = init.encodings ?? [
1907
+ CompressionEncoding.ZSTD,
1908
+ CompressionEncoding.GZIP
1909
+ ];
1910
+ const missing = this.encodings.filter((encoding) => !encodable(encoding));
1911
+ if (missing.length > 0) {
1912
+ throw new Error(`Bun ${Bun.version} cannot encode ${missing.join(", ")}. ` + "Pass `encodings` without it, or upgrade Bun.");
1913
+ }
1914
+ this.threshold = init.threshold ?? 1024;
1915
+ this.filter = init.filter ?? isCompressibleType;
1916
+ }
1917
+ }
1918
+ Object.defineProperty(CompressionOptions, Symbol.for("dunx.deps"), {
1919
+ value: () => [{ unresolved: "init: CompressionOptionsInit = {}" }]
1920
+ });
1921
+
1922
+ // src/compression/compression.ts
1923
+ var BODYLESS = new Set([204, 205, 304]);
1924
+ var BUFFER_LIMIT = 1024 * 1024;
1925
+ var buffer = async (body, limit) => {
1926
+ const reader = body.getReader();
1927
+ const chunks = [];
1928
+ let size = 0;
1929
+ for (;; ) {
1930
+ const { done, value } = await reader.read();
1931
+ if (done)
1932
+ break;
1933
+ chunks.push(value);
1934
+ size += value.byteLength;
1935
+ if (size > limit) {
1936
+ return {
1937
+ rest: new ReadableStream({
1938
+ start: (controller) => {
1939
+ for (const chunk of chunks)
1940
+ controller.enqueue(chunk);
1941
+ },
1942
+ pull: async (controller) => {
1943
+ const next = await reader.read();
1944
+ if (next.done)
1945
+ controller.close();
1946
+ else
1947
+ controller.enqueue(next.value);
1948
+ },
1949
+ cancel: (reason) => reader.cancel(reason)
1950
+ })
1951
+ };
1952
+ }
1953
+ }
1954
+ const bytes = new Uint8Array(size);
1955
+ let offset = 0;
1956
+ for (const chunk of chunks) {
1957
+ bytes.set(chunk, offset);
1958
+ offset += chunk.byteLength;
1959
+ }
1960
+ return { bytes };
1961
+ };
1962
+ var declaredLength = (headers) => {
1963
+ const raw = headers.get("content-length");
1964
+ if (raw === null)
1965
+ return;
1966
+ const length = Number.parseInt(raw, 10);
1967
+ return Number.isFinite(length) ? length : undefined;
1968
+ };
1969
+ var weakenETag = (headers) => {
1970
+ const etag = headers.get("etag");
1971
+ if (etag !== null && !etag.startsWith("W/"))
1972
+ headers.set("etag", `W/${etag}`);
1973
+ };
1974
+ var varyOnEncoding = (headers) => {
1975
+ const existing = headers.get("vary");
1976
+ if (existing === null) {
1977
+ headers.set("vary", "accept-encoding");
1978
+ return;
1979
+ }
1980
+ if (existing.trim() === "*")
1981
+ return;
1982
+ const listed = existing.split(",").some((field) => field.trim().toLowerCase() === "accept-encoding");
1983
+ if (!listed)
1984
+ headers.set("vary", `${existing}, accept-encoding`);
1985
+ };
1986
+ var encodeSync = (encoding, data) => {
1987
+ switch (encoding) {
1988
+ case CompressionEncoding.ZSTD:
1989
+ return Bun.zstdCompressSync(data);
1990
+ case CompressionEncoding.GZIP:
1991
+ return Bun.gzipSync(data);
1992
+ }
1993
+ };
1994
+
1995
+ class Compression {
1996
+ #options;
1997
+ constructor(options) {
1998
+ this.#options = options;
1999
+ }
2000
+ #considers(res) {
2001
+ if (BODYLESS.has(res.status) || res.status === 206)
2002
+ return false;
2003
+ if (res.headers.has("content-encoding"))
2004
+ return false;
2005
+ if (res.headers.get("cache-control")?.includes("no-transform") === true) {
2006
+ return false;
2007
+ }
2008
+ return this.#options.filter(res.headers.get("content-type"));
2009
+ }
2010
+ async handle(req, _ctx, next) {
2011
+ const res = await next();
2012
+ const body = res.body;
2013
+ if (body === null || !this.#considers(res))
2014
+ return res;
2015
+ varyOnEncoding(res.headers);
2016
+ const encoding = negotiate(req.headers.get("accept-encoding"), this.#options.encodings);
2017
+ if (encoding === undefined)
2018
+ return res;
2019
+ const declared = declaredLength(res.headers);
2020
+ if (declared !== undefined && declared < this.#options.threshold)
2021
+ return res;
2022
+ const headers = new Headers(res.headers);
2023
+ headers.set("content-encoding", encoding);
2024
+ weakenETag(headers);
2025
+ const source = declared !== undefined && declared > BUFFER_LIMIT ? { rest: body } : await buffer(body, BUFFER_LIMIT);
2026
+ if ("rest" in source) {
2027
+ headers.delete("content-length");
2028
+ return new Response(source.rest.pipeThrough(new CompressionStream(encoding)), { status: res.status, statusText: res.statusText, headers });
2029
+ }
2030
+ if (source.bytes.byteLength < this.#options.threshold) {
2031
+ const passthrough = new Headers(res.headers);
2032
+ passthrough.set("content-length", String(source.bytes.byteLength));
2033
+ return new Response(source.bytes, {
2034
+ status: res.status,
2035
+ statusText: res.statusText,
2036
+ headers: passthrough
2037
+ });
2038
+ }
2039
+ const encoded = encodeSync(encoding, source.bytes);
2040
+ headers.set("content-length", String(encoded.byteLength));
2041
+ return new Response(encoded, {
2042
+ status: res.status,
2043
+ statusText: res.statusText,
2044
+ headers
2045
+ });
2046
+ }
2047
+ }
2048
+ Object.defineProperty(Compression, Symbol.for("dunx.deps"), {
2049
+ value: () => [CompressionOptions]
2050
+ });
2051
+ // src/compression/module.ts
2052
+ import {
2053
+ Module as Module2,
2054
+ provide as provide3
2055
+ } from "@dunx/core";
2056
+ var middleware = () => provide3(Compression, {
2057
+ useFactory: (options) => new Compression(options),
2058
+ inject: [CompressionOptions]
2059
+ });
2060
+ var _dec = [
2061
+ Module2({})
2062
+ ];
2063
+ var _init = __decoratorStart(undefined);
2064
+
2065
+ class CompressionModule {
2066
+ static forRoot(init = {}) {
2067
+ return {
2068
+ module: CompressionModule,
2069
+ exports: [CompressionOptions, Compression],
2070
+ providers: [
2071
+ provide3(CompressionOptions, { useValue: new CompressionOptions(init) }),
2072
+ middleware()
2073
+ ]
2074
+ };
2075
+ }
2076
+ static forRootAsync(config) {
2077
+ return {
2078
+ module: CompressionModule,
2079
+ ...config.imports && { imports: config.imports },
2080
+ exports: [CompressionOptions, Compression],
2081
+ providers: [
2082
+ provide3(CompressionOptions, {
2083
+ useFactory: async (...deps) => new CompressionOptions(await config.useFactory(...deps)),
2084
+ inject: config.inject ?? []
2085
+ }),
2086
+ middleware()
2087
+ ]
2088
+ };
2089
+ }
2090
+ }
2091
+ CompressionModule = __decorateElement(_init, 0, "CompressionModule", _dec, CompressionModule);
2092
+ __runInitializers(_init, 1, CompressionModule);
2093
+ __decoratorMetadata(_init, CompressionModule);
2094
+ let _CompressionModule = CompressionModule;
1770
2095
  // src/throttle/decorators.ts
1771
2096
  var THROTTLE = metaKey("throttle");
1772
2097
  var SKIP_THROTTLE = metaKey("skip-throttle");
@@ -1952,20 +2277,20 @@ Object.defineProperty(ThrottleGuard, Symbol.for("dunx.deps"), {
1952
2277
  // src/throttle/module.ts
1953
2278
  import {
1954
2279
  Logger as Logger6,
1955
- Module as Module2,
1956
- provide as provide3
2280
+ Module as Module3,
2281
+ provide as provide4
1957
2282
  } from "@dunx/core";
1958
2283
  var EXPORTS = [ThrottleOptions, ThrottleStore, ThrottleGuard];
1959
- var guard = () => provide3(ThrottleGuard, {
2284
+ var guard = () => provide4(ThrottleGuard, {
1960
2285
  useFactory: (options, store, address, logger) => new ThrottleGuard(options, store, address, logger),
1961
2286
  inject: [ThrottleOptions, ThrottleStore, ClientAddress, Logger6]
1962
2287
  });
1963
- var store = () => provide3(ThrottleStore, {
2288
+ var store = () => provide4(ThrottleStore, {
1964
2289
  useFactory: (options) => options.store ?? new MemoryThrottleStore,
1965
2290
  inject: [ThrottleOptions]
1966
2291
  });
1967
2292
  var _dec = [
1968
- Module2({})
2293
+ Module3({})
1969
2294
  ];
1970
2295
  var _init = __decoratorStart(undefined);
1971
2296
 
@@ -1976,7 +2301,7 @@ class ThrottleModule {
1976
2301
  global: true,
1977
2302
  exports: EXPORTS,
1978
2303
  providers: [
1979
- provide3(ThrottleOptions, { useValue: new ThrottleOptions(init) }),
2304
+ provide4(ThrottleOptions, { useValue: new ThrottleOptions(init) }),
1980
2305
  store(),
1981
2306
  guard()
1982
2307
  ]
@@ -1989,7 +2314,7 @@ class ThrottleModule {
1989
2314
  ...config.imports && { imports: config.imports },
1990
2315
  exports: EXPORTS,
1991
2316
  providers: [
1992
- provide3(ThrottleOptions, {
2317
+ provide4(ThrottleOptions, {
1993
2318
  useFactory: async (...deps) => new ThrottleOptions(await config.useFactory(...deps)),
1994
2319
  inject: config.inject ?? []
1995
2320
  }),
@@ -2128,6 +2453,50 @@ class QueryProbe {
2128
2453
  // src/health/controller.ts
2129
2454
  import { inject } from "@dunx/core";
2130
2455
 
2456
+ // src/health/report-schema.ts
2457
+ var state = {
2458
+ type: "string",
2459
+ enum: ["up", "down", "unknown"],
2460
+ description: "`unknown` is not `down`: a probe that timed out has told you nothing."
2461
+ };
2462
+ var HEALTH_REPORT_SCHEMA = Object.freeze({
2463
+ $id: "HealthReport",
2464
+ type: "object",
2465
+ description: "What the probe found. `up` answers 200 and anything else answers 503.",
2466
+ properties: {
2467
+ status: state,
2468
+ draining: {
2469
+ type: "boolean",
2470
+ description: "The process is shutting down, or something holds it out."
2471
+ },
2472
+ uptimeMs: {
2473
+ type: "integer",
2474
+ description: "Measured on a monotonic clock, so it never goes backwards."
2475
+ },
2476
+ checks: {
2477
+ type: "array",
2478
+ items: {
2479
+ type: "object",
2480
+ properties: {
2481
+ name: { type: "string" },
2482
+ state,
2483
+ critical: {
2484
+ type: "boolean",
2485
+ description: "A failure here sheds traffic. Memory and disk do not."
2486
+ },
2487
+ ms: { type: "integer", description: "How long the check took." },
2488
+ detail: {
2489
+ type: "string",
2490
+ description: "A latency, a version, or a failure message."
2491
+ }
2492
+ },
2493
+ required: ["name", "state", "critical", "ms"]
2494
+ }
2495
+ }
2496
+ },
2497
+ required: ["status", "draining", "uptimeMs", "checks"]
2498
+ });
2499
+
2131
2500
  // src/health/registry.ts
2132
2501
  var bounded = async (indicator, timeoutMs) => {
2133
2502
  let timer;
@@ -2162,12 +2531,14 @@ class HealthOptions {
2162
2531
  readiness;
2163
2532
  timeoutMs;
2164
2533
  routes;
2534
+ documented;
2165
2535
  drainDelayMs;
2166
2536
  constructor(init = {}) {
2167
2537
  this.liveness = init.liveness ?? [];
2168
2538
  this.readiness = init.readiness ?? [];
2169
2539
  this.timeoutMs = init.timeoutMs ?? 2000;
2170
2540
  this.routes = init.routes ?? true;
2541
+ this.documented = init.documented ?? true;
2171
2542
  this.drainDelayMs = Math.max(0, init.drainDelayMs ?? 0);
2172
2543
  }
2173
2544
  }
@@ -2230,18 +2601,20 @@ Object.defineProperty(HealthRegistry, Symbol.for("dunx.deps"), {
2230
2601
  });
2231
2602
 
2232
2603
  // src/health/controller.ts
2604
+ var probeResponses = {
2605
+ response: { 200: HEALTH_REPORT_SCHEMA, 503: HEALTH_REPORT_SCHEMA }
2606
+ };
2233
2607
  var answer = (report) => Response.json(report, { status: report.status === "up" ? 200 : 503 });
2234
2608
  var _dec = [
2235
- Controller("health"),
2236
- ApiHidden()
2609
+ Controller("health")
2237
2610
  ];
2238
2611
  var _dec2 = [
2239
2612
  Public(),
2240
- Get("/live")
2613
+ Get("/live", probeResponses)
2241
2614
  ];
2242
2615
  var _dec3 = [
2243
2616
  Public(),
2244
- Get("/ready")
2617
+ Get("/ready", probeResponses)
2245
2618
  ];
2246
2619
  var _health = new WeakMap;
2247
2620
  var _init = __decoratorStart(undefined);
@@ -2264,6 +2637,18 @@ HealthController = __decorateElement(_init, 0, "HealthController", _dec, HealthC
2264
2637
  __runInitializers(_init, 1, HealthController);
2265
2638
  __decoratorMetadata(_init, HealthController);
2266
2639
  let _HealthController = HealthController;
2640
+ var _dec = [
2641
+ ApiHidden()
2642
+ ];
2643
+ var _base = HealthController;
2644
+ var _init = __decoratorStart(_base);
2645
+
2646
+ class HiddenHealthController extends _base {
2647
+ }
2648
+ HiddenHealthController = __decorateElement(_init, 0, "HiddenHealthController", _dec, HiddenHealthController);
2649
+ __runInitializers(_init, 1, HiddenHealthController);
2650
+ __decoratorMetadata(_init, HiddenHealthController);
2651
+ let _HiddenHealthController = HiddenHealthController;
2267
2652
  // src/health/indicators.ts
2268
2653
  import { statfs } from "fs/promises";
2269
2654
  var ms = (started) => Math.round(performance.now() - started);
@@ -2368,8 +2753,8 @@ Object.defineProperty(DiskIndicator, Symbol.for("dunx.deps"), {
2368
2753
  });
2369
2754
  // src/health/module.ts
2370
2755
  import {
2371
- Module as Module3,
2372
- provide as provide4
2756
+ Module as Module4,
2757
+ provide as provide5
2373
2758
  } from "@dunx/core";
2374
2759
 
2375
2760
  // src/health/readiness.ts
@@ -2416,22 +2801,23 @@ Object.defineProperty(Readiness, Symbol.for("dunx.deps"), {
2416
2801
  // src/health/module.ts
2417
2802
  var wiring = (options) => [
2418
2803
  ...options,
2419
- provide4(ReadinessOptions, {
2804
+ provide5(ReadinessOptions, {
2420
2805
  useFactory: (opts) => new ReadinessOptions({ drainDelayMs: opts.drainDelayMs }),
2421
2806
  inject: [HealthOptions]
2422
2807
  }),
2423
- provide4(Readiness, {
2808
+ provide5(Readiness, {
2424
2809
  useFactory: (opts) => new Readiness(opts),
2425
2810
  inject: [ReadinessOptions]
2426
2811
  }),
2427
- provide4(HealthRegistry, {
2812
+ provide5(HealthRegistry, {
2428
2813
  useFactory: (opts, readiness) => new HealthRegistry(opts, readiness),
2429
2814
  inject: [HealthOptions, Readiness]
2430
2815
  })
2431
2816
  ];
2432
2817
  var surface = [HealthOptions, HealthRegistry, Readiness];
2818
+ var controllerFor = (documented) => documented ? HealthController : HiddenHealthController;
2433
2819
  var _dec = [
2434
- Module3({})
2820
+ Module4({})
2435
2821
  ];
2436
2822
  var _init = __decoratorStart(undefined);
2437
2823
 
@@ -2440,19 +2826,19 @@ class HealthModule {
2440
2826
  const options = new HealthOptions(init);
2441
2827
  return {
2442
2828
  module: HealthModule,
2443
- ...options.routes ? { controllers: [HealthController] } : {},
2829
+ ...options.routes ? { controllers: [controllerFor(options.documented)] } : {},
2444
2830
  exports: surface,
2445
- providers: wiring([provide4(HealthOptions, { useValue: options })])
2831
+ providers: wiring([provide5(HealthOptions, { useValue: options })])
2446
2832
  };
2447
2833
  }
2448
2834
  static forRootAsync(config) {
2449
2835
  return {
2450
2836
  module: HealthModule,
2451
2837
  ...config.imports ? { imports: config.imports } : {},
2452
- ...config.routes ?? true ? { controllers: [HealthController] } : {},
2838
+ ...config.routes ?? true ? { controllers: [controllerFor(config.documented ?? true)] } : {},
2453
2839
  exports: surface,
2454
2840
  providers: wiring([
2455
- provide4(HealthOptions, {
2841
+ provide5(HealthOptions, {
2456
2842
  useFactory: async (...deps) => new HealthOptions(await config.useFactory(...deps)),
2457
2843
  inject: config.inject ?? []
2458
2844
  })
@@ -2467,6 +2853,10 @@ let _HealthModule = HealthModule;
2467
2853
  export {
2468
2854
  ApiHidden,
2469
2855
  ClientAddress,
2856
+ Compression,
2857
+ CompressionEncoding,
2858
+ CompressionModule,
2859
+ CompressionOptions,
2470
2860
  Controller,
2471
2861
  DEFAULT_RELAY_CHANNEL,
2472
2862
  DatabaseIndicator,
@@ -2476,6 +2866,7 @@ export {
2476
2866
  ErrorFilter,
2477
2867
  Gateway,
2478
2868
  Get,
2869
+ HEALTH_REPORT_SCHEMA,
2479
2870
  HIDDEN,
2480
2871
  HandlerKind,
2481
2872
  HealthController,
@@ -2483,6 +2874,7 @@ export {
2483
2874
  HealthModule,
2484
2875
  HealthOptions,
2485
2876
  HealthRegistry,
2877
+ HiddenHealthController,
2486
2878
  HttpError,
2487
2879
  HttpFactory,
2488
2880
  HttpStatusCode,
@@ -2520,11 +2912,14 @@ export {
2520
2912
  StaticModule,
2521
2913
  StaticOptions,
2522
2914
  THROTTLE,
2915
+ TRACEPARENT_HEADER,
2916
+ TRACESTATE_HEADER,
2523
2917
  Throttle,
2524
2918
  ThrottleGuard,
2525
2919
  ThrottleModule,
2526
2920
  ThrottleOptions,
2527
2921
  ThrottleStore,
2922
+ TraceContext,
2528
2923
  UNMATCHED,
2529
2924
  UseGuards,
2530
2925
  ValidationError,
@@ -2541,6 +2936,7 @@ export {
2541
2936
  decodeRelay,
2542
2937
  defaultErrorMapper,
2543
2938
  defaultRelayUrl,
2939
+ defaultStatusFor,
2544
2940
  discoverGateway,
2545
2941
  discoverGateways,
2546
2942
  discoverRoutes,
@@ -2549,6 +2945,7 @@ export {
2549
2945
  errorMapper,
2550
2946
  gatewaysOf,
2551
2947
  guardsOf,
2948
+ isCompressibleType,
2552
2949
  isErrorFilter,
2553
2950
  isGateway,
2554
2951
  joinPath,
@@ -2556,6 +2953,7 @@ export {
2556
2953
  meta,
2557
2954
  metaKey,
2558
2955
  metaOf,
2956
+ negotiate,
2559
2957
  normalizePath,
2560
2958
  normalizePrefix,
2561
2959
  observe,
@@ -2565,6 +2963,3 @@ export {
2565
2963
  withCors,
2566
2964
  withUpgradeRoutes
2567
2965
  };
2568
-
2569
- //# debugId=30A653C61AAD581564756E2164756E21
2570
- //# sourceMappingURL=index.js.map