@zudojs/http 1.1.0 → 1.2.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.
Files changed (79) hide show
  1. package/README.md +53 -3
  2. package/dist/httpAdapter/http.adapter.d.ts +34 -3
  3. package/dist/httpAdapter/http.adapter.js +22 -6
  4. package/dist/httpAdapter/http.adapters.js +4 -34
  5. package/dist/httpAdapter/httpAdapter.errorResponse.d.ts +2 -2
  6. package/dist/httpAdapter/httpAdapter.errorResponse.js +26 -9
  7. package/dist/httpAdapter/httpAdapter.logger.d.ts +19 -0
  8. package/dist/httpAdapter/httpAdapter.logger.js +21 -0
  9. package/dist/httpAdapter/node/httpNode.adapter.d.ts +12 -1
  10. package/dist/httpAdapter/node/httpNode.adapter.js +28 -14
  11. package/dist/httpAdapter/node/httpNode.request.d.ts +8 -7
  12. package/dist/httpAdapter/node/httpNode.request.js +17 -27
  13. package/dist/httpAdapter/node/httpNode.server.d.ts +6 -0
  14. package/dist/httpAdapter/node/httpNode.server.js +6 -0
  15. package/dist/httpAdapter/node/httpNode.type.d.ts +2 -1
  16. package/dist/httpCookies/http.cookies.d.ts +29 -2
  17. package/dist/httpCookies/http.cookies.js +44 -24
  18. package/dist/httpCookies/httpCookies.defaults.d.ts +40 -0
  19. package/dist/httpCookies/httpCookies.defaults.js +42 -0
  20. package/dist/httpCookies/index.d.ts +1 -0
  21. package/dist/httpCookies/index.js +1 -0
  22. package/dist/httpMiddleware/builtin/conditional/httpMiddleware.conditional.d.ts +22 -1
  23. package/dist/httpMiddleware/builtin/conditional/httpMiddleware.conditional.js +19 -4
  24. package/dist/httpMiddleware/builtin/conditional/index.d.ts +1 -0
  25. package/dist/httpMiddleware/builtin/cors/httpMiddleware.cors.d.ts +8 -0
  26. package/dist/httpMiddleware/builtin/cors/httpMiddleware.cors.js +25 -22
  27. package/dist/httpMiddleware/builtin/helpers/httpMiddleware.accessor.js +2 -6
  28. package/dist/httpMiddleware/builtin/helpers/httpMiddleware.media.d.ts +33 -0
  29. package/dist/httpMiddleware/builtin/helpers/httpMiddleware.media.js +59 -0
  30. package/dist/httpMiddleware/builtin/helpers/index.d.ts +1 -0
  31. package/dist/httpMiddleware/builtin/helpers/index.js +1 -0
  32. package/dist/httpMiddleware/builtin/image/httpMiddleware.image.d.ts +13 -0
  33. package/dist/httpMiddleware/builtin/image/httpMiddleware.image.js +31 -53
  34. package/dist/httpMiddleware/builtin/index.d.ts +1 -0
  35. package/dist/httpMiddleware/builtin/index.js +1 -0
  36. package/dist/httpMiddleware/builtin/rateLimit/httpMiddleware.rateLimit.d.ts +47 -0
  37. package/dist/httpMiddleware/builtin/rateLimit/httpMiddleware.rateLimit.js +61 -0
  38. package/dist/httpMiddleware/builtin/rateLimit/index.d.ts +7 -0
  39. package/dist/httpMiddleware/builtin/rateLimit/index.js +7 -0
  40. package/dist/httpMiddleware/builtin/static/httpMiddleware.static.js +18 -4
  41. package/dist/httpMiddleware/builtin/video/httpMiddleware.video.d.ts +19 -1
  42. package/dist/httpMiddleware/builtin/video/httpMiddleware.video.js +38 -59
  43. package/dist/httpMiddleware/builtin/video/httpMiddleware.video.options.d.ts +12 -0
  44. package/dist/httpMiddleware/builtin/video/httpMiddleware.video.options.js +31 -0
  45. package/dist/httpMiddleware/httpMiddleware.error.d.ts +5 -31
  46. package/dist/httpMiddleware/httpMiddleware.error.js +5 -53
  47. package/dist/httpProxy/http.proxy.d.ts +7 -0
  48. package/dist/httpProxy/http.proxy.js +9 -0
  49. package/dist/httpProxy/httpProxy.pathGuard.d.ts +23 -0
  50. package/dist/httpProxy/httpProxy.pathGuard.js +43 -0
  51. package/dist/httpProxy/index.d.ts +1 -0
  52. package/dist/httpProxy/index.js +1 -0
  53. package/dist/httpRequest/httpRequest.context.d.ts +7 -0
  54. package/dist/httpRequest/httpRequest.context.js +15 -16
  55. package/dist/httpRequest/index.d.ts +1 -0
  56. package/dist/httpRequest/index.js +1 -0
  57. package/dist/httpRequest/target/httpRequest.target.d.ts +45 -0
  58. package/dist/httpRequest/target/httpRequest.target.js +93 -0
  59. package/dist/httpRequest/target/index.d.ts +9 -0
  60. package/dist/httpRequest/target/index.js +9 -0
  61. package/dist/httpResponse/httpResponse.helper.js +2 -1
  62. package/dist/httpRouter/core/util/httpRoute.util.d.ts +14 -0
  63. package/dist/httpRouter/core/util/httpRoute.util.js +18 -14
  64. package/dist/httpSecurity/httpSecurity.config.d.ts +6 -0
  65. package/dist/httpSecurity/httpSecurity.config.js +1 -0
  66. package/dist/httpSecurity/httpSecurity.guard.d.ts +7 -9
  67. package/dist/httpSecurity/httpSecurity.guard.js +7 -14
  68. package/dist/httpSecurity/httpSecurity.nodeGuard.d.ts +48 -0
  69. package/dist/httpSecurity/httpSecurity.nodeGuard.js +32 -0
  70. package/dist/httpSecurity/httpSecurity.validator.js +4 -2
  71. package/dist/httpSecurity/index.d.ts +2 -0
  72. package/dist/httpSecurity/index.js +1 -0
  73. package/dist/httpServer/core/httpServer.core.d.ts +11 -0
  74. package/dist/httpServer/core/httpServer.core.js +30 -4
  75. package/dist/httpTrustProxy/httpTrustProxy.compilation.d.ts +5 -2
  76. package/dist/httpTrustProxy/httpTrustProxy.compilation.js +19 -2
  77. package/dist/httpTrustProxy/httpTrustProxy.type.d.ts +3 -1
  78. package/dist/index.js +0 -1
  79. package/package.json +5 -5
@@ -6,6 +6,7 @@
6
6
  import { isHttpAdapter, startAdapter, stopAdapter, } from "../../httpAdapter/http.adapter.js";
7
7
  import { HttpServerLifecycleError, InvalidHttpServerStateError, HttpServerStartError, HttpServerStopError, } from "@zudojs/errors";
8
8
  import { withTimeout, validateShutdownTimeout, } from "../factory/httpServer.factory.js";
9
+ const SHUTDOWN_CLOSE_MARGIN_MS = 1_000;
9
10
  export class HttpServer {
10
11
  name;
11
12
  adapter;
@@ -170,7 +171,22 @@ export class HttpServer {
170
171
  this.adapterErrorHandler(handler);
171
172
  return this;
172
173
  }
173
- adapterHandler(handler) {
174
+ /**
175
+ * Installs `handler` on the adapter, wrapped so every dispatch is counted
176
+ * (`requests`, `onRequest`) and its completion reported (`onResponse`).
177
+ * Nothing called `recordRequest`/`recordResponse` before, so the counter
178
+ * and both events stayed at zero.
179
+ */
180
+ adapterHandler(application) {
181
+ const handler = async (request) => {
182
+ this.recordRequest();
183
+ try {
184
+ return await application(request);
185
+ }
186
+ finally {
187
+ this.recordResponse();
188
+ }
189
+ };
174
190
  const adapter = this.adapter;
175
191
  if (typeof adapter.setHandler === "function") {
176
192
  adapter.setHandler(handler);
@@ -262,13 +278,23 @@ export class HttpServer {
262
278
  async performStart() {
263
279
  await startAdapter(this.adapter);
264
280
  }
281
+ /**
282
+ * The adapter is told the shutdown timeout as its grace period, so
283
+ * in-flight requests get the documented `gracefulShutdownTimeout` rather
284
+ * than the Node adapter's hidden 10 s default.
285
+ */
286
+ /*
287
+ * The adapter gets the full timeout as its grace period and then destroys
288
+ * the remaining sockets; the margin only lets that close complete before
289
+ * the stop is reported as timed out.
290
+ */
265
291
  async performStop(force, timeout) {
266
292
  if (force) {
267
- await stopAdapter(this.adapter);
293
+ await stopAdapter(this.adapter, { graceMs: 0 });
268
294
  return;
269
295
  }
270
296
  try {
271
- await withTimeout(stopAdapter(this.adapter), timeout, "HTTP server shutdown timed out.");
297
+ await withTimeout(stopAdapter(this.adapter, { graceMs: timeout }), timeout + SHUTDOWN_CLOSE_MARGIN_MS, "HTTP server shutdown timed out.");
272
298
  }
273
299
  catch (error) {
274
300
  /*
@@ -277,7 +303,7 @@ export class HttpServer {
277
303
  * rebind the port. Escalate to a forced stop before rethrowing.
278
304
  */
279
305
  try {
280
- await stopAdapter(this.adapter);
306
+ await stopAdapter(this.adapter, { graceMs: 0 });
281
307
  }
282
308
  catch {
283
309
  /* The original timeout is the more useful error. */
@@ -23,10 +23,13 @@ export type TrustProxyPredicate = (value: string, index: number) => boolean;
23
23
  * - `"loopback"`, `"linklocal"`, `"uniquelocal"` / `"private"` — named ranges.
24
24
  * - an IP address, a CIDR range, a comma-separated list of either, or an array
25
25
  * of the same.
26
+ * - a hop count `n`: trust the `n` hops nearest the server (the socket peer
27
+ * is hop `0`), as Express/`proxy-addr` do. `0` trusts nothing.
26
28
  * - a custom predicate `(address, hopIndexFromPeer) => boolean`.
27
29
  *
28
- * Throws `TypeError` on a string that is none of the above rather than
29
- * returning a predicate that can never match.
30
+ * Throws `TypeError` on a string that is none of the above, or on a hop
31
+ * count that is not a non-negative integer, rather than returning a
32
+ * predicate that can never match.
30
33
  */
31
34
  export declare function compileTrustProxy(trustProxy: TrustProxy): TrustProxyPredicate;
32
35
  //# sourceMappingURL=httpTrustProxy.compilation.d.ts.map
@@ -88,10 +88,13 @@ function buildListPredicate(trustProxy) {
88
88
  * - `"loopback"`, `"linklocal"`, `"uniquelocal"` / `"private"` — named ranges.
89
89
  * - an IP address, a CIDR range, a comma-separated list of either, or an array
90
90
  * of the same.
91
+ * - a hop count `n`: trust the `n` hops nearest the server (the socket peer
92
+ * is hop `0`), as Express/`proxy-addr` do. `0` trusts nothing.
91
93
  * - a custom predicate `(address, hopIndexFromPeer) => boolean`.
92
94
  *
93
- * Throws `TypeError` on a string that is none of the above rather than
94
- * returning a predicate that can never match.
95
+ * Throws `TypeError` on a string that is none of the above, or on a hop
96
+ * count that is not a non-negative integer, rather than returning a
97
+ * predicate that can never match.
95
98
  */
96
99
  export function compileTrustProxy(trustProxy) {
97
100
  if (typeof trustProxy === "function") {
@@ -100,6 +103,9 @@ export function compileTrustProxy(trustProxy) {
100
103
  if (trustProxy === true) {
101
104
  return () => true;
102
105
  }
106
+ if (typeof trustProxy === "number") {
107
+ return compileHopCount(trustProxy);
108
+ }
103
109
  /* Anything that is not a string or a list (including `false`, `undefined`
104
110
  * and any malformed runtime value) trusts nothing. */
105
111
  if (typeof trustProxy !== "string" && !Array.isArray(trustProxy)) {
@@ -116,4 +122,15 @@ export function compileTrustProxy(trustProxy) {
116
122
  compilationCache.set(trustProxy, predicate);
117
123
  return predicate;
118
124
  }
125
+ /**
126
+ * Hop-count trust. The numeric form was typed and documented ("trust N
127
+ * proxies") but fell through to "trust nothing", so behind a load balancer
128
+ * every client shared the balancer's address.
129
+ */
130
+ function compileHopCount(hops) {
131
+ if (!Number.isSafeInteger(hops) || hops < 0) {
132
+ throw new TypeError(`trustProxy hop count must be a non-negative integer, got ${hops}.`);
133
+ }
134
+ return (_address, index) => index < hops;
135
+ }
119
136
  //# sourceMappingURL=httpTrustProxy.compilation.js.map
@@ -3,7 +3,9 @@
3
3
  *
4
4
  * @module httpTrustProxy/types
5
5
  */
6
- export type TrustProxy = boolean | "all" | "linklocal" | "loopback" | string | readonly string[] | ((value: string, index: number) => boolean);
6
+ export type TrustProxy = boolean
7
+ /** Hop count: trust the `n` hops nearest the server (the peer is hop 0). */
8
+ | number | "all" | "linklocal" | "loopback" | string | readonly string[] | ((value: string, index: number) => boolean);
7
9
  export interface TrustProxyOptions {
8
10
  readonly trustProxy?: TrustProxy;
9
11
  readonly maxDepth?: number;
package/dist/index.js CHANGED
@@ -7,7 +7,6 @@
7
7
  * TypeScript reports TS2308 (ambiguous re-exports) for these duplicates.
8
8
  * This is intentional — consumers can import from either path.
9
9
  */
10
- /* eslint-disable @typescript-eslint/no-explicit-any */
11
10
  export * from "./httpProtocol/index.js";
12
11
  export * from "./httpTypes/index.js";
13
12
  export * from "./httpConstants/index.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zudojs/http",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "HTTP primitives, request handling, routing, middleware, and server infrastructure for Zudojs applications.",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -24,10 +24,10 @@
24
24
  "!dist/.tsbuildinfo"
25
25
  ],
26
26
  "dependencies": {
27
- "@zudojs/core": "1.1.0",
28
- "@zudojs/errors": "1.0.1",
29
- "@zudojs/logger": "1.1.0",
30
- "@zudojs/security": "1.0.1"
27
+ "@zudojs/crypto": "1.2.0",
28
+ "@zudojs/errors": "1.1.0",
29
+ "@zudojs/logger": "1.2.0",
30
+ "@zudojs/security": "1.1.0"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/node": "^26.4.1",