@bymax-one/nest-core 1.6.5 → 1.6.7

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.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { Catch, Inject, Optional, Injectable, ConfigurableModuleBuilder, Module, HttpException, Logger, Get, Res, Controller, Req, HttpStatus, UnauthorizedException, NotFoundException } from '@nestjs/common';
1
+ import { Injectable, Inject, Catch, Optional, ConfigurableModuleBuilder, Module, BadRequestException, HttpException, Logger, Get, Res, Controller, Req, HttpStatus, UnauthorizedException, NotFoundException } from '@nestjs/common';
2
2
  import { HttpAdapterHost, DiscoveryService, Reflector, BaseExceptionFilter, APP_FILTER, DiscoveryModule } from '@nestjs/core';
3
3
  import { createHash, timingSafeEqual } from 'crypto';
4
4
  import { AsyncResource } from 'async_hooks';
@@ -16,6 +16,114 @@ var __decorateClass = (decorators, target, key, kind) => {
16
16
  };
17
17
  var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
18
18
 
19
+ // src/core.tokens.ts
20
+ var BYMAX_CORE_OPTIONS = /* @__PURE__ */ Symbol.for("@bymax-one/nest-core:core-options");
21
+ var BYMAX_CORRELATION_PROVIDER = /* @__PURE__ */ Symbol.for(
22
+ "@bymax-one/nest-core:correlation-provider"
23
+ );
24
+ var BYMAX_TIMING_SINK = /* @__PURE__ */ Symbol.for("@bymax-one/nest-core:timing-sink");
25
+ var BYMAX_HEALTH_INDICATORS = /* @__PURE__ */ Symbol.for(
26
+ "@bymax-one/nest-core:health-indicators"
27
+ );
28
+ var BYMAX_HEALTH_TRANSITION_SINK = /* @__PURE__ */ Symbol.for(
29
+ "@bymax-one/nest-core:health-transition-sink"
30
+ );
31
+ var BYMAX_UNEXPECTED_ERROR_SINK = /* @__PURE__ */ Symbol.for(
32
+ "@bymax-one/nest-core:unexpected-error-sink"
33
+ );
34
+ var BYMAX_METRICS_REGISTRY = /* @__PURE__ */ Symbol.for(
35
+ "@bymax-one/nest-core:metrics-registry"
36
+ );
37
+ var BYMAX_TRACE_CONTEXT = /* @__PURE__ */ Symbol.for("@bymax-one/nest-core:trace-context");
38
+
39
+ // src/envelope/error-codes.ts
40
+ var BYMAX_BAD_REQUEST = "BYMAX_BAD_REQUEST";
41
+ var BYMAX_VALIDATION_FAILED = "BYMAX_VALIDATION_FAILED";
42
+ var BYMAX_UNAUTHORIZED = "BYMAX_UNAUTHORIZED";
43
+ var BYMAX_FORBIDDEN = "BYMAX_FORBIDDEN";
44
+ var BYMAX_NOT_FOUND = "BYMAX_NOT_FOUND";
45
+ var BYMAX_CONFLICT = "BYMAX_CONFLICT";
46
+ var BYMAX_PAYLOAD_TOO_LARGE = "BYMAX_PAYLOAD_TOO_LARGE";
47
+ var BYMAX_UNSUPPORTED_MEDIA_TYPE = "BYMAX_UNSUPPORTED_MEDIA_TYPE";
48
+ var BYMAX_UNPROCESSABLE_ENTITY = "BYMAX_UNPROCESSABLE_ENTITY";
49
+ var BYMAX_TOO_MANY_REQUESTS = "BYMAX_TOO_MANY_REQUESTS";
50
+ var BYMAX_CLIENT_ERROR = "BYMAX_CLIENT_ERROR";
51
+ var BYMAX_INTERNAL_ERROR = "BYMAX_INTERNAL_ERROR";
52
+ var BYMAX_NOT_IMPLEMENTED = "BYMAX_NOT_IMPLEMENTED";
53
+ var BYMAX_BAD_GATEWAY = "BYMAX_BAD_GATEWAY";
54
+ var BYMAX_SERVICE_UNAVAILABLE = "BYMAX_SERVICE_UNAVAILABLE";
55
+ var BYMAX_GATEWAY_TIMEOUT = "BYMAX_GATEWAY_TIMEOUT";
56
+ var STATUS_CODES = /* @__PURE__ */ new Map([
57
+ [400, BYMAX_BAD_REQUEST],
58
+ [401, BYMAX_UNAUTHORIZED],
59
+ [403, BYMAX_FORBIDDEN],
60
+ [404, BYMAX_NOT_FOUND],
61
+ [409, BYMAX_CONFLICT],
62
+ [413, BYMAX_PAYLOAD_TOO_LARGE],
63
+ [415, BYMAX_UNSUPPORTED_MEDIA_TYPE],
64
+ [422, BYMAX_UNPROCESSABLE_ENTITY],
65
+ [429, BYMAX_TOO_MANY_REQUESTS],
66
+ [500, BYMAX_INTERNAL_ERROR],
67
+ [501, BYMAX_NOT_IMPLEMENTED],
68
+ [502, BYMAX_BAD_GATEWAY],
69
+ [503, BYMAX_SERVICE_UNAVAILABLE],
70
+ [504, BYMAX_GATEWAY_TIMEOUT]
71
+ ]);
72
+ var CLIENT_ERROR_MIN = 400;
73
+ var CLIENT_ERROR_MAX = 500;
74
+ function codeForStatus(status) {
75
+ const catalogued = STATUS_CODES.get(status);
76
+ if (catalogued !== void 0) {
77
+ return catalogued;
78
+ }
79
+ if (status >= CLIENT_ERROR_MIN && status < CLIENT_ERROR_MAX) {
80
+ return BYMAX_CLIENT_ERROR;
81
+ }
82
+ return BYMAX_INTERNAL_ERROR;
83
+ }
84
+
85
+ // src/body-depth/body-depth.middleware.ts
86
+ var BODY_TOO_DEEP_MESSAGE = "Request body is nested too deeply";
87
+ function exceedsDepth(value, maxDepth) {
88
+ let level = [value];
89
+ for (let depth = 0; level.length > 0; depth += 1) {
90
+ const next = [];
91
+ for (const node of level) {
92
+ if (typeof node === "object" && node !== null) {
93
+ if (depth >= maxDepth) {
94
+ return true;
95
+ }
96
+ for (const child of Object.values(node)) {
97
+ next.push(child);
98
+ }
99
+ }
100
+ }
101
+ level = next;
102
+ }
103
+ return false;
104
+ }
105
+ var BymaxBodyDepthMiddleware = class {
106
+ constructor(options) {
107
+ this.options = options;
108
+ }
109
+ /**
110
+ * @param req - The request, whose `body` the parser has already filled.
111
+ * @param _res - Unused.
112
+ * @param next - Continues the chain.
113
+ * @throws BadRequestException When the body is nested too deeply.
114
+ */
115
+ use(req, _res, next) {
116
+ if (exceedsDepth(req.body, this.options.bodyDepth.maxDepth)) {
117
+ throw new BadRequestException({ code: BYMAX_BAD_REQUEST, message: BODY_TOO_DEEP_MESSAGE });
118
+ }
119
+ next();
120
+ }
121
+ };
122
+ BymaxBodyDepthMiddleware = __decorateClass([
123
+ Injectable(),
124
+ __decorateParam(0, Inject(BYMAX_CORE_OPTIONS))
125
+ ], BymaxBodyDepthMiddleware);
126
+
19
127
  // src/route-defaults.ts
20
128
  var DEFAULT_HEALTH_PATH = "health";
21
129
  var DEFAULT_METRICS_PATH = "metrics";
@@ -62,6 +170,16 @@ function resolveTiming(raw) {
62
170
  const threshold = raw?.slowRequestThresholdMs;
63
171
  return threshold === void 0 ? { enabled } : { enabled, slowRequestThresholdMs: threshold };
64
172
  }
173
+ var DEFAULT_MAX_BODY_DEPTH = 32;
174
+ function resolveBodyDepth(raw) {
175
+ const maxDepth = raw?.maxDepth ?? DEFAULT_MAX_BODY_DEPTH;
176
+ if (!Number.isSafeInteger(maxDepth) || maxDepth < 1) {
177
+ throw new Error(
178
+ `bodyDepth.maxDepth must be a positive safe integer, received ${String(maxDepth)}`
179
+ );
180
+ }
181
+ return { enabled: raw?.enabled ?? false, maxDepth };
182
+ }
65
183
  function resolveHealth(raw) {
66
184
  return {
67
185
  enabled: raw?.enabled ?? true,
@@ -134,6 +252,7 @@ function normalizeCoreOptions(raw) {
134
252
  return deepFreeze({
135
253
  envelope: resolveEnvelope(raw?.envelope),
136
254
  timing: resolveTiming(raw?.timing),
255
+ bodyDepth: resolveBodyDepth(raw?.bodyDepth),
137
256
  health: resolveHealth(raw?.health),
138
257
  metrics: resolveMetrics(raw?.metrics),
139
258
  openapi: resolveOpenApi(raw?.openapi, raw?.environment),
@@ -146,26 +265,6 @@ function normalizeCoreOptions(raw) {
146
265
  }
147
266
  normalizeCoreOptions();
148
267
 
149
- // src/core.tokens.ts
150
- var BYMAX_CORE_OPTIONS = /* @__PURE__ */ Symbol.for("@bymax-one/nest-core:core-options");
151
- var BYMAX_CORRELATION_PROVIDER = /* @__PURE__ */ Symbol.for(
152
- "@bymax-one/nest-core:correlation-provider"
153
- );
154
- var BYMAX_TIMING_SINK = /* @__PURE__ */ Symbol.for("@bymax-one/nest-core:timing-sink");
155
- var BYMAX_HEALTH_INDICATORS = /* @__PURE__ */ Symbol.for(
156
- "@bymax-one/nest-core:health-indicators"
157
- );
158
- var BYMAX_HEALTH_TRANSITION_SINK = /* @__PURE__ */ Symbol.for(
159
- "@bymax-one/nest-core:health-transition-sink"
160
- );
161
- var BYMAX_UNEXPECTED_ERROR_SINK = /* @__PURE__ */ Symbol.for(
162
- "@bymax-one/nest-core:unexpected-error-sink"
163
- );
164
- var BYMAX_METRICS_REGISTRY = /* @__PURE__ */ Symbol.for(
165
- "@bymax-one/nest-core:metrics-registry"
166
- );
167
- var BYMAX_TRACE_CONTEXT = /* @__PURE__ */ Symbol.for("@bymax-one/nest-core:trace-context");
168
-
169
268
  // src/optional-peer.ts
170
269
  function isMissingModuleError(cause) {
171
270
  const code = cause.code;
@@ -273,52 +372,6 @@ function containRejection(returned, onFailure) {
273
372
  }
274
373
  }
275
374
 
276
- // src/envelope/error-codes.ts
277
- var BYMAX_BAD_REQUEST = "BYMAX_BAD_REQUEST";
278
- var BYMAX_VALIDATION_FAILED = "BYMAX_VALIDATION_FAILED";
279
- var BYMAX_UNAUTHORIZED = "BYMAX_UNAUTHORIZED";
280
- var BYMAX_FORBIDDEN = "BYMAX_FORBIDDEN";
281
- var BYMAX_NOT_FOUND = "BYMAX_NOT_FOUND";
282
- var BYMAX_CONFLICT = "BYMAX_CONFLICT";
283
- var BYMAX_PAYLOAD_TOO_LARGE = "BYMAX_PAYLOAD_TOO_LARGE";
284
- var BYMAX_UNSUPPORTED_MEDIA_TYPE = "BYMAX_UNSUPPORTED_MEDIA_TYPE";
285
- var BYMAX_UNPROCESSABLE_ENTITY = "BYMAX_UNPROCESSABLE_ENTITY";
286
- var BYMAX_TOO_MANY_REQUESTS = "BYMAX_TOO_MANY_REQUESTS";
287
- var BYMAX_CLIENT_ERROR = "BYMAX_CLIENT_ERROR";
288
- var BYMAX_INTERNAL_ERROR = "BYMAX_INTERNAL_ERROR";
289
- var BYMAX_NOT_IMPLEMENTED = "BYMAX_NOT_IMPLEMENTED";
290
- var BYMAX_BAD_GATEWAY = "BYMAX_BAD_GATEWAY";
291
- var BYMAX_SERVICE_UNAVAILABLE = "BYMAX_SERVICE_UNAVAILABLE";
292
- var BYMAX_GATEWAY_TIMEOUT = "BYMAX_GATEWAY_TIMEOUT";
293
- var STATUS_CODES = /* @__PURE__ */ new Map([
294
- [400, BYMAX_BAD_REQUEST],
295
- [401, BYMAX_UNAUTHORIZED],
296
- [403, BYMAX_FORBIDDEN],
297
- [404, BYMAX_NOT_FOUND],
298
- [409, BYMAX_CONFLICT],
299
- [413, BYMAX_PAYLOAD_TOO_LARGE],
300
- [415, BYMAX_UNSUPPORTED_MEDIA_TYPE],
301
- [422, BYMAX_UNPROCESSABLE_ENTITY],
302
- [429, BYMAX_TOO_MANY_REQUESTS],
303
- [500, BYMAX_INTERNAL_ERROR],
304
- [501, BYMAX_NOT_IMPLEMENTED],
305
- [502, BYMAX_BAD_GATEWAY],
306
- [503, BYMAX_SERVICE_UNAVAILABLE],
307
- [504, BYMAX_GATEWAY_TIMEOUT]
308
- ]);
309
- var CLIENT_ERROR_MIN = 400;
310
- var CLIENT_ERROR_MAX = 500;
311
- function codeForStatus(status) {
312
- const catalogued = STATUS_CODES.get(status);
313
- if (catalogued !== void 0) {
314
- return catalogued;
315
- }
316
- if (status >= CLIENT_ERROR_MIN && status < CLIENT_ERROR_MAX) {
317
- return BYMAX_CLIENT_ERROR;
318
- }
319
- return BYMAX_INTERNAL_ERROR;
320
- }
321
-
322
375
  // src/envelope/error-envelope.ts
323
376
  function buildErrorEnvelope(input) {
324
377
  const base = {
@@ -357,6 +410,12 @@ function extractRequestInfo(context) {
357
410
  var INTERNAL_ERROR_STATUS = 500;
358
411
  var INTERNAL_ERROR_MESSAGE = "Internal server error";
359
412
  var VALIDATION_FAILED_MESSAGE = "Validation failed";
413
+ var MALFORMED_REQUEST_MESSAGE = "Malformed request";
414
+ var PRE_ROUTING_MESSAGES = /* @__PURE__ */ new Map([
415
+ [400, MALFORMED_REQUEST_MESSAGE],
416
+ [413, "Request entity too large"],
417
+ [415, "Unsupported media type"]
418
+ ]);
360
419
  var ABSOLUTE_FORM_PREFIX = /^[A-Za-z][A-Za-z0-9+.-]*:\/\//;
361
420
  function pathOf(url) {
362
421
  let target = String(url);
@@ -407,8 +466,9 @@ function resolveExposedClientError(exception) {
407
466
  if (typeof status !== "number" || !Number.isInteger(status) || status < CLIENT_ERROR_MIN2 || status >= CLIENT_ERROR_MAX2) {
408
467
  return void 0;
409
468
  }
469
+ const fixed = typeof candidate.type === "string" ? PRE_ROUTING_MESSAGES.get(status) : void 0;
410
470
  const message = exception instanceof Error ? exception.message : "";
411
- return { status, message: message === "" ? INTERNAL_ERROR_MESSAGE : message };
471
+ return { status, message: fixed ?? (message === "" ? INTERNAL_ERROR_MESSAGE : message) };
412
472
  }
413
473
  function isValidationResponse(response) {
414
474
  return typeof response === "object" && response !== null && "message" in response && Array.isArray(response.message);
@@ -609,6 +669,9 @@ var BymaxExceptionFilter = class {
609
669
  toValidationDetails(response.message)
610
670
  );
611
671
  }
672
+ if (status === 400 && readRequestInfo(request).route === UNMATCHED_ROUTE) {
673
+ return this.toEnvelope(status, codeForStatus(status), MALFORMED_REQUEST_MESSAGE, context);
674
+ }
612
675
  const message = extractHttpMessage(response, exception);
613
676
  const rawUrl = String(this.adapterHost.httpAdapter.getRequestUrl(request));
614
677
  return this.toEnvelope(
@@ -1685,12 +1748,14 @@ var BymaxCoreModule = class extends BymaxCoreModuleBase {
1685
1748
  * @param consumer - Nest's middleware consumer.
1686
1749
  */
1687
1750
  configure(consumer) {
1688
- if (!this.resolved.timing.enabled) {
1689
- return;
1690
- }
1691
1751
  const adapter = this.adapterHost?.httpAdapter;
1692
- const onFastify = bridgeFastifyRouteMetadata(adapter);
1693
- consumer.apply(BymaxTimingMiddleware).forRoutes(onFastify ? "{*splat}" : "/");
1752
+ if (this.resolved.timing.enabled) {
1753
+ const onFastify = bridgeFastifyRouteMetadata(adapter);
1754
+ consumer.apply(BymaxTimingMiddleware).forRoutes(onFastify ? "{*splat}" : "/");
1755
+ }
1756
+ if (this.resolved.bodyDepth.enabled && adapter?.getType?.() !== "fastify") {
1757
+ consumer.apply(BymaxBodyDepthMiddleware).forRoutes("/");
1758
+ }
1694
1759
  }
1695
1760
  /**
1696
1761
  * Register the module synchronously. Options are known now, so disabled
@@ -1882,4 +1947,4 @@ TimingInterceptor = __decorateClass([
1882
1947
  __decorateParam(3, Inject(BYMAX_TRACE_CONTEXT))
1883
1948
  ], TimingInterceptor);
1884
1949
 
1885
- export { BYMAX_BAD_GATEWAY, BYMAX_BAD_REQUEST, BYMAX_CLIENT_ERROR, BYMAX_CONFLICT, BYMAX_CORE_OPTIONS, BYMAX_CORRELATION_PROVIDER, BYMAX_FORBIDDEN, BYMAX_GATEWAY_TIMEOUT, BYMAX_HEALTH_INDICATORS, BYMAX_HEALTH_TRANSITION_SINK, BYMAX_INTERNAL_ERROR, BYMAX_METRICS_REGISTRY, BYMAX_NOT_FOUND, BYMAX_NOT_IMPLEMENTED, BYMAX_PAYLOAD_TOO_LARGE, BYMAX_SERVICE_UNAVAILABLE, BYMAX_TIMING_SINK, BYMAX_TOO_MANY_REQUESTS, BYMAX_TRACE_CONTEXT, BYMAX_UNAUTHORIZED, BYMAX_UNEXPECTED_ERROR_SINK, BYMAX_UNPROCESSABLE_ENTITY, BYMAX_UNSUPPORTED_MEDIA_TYPE, BYMAX_VALIDATION_FAILED, BymaxCoreModule, BymaxExceptionFilter, BymaxTimingMiddleware, TimingInterceptor, UNMATCHED_ROUTE, buildErrorEnvelope, codeForStatus };
1950
+ export { BYMAX_BAD_GATEWAY, BYMAX_BAD_REQUEST, BYMAX_CLIENT_ERROR, BYMAX_CONFLICT, BYMAX_CORE_OPTIONS, BYMAX_CORRELATION_PROVIDER, BYMAX_FORBIDDEN, BYMAX_GATEWAY_TIMEOUT, BYMAX_HEALTH_INDICATORS, BYMAX_HEALTH_TRANSITION_SINK, BYMAX_INTERNAL_ERROR, BYMAX_METRICS_REGISTRY, BYMAX_NOT_FOUND, BYMAX_NOT_IMPLEMENTED, BYMAX_PAYLOAD_TOO_LARGE, BYMAX_SERVICE_UNAVAILABLE, BYMAX_TIMING_SINK, BYMAX_TOO_MANY_REQUESTS, BYMAX_TRACE_CONTEXT, BYMAX_UNAUTHORIZED, BYMAX_UNEXPECTED_ERROR_SINK, BYMAX_UNPROCESSABLE_ENTITY, BYMAX_UNSUPPORTED_MEDIA_TYPE, BYMAX_VALIDATION_FAILED, BymaxBodyDepthMiddleware, BymaxCoreModule, BymaxExceptionFilter, BymaxTimingMiddleware, TimingInterceptor, UNMATCHED_ROUTE, buildErrorEnvelope, codeForStatus };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bymax-one/nest-core",
3
- "version": "1.6.5",
3
+ "version": "1.6.7",
4
4
  "description": "Zero-dependency NestJS 11 application foundation kit: error-envelope exception filter, request-timing middleware, pagination helpers, health endpoints with indicator discovery, an optional Prometheus metrics endpoint with a contribution contract, OpenAPI documents in development, and OpenTelemetry trace correlation.",
5
5
  "author": "Bymax One <support@bymax.one>",
6
6
  "license": "MIT",
@@ -63,6 +63,16 @@
63
63
  "default": "./dist/metrics/index.cjs"
64
64
  }
65
65
  },
66
+ "./http": {
67
+ "import": {
68
+ "types": "./dist/http/index.d.ts",
69
+ "default": "./dist/http/index.mjs"
70
+ },
71
+ "require": {
72
+ "types": "./dist/http/index.d.cts",
73
+ "default": "./dist/http/index.cjs"
74
+ }
75
+ },
66
76
  "./openapi": {
67
77
  "import": {
68
78
  "types": "./dist/openapi/index.d.ts",
@@ -77,6 +87,7 @@
77
87
  },
78
88
  "scripts": {
79
89
  "build": "pnpm clean && tsup",
90
+ "check:file-length": "node scripts/check-file-length.mjs",
80
91
  "check:exports": "attw --pack . --profile strict",
81
92
  "check:mutants": "node scripts/check-mutation-directives.mjs",
82
93
  "check:published": "node scripts/check-published-surface.mjs",
@@ -94,8 +105,8 @@
94
105
  "size": "node scripts/check-size.mjs",
95
106
  "test": "jest",
96
107
  "test:cov": "jest --coverage",
97
- "test:cov:all": "jest --config jest.coverage.config.ts --coverage",
98
- "test:e2e": "jest --config jest.e2e.config.ts",
108
+ "test:cov:all": "node --experimental-vm-modules --disable-warning=ExperimentalWarning node_modules/jest/bin/jest.js --config jest.coverage.config.ts --coverage",
109
+ "test:e2e": "node --experimental-vm-modules --disable-warning=ExperimentalWarning node_modules/jest/bin/jest.js --config jest.e2e.config.ts",
99
110
  "test:watch": "jest --watch",
100
111
  "typecheck": "tsc --noEmit"
101
112
  },
@@ -113,6 +124,7 @@
113
124
  "@nestjs/core": "^11.1.18",
114
125
  "@nestjs/swagger": "^11.0.0",
115
126
  "@opentelemetry/api": "^1.9.0",
127
+ "helmet": "^8.0.0",
116
128
  "prom-client": "^15.0.0",
117
129
  "reflect-metadata": "^0.2.0",
118
130
  "rxjs": "^7.0.0"
@@ -124,6 +136,9 @@
124
136
  "@opentelemetry/api": {
125
137
  "optional": true
126
138
  },
139
+ "helmet": {
140
+ "optional": true
141
+ },
127
142
  "prom-client": {
128
143
  "optional": true
129
144
  }
@@ -150,6 +165,8 @@
150
165
  "@types/supertest": "^7.2.0",
151
166
  "@typescript-eslint/eslint-plugin": "^8.59.3",
152
167
  "@typescript-eslint/parser": "^8.59.3",
168
+ "class-transformer": "^0.5.1",
169
+ "class-validator": "^0.15.1",
153
170
  "eslint": "^9.39.4",
154
171
  "eslint-config-prettier": "^10.1.8",
155
172
  "eslint-import-resolver-typescript": "^4.4.4",
@@ -158,6 +175,7 @@
158
175
  "eslint-plugin-security": "^4.0.0",
159
176
  "fastify": "^5.12.5",
160
177
  "globals": "^17.6.0",
178
+ "helmet": "^8.3.0",
161
179
  "husky": "^9.1.7",
162
180
  "jest": "^30.4.2",
163
181
  "lint-staged": "^17.2.0",
@@ -182,6 +200,7 @@
182
200
  "metrics",
183
201
  "openapi",
184
202
  "swagger",
203
+ "helmet",
185
204
  "opentelemetry",
186
205
  "tracing",
187
206
  "typescript"
@@ -209,6 +228,9 @@
209
228
  ],
210
229
  "metrics": [
211
230
  "./dist/metrics/index.d.cts"
231
+ ],
232
+ "http": [
233
+ "./dist/http/index.d.cts"
212
234
  ]
213
235
  }
214
236
  }