@fluojs/http 1.1.2 → 3.0.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 (125) hide show
  1. package/README.ko.md +430 -15
  2. package/README.md +437 -15
  3. package/dist/access-log-observer.d.ts +77 -0
  4. package/dist/access-log-observer.d.ts.map +1 -0
  5. package/dist/access-log-observer.js +171 -0
  6. package/dist/adapter.d.ts +9 -0
  7. package/dist/adapter.d.ts.map +1 -1
  8. package/dist/adapter.js +15 -1
  9. package/dist/adapters/binding.d.ts.map +1 -1
  10. package/dist/adapters/binding.js +18 -16
  11. package/dist/adapters/dto-binding-plan.d.ts +2 -2
  12. package/dist/adapters/dto-binding-plan.d.ts.map +1 -1
  13. package/dist/adapters/dto-binding-plan.js +13 -4
  14. package/dist/adapters/dto-validation-adapter.d.ts +2 -1
  15. package/dist/adapters/dto-validation-adapter.d.ts.map +1 -1
  16. package/dist/adapters/dto-validation-adapter.js +2 -2
  17. package/dist/byte-range-response.d.ts +71 -0
  18. package/dist/byte-range-response.d.ts.map +1 -0
  19. package/dist/byte-range-response.js +347 -0
  20. package/dist/client-identity.d.ts +8 -4
  21. package/dist/client-identity.d.ts.map +1 -1
  22. package/dist/client-identity.js +12 -93
  23. package/dist/compiled-route-identity.d.ts +17 -0
  24. package/dist/compiled-route-identity.d.ts.map +1 -0
  25. package/dist/compiled-route-identity.js +29 -0
  26. package/dist/connection.d.ts +67 -0
  27. package/dist/connection.d.ts.map +1 -0
  28. package/dist/connection.js +480 -0
  29. package/dist/context/request-context-node-store.d.ts +6 -0
  30. package/dist/context/request-context-node-store.d.ts.map +1 -1
  31. package/dist/context/request-context-node-store.js +14 -0
  32. package/dist/context/request-context.d.ts +5 -5
  33. package/dist/context/request-context.d.ts.map +1 -1
  34. package/dist/context/request-context.js +8 -83
  35. package/dist/context/request-id.d.ts +10 -0
  36. package/dist/context/request-id.d.ts.map +1 -0
  37. package/dist/context/request-id.js +27 -0
  38. package/dist/context/sse.d.ts +13 -0
  39. package/dist/context/sse.d.ts.map +1 -1
  40. package/dist/context/sse.js +36 -6
  41. package/dist/cookie-helpers.d.ts +47 -0
  42. package/dist/cookie-helpers.d.ts.map +1 -0
  43. package/dist/cookie-helpers.js +166 -0
  44. package/dist/decorators.d.ts +52 -19
  45. package/dist/decorators.d.ts.map +1 -1
  46. package/dist/decorators.js +57 -10
  47. package/dist/dispatch/conditional-request-policy.d.ts +67 -0
  48. package/dist/dispatch/conditional-request-policy.d.ts.map +1 -0
  49. package/dist/dispatch/conditional-request-policy.js +297 -0
  50. package/dist/dispatch/dispatch-content-negotiation.d.ts +8 -0
  51. package/dist/dispatch/dispatch-content-negotiation.d.ts.map +1 -1
  52. package/dist/dispatch/dispatch-content-negotiation.js +89 -42
  53. package/dist/dispatch/dispatch-error-negotiation.d.ts +26 -0
  54. package/dist/dispatch/dispatch-error-negotiation.d.ts.map +1 -0
  55. package/dist/dispatch/dispatch-error-negotiation.js +110 -0
  56. package/dist/dispatch/dispatch-error-policy.d.ts +1 -10
  57. package/dist/dispatch/dispatch-error-policy.d.ts.map +1 -1
  58. package/dist/dispatch/dispatch-error-policy.js +1 -33
  59. package/dist/dispatch/dispatch-error-representation.d.ts +18 -0
  60. package/dist/dispatch/dispatch-error-representation.d.ts.map +1 -0
  61. package/dist/dispatch/dispatch-error-representation.js +125 -0
  62. package/dist/dispatch/dispatch-response-metadata.d.ts +10 -0
  63. package/dist/dispatch/dispatch-response-metadata.d.ts.map +1 -0
  64. package/dist/dispatch/dispatch-response-metadata.js +12 -0
  65. package/dist/dispatch/dispatch-response-policy.d.ts +33 -5
  66. package/dist/dispatch/dispatch-response-policy.d.ts.map +1 -1
  67. package/dist/dispatch/dispatch-response-policy.js +149 -18
  68. package/dist/dispatch/dispatcher.d.ts +5 -1
  69. package/dist/dispatch/dispatcher.d.ts.map +1 -1
  70. package/dist/dispatch/dispatcher.js +178 -107
  71. package/dist/dispatch/fast-path/debug-visibility.d.ts.map +1 -1
  72. package/dist/dispatch/fast-path/debug-visibility.js +6 -3
  73. package/dist/dispatch/fast-path/dispatcher-state.d.ts +10 -0
  74. package/dist/dispatch/fast-path/dispatcher-state.d.ts.map +1 -0
  75. package/dist/dispatch/fast-path/dispatcher-state.js +52 -0
  76. package/dist/dispatch/fast-path/eligibility-checker.d.ts.map +1 -1
  77. package/dist/dispatch/fast-path/eligibility-checker.js +27 -15
  78. package/dist/dispatch/fast-path/eligibility.d.ts +16 -10
  79. package/dist/dispatch/fast-path/eligibility.d.ts.map +1 -1
  80. package/dist/dispatch/fast-path/eligibility.js +10 -4
  81. package/dist/dispatch/fast-path/fast-path-executor.d.ts +14 -1
  82. package/dist/dispatch/fast-path/fast-path-executor.d.ts.map +1 -1
  83. package/dist/dispatch/fast-path/fast-path-executor.js +23 -6
  84. package/dist/dispatch/request-abort.d.ts +22 -0
  85. package/dist/dispatch/request-abort.d.ts.map +1 -0
  86. package/dist/dispatch/request-abort.js +30 -0
  87. package/dist/dispatch/response-integration.d.ts +55 -0
  88. package/dist/dispatch/response-integration.d.ts.map +1 -0
  89. package/dist/dispatch/response-integration.js +57 -0
  90. package/dist/errors.d.ts +10 -0
  91. package/dist/errors.d.ts.map +1 -1
  92. package/dist/errors.js +19 -0
  93. package/dist/guards.d.ts +1 -1
  94. package/dist/guards.d.ts.map +1 -1
  95. package/dist/header-helpers.d.ts +59 -0
  96. package/dist/header-helpers.d.ts.map +1 -0
  97. package/dist/header-helpers.js +185 -0
  98. package/dist/index.d.ts +1 -16
  99. package/dist/index.d.ts.map +1 -1
  100. package/dist/index.js +4 -15
  101. package/dist/index.portable.d.ts +25 -0
  102. package/dist/index.portable.d.ts.map +1 -0
  103. package/dist/index.portable.js +21 -0
  104. package/dist/internal.d.ts +3 -1
  105. package/dist/internal.d.ts.map +1 -1
  106. package/dist/internal.js +2 -0
  107. package/dist/mapping.d.ts.map +1 -1
  108. package/dist/mapping.js +100 -15
  109. package/dist/middleware/correlation.d.ts +9 -1
  110. package/dist/middleware/correlation.d.ts.map +1 -1
  111. package/dist/middleware/correlation.js +25 -14
  112. package/dist/middleware/cors.d.ts.map +1 -1
  113. package/dist/middleware/cors.js +7 -8
  114. package/dist/middleware/middleware.d.ts +3 -3
  115. package/dist/middleware/middleware.d.ts.map +1 -1
  116. package/dist/middleware/rate-limit.d.ts +13 -2
  117. package/dist/middleware/rate-limit.d.ts.map +1 -1
  118. package/dist/middleware/rate-limit.js +1 -0
  119. package/dist/static-assets.d.ts +77 -0
  120. package/dist/static-assets.d.ts.map +1 -0
  121. package/dist/static-assets.js +270 -0
  122. package/dist/types.d.ts +225 -17
  123. package/dist/types.d.ts.map +1 -1
  124. package/dist/types.js +71 -1
  125. package/package.json +19 -9
@@ -0,0 +1,27 @@
1
+ import { getRequestHeader } from '../header-helpers.js';
2
+ const REQUEST_ID_HEADER = 'x-request-id';
3
+ const CORRELATION_ID_HEADER = 'x-correlation-id';
4
+ function readInboundHeaderValue(request, headerName) {
5
+ const rawHeaderValue = getRequestHeader(request, headerName);
6
+ const value = Array.isArray(rawHeaderValue) ? rawHeaderValue[0] : rawHeaderValue;
7
+ const normalized = value?.trim();
8
+ return normalized ? normalized : undefined;
9
+ }
10
+ function createRequestId() {
11
+ const randomUUID = globalThis.crypto?.randomUUID;
12
+ if (randomUUID) {
13
+ return randomUUID.call(globalThis.crypto);
14
+ }
15
+ return `req_${Date.now().toString(36)}_${Math.random().toString(36).slice(2)}`;
16
+ }
17
+
18
+ /**
19
+ * Resolves the request identity before dispatcher observers begin.
20
+ *
21
+ * @param request Adapter-normalized request carrying inbound correlation headers.
22
+ * @param generate Whether to generate an ID when neither supported inbound header is present.
23
+ * @returns The adopted request or legacy correlation ID, or a newly generated ID.
24
+ */
25
+ export function resolveRequestId(request, generate = true) {
26
+ return readInboundHeaderValue(request, REQUEST_ID_HEADER) ?? readInboundHeaderValue(request, CORRELATION_ID_HEADER) ?? (generate ? createRequestId() : undefined);
27
+ }
@@ -53,6 +53,8 @@ export declare function encodeSseMessage(data: unknown, options?: SseSendOptions
53
53
  export declare class SseResponse {
54
54
  private readonly context;
55
55
  private closed;
56
+ private resolveCompletion;
57
+ private readonly completionPromise;
56
58
  private readonly stream;
57
59
  private removeCloseListener?;
58
60
  private readonly onAbort;
@@ -72,8 +74,19 @@ export declare class SseResponse {
72
74
  * @returns `true` when the underlying stream accepted the frame without backpressure.
73
75
  */
74
76
  comment(comment: string): boolean;
77
+ /** @internal Completion signal consumed by the dispatcher for manual SSE responses. */
78
+ get completion(): Promise<void>;
75
79
  /** Closes the SSE stream and removes registered abort/close listeners exactly once. */
76
80
  close(): void;
77
81
  private writeFrame;
78
82
  }
83
+ /**
84
+ * Resolves after a manual SSE response closes through any supported termination path.
85
+ *
86
+ * @param response Manual SSE response whose lifecycle is observed.
87
+ * @returns A promise that resolves after the response closes.
88
+ *
89
+ * @internal
90
+ */
91
+ export declare function waitForSseResponseCompletion(response: SseResponse): Promise<void>;
79
92
  //# sourceMappingURL=sse.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/context/sse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA8C,cAAc,EAAE,MAAM,aAAa,CAAC;AAE9F,iFAAiF;AACjF,MAAM,WAAW,cAAc;IAC7B,+EAA+E;IAC/E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,8FAA8F;IAC9F,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,UAAU,CAAC,CAAC,GAAG,OAAO,CAAE,SAAQ,cAAc;IAC7D,4DAA4D;IAC5D,IAAI,EAAE,CAAC,CAAC;CACT;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAAC,CAAC,CAAC,CAEhF;AAoCD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKxD;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,GAAE,cAAmB,GAAG,MAAM,CAoBpF;AAED;;;;;GAKG;AACH,qBAAa,WAAW;IASV,OAAO,CAAC,QAAQ,CAAC,OAAO;IARpC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;IACjD,OAAO,CAAC,mBAAmB,CAAC,CAAa;IAEzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAEtB;gBAE2B,OAAO,EAAE,cAAc;IAmCpD;;;;;;OAMG;IACH,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO;IAI1D;;;;;OAKG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAIjC,uFAAuF;IACvF,KAAK,IAAI,IAAI;IAiBb,OAAO,CAAC,UAAU;CAYnB"}
1
+ {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/context/sse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA8C,cAAc,EAAE,MAAM,aAAa,CAAC;AAG9F,iFAAiF;AACjF,MAAM,WAAW,cAAc;IAC7B,+EAA+E;IAC/E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,8FAA8F;IAC9F,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,UAAU,CAAC,CAAC,GAAG,OAAO,CAAE,SAAQ,cAAc;IAC7D,4DAA4D;IAC5D,IAAI,EAAE,CAAC,CAAC;CACT;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAAC,CAAC,CAAC,CAEhF;AAoCD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKxD;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,GAAE,cAAmB,GAAG,MAAM,CAoBpF;AAED;;;;;GAKG;AACH,qBAAa,WAAW;IAcV,OAAO,CAAC,QAAQ,CAAC,OAAO;IAbpC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,iBAAiB,CAA+B;IACxD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAE/B;IACH,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;IACjD,OAAO,CAAC,mBAAmB,CAAC,CAAa;IAEzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAGtB;gBAE2B,OAAO,EAAE,cAAc;IAoCpD;;;;;;OAMG;IACH,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO;IAI1D;;;;;OAKG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAIjC,uFAAuF;IACvF,IAAI,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAE9B;IAED,uFAAuF;IACvF,KAAK,IAAI,IAAI;IAoBb,OAAO,CAAC,UAAU;CAanB;AAED;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAEjF"}
@@ -1,3 +1,5 @@
1
+ import { markRequestContextAborted } from '../dispatch/request-abort.js';
2
+
1
3
  /** Options that customize the fields emitted for one server-sent event frame. */
2
4
 
3
5
  /**
@@ -90,9 +92,14 @@ export function encodeSseMessage(data, options = {}) {
90
92
  */
91
93
  export class SseResponse {
92
94
  closed = false;
95
+ resolveCompletion = () => undefined;
96
+ completionPromise = new Promise(resolve => {
97
+ this.resolveCompletion = resolve;
98
+ });
93
99
  stream;
94
100
  removeCloseListener;
95
101
  onAbort = () => {
102
+ markRequestContextAborted(this.context);
96
103
  this.close();
97
104
  };
98
105
  constructor(context) {
@@ -121,6 +128,7 @@ export class SseResponse {
121
128
  }
122
129
  this.removeCloseListener = removeCloseListener;
123
130
  if (this.stream.closed) {
131
+ markRequestContextAborted(this.context);
124
132
  this.close();
125
133
  }
126
134
  }
@@ -146,28 +154,50 @@ export class SseResponse {
146
154
  return this.writeFrame(encodeSseComment(comment));
147
155
  }
148
156
 
157
+ /** @internal Completion signal consumed by the dispatcher for manual SSE responses. */
158
+ get completion() {
159
+ return this.completionPromise;
160
+ }
161
+
149
162
  /** Closes the SSE stream and removes registered abort/close listeners exactly once. */
150
163
  close() {
151
164
  if (this.closed) {
152
165
  return;
153
166
  }
154
167
  this.closed = true;
155
- this.context.request.signal?.removeEventListener('abort', this.onAbort);
156
- this.removeCloseListener?.();
157
- this.removeCloseListener = undefined;
158
- if (!this.stream.closed) {
159
- this.stream.close();
168
+ try {
169
+ this.context.request.signal?.removeEventListener('abort', this.onAbort);
170
+ this.removeCloseListener?.();
171
+ this.removeCloseListener = undefined;
172
+ if (!this.stream.closed) {
173
+ this.stream.close();
174
+ }
175
+ } finally {
176
+ this.context.response.committed = true;
177
+ this.resolveCompletion();
160
178
  }
161
- this.context.response.committed = true;
162
179
  }
163
180
  writeFrame(frame) {
164
181
  if (this.closed) {
165
182
  return false;
166
183
  }
167
184
  if (this.stream.closed) {
185
+ markRequestContextAborted(this.context);
168
186
  this.close();
169
187
  return false;
170
188
  }
171
189
  return this.stream.write(frame);
172
190
  }
191
+ }
192
+
193
+ /**
194
+ * Resolves after a manual SSE response closes through any supported termination path.
195
+ *
196
+ * @param response Manual SSE response whose lifecycle is observed.
197
+ * @returns A promise that resolves after the response closes.
198
+ *
199
+ * @internal
200
+ */
201
+ export function waitForSseResponseCompletion(response) {
202
+ return response.completion;
173
203
  }
@@ -0,0 +1,47 @@
1
+ import type { FrameworkResponse } from './types.js';
2
+ /** SameSite policies supported by the portable cookie serializer. */
3
+ export type CookieSameSite = 'lax' | 'none' | 'strict';
4
+ /** Runtime-neutral attributes used when serializing one response cookie. */
5
+ export interface CookieOptions {
6
+ /** Domain that scopes the cookie. */
7
+ readonly domain?: string;
8
+ /** Absolute expiry time for the cookie. */
9
+ readonly expires?: Date;
10
+ /** Whether the cookie is inaccessible to client-side scripts. */
11
+ readonly httpOnly?: boolean;
12
+ /** Lifetime in whole seconds. */
13
+ readonly maxAgeSeconds?: number;
14
+ /** URL path that scopes the cookie. */
15
+ readonly path?: string;
16
+ /** Cross-site request policy for the cookie. */
17
+ readonly sameSite?: CookieSameSite;
18
+ /** Whether the cookie is sent only over secure connections. */
19
+ readonly secure?: boolean;
20
+ }
21
+ /**
22
+ * Attributes accepted when clearing a cookie.
23
+ *
24
+ * Only `path` and `domain` identify the browser cookie to delete. `httpOnly`,
25
+ * `secure`, and `sameSite` are deletion attributes, not cookie identity keys.
26
+ */
27
+ export type ClearCookieOptions = Omit<CookieOptions, 'expires' | 'maxAgeSeconds'>;
28
+ /**
29
+ * Serialize one runtime-neutral response cookie as an independent `Set-Cookie` field.
30
+ *
31
+ * @param response Mutable response that receives the cookie header.
32
+ * @param name Cookie name, validated as an HTTP token.
33
+ * @param value Cookie value, percent-encoded before serialization.
34
+ * @param options Explicit cookie attributes shared by all supported adapters.
35
+ * @returns Nothing. The response receives one independent cookie field.
36
+ */
37
+ export declare function setCookie(response: FrameworkResponse, name: string, value: string, options?: CookieOptions): void;
38
+ /**
39
+ * Expire one runtime-neutral response cookie while retaining its matching scope attributes.
40
+ *
41
+ * @param response Mutable response that receives the deletion cookie header.
42
+ * @param name Cookie name, validated as an HTTP token.
43
+ * @param options Original Path and Domain attributes required to target the same cookie.
44
+ * @returns Nothing. The response receives one independent deletion cookie field.
45
+ */
46
+ export declare function clearCookie(response: FrameworkResponse, name: string, options?: ClearCookieOptions): void;
47
+ //# sourceMappingURL=cookie-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cookie-helpers.d.ts","sourceRoot":"","sources":["../src/cookie-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAMpD,qEAAqE;AACrE,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEvD,4EAA4E;AAC5E,MAAM,WAAW,aAAa;IAC5B,qCAAqC;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,2CAA2C;IAC3C,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC;IACxB,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,iCAAiC;IACjC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,uCAAuC;IACvC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,gDAAgD;IAChD,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC;IACnC,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,eAAe,CAAC,CAAC;AA8KlF;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CACvB,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,aAAkB,GAC1B,IAAI,CAEN;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,kBAAuB,GAC/B,IAAI,CAUN"}
@@ -0,0 +1,166 @@
1
+ const COOKIE_DELETION_EXPIRES = new Date(0);
2
+ const COOKIE_NAME_TOKEN = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
3
+ const COOKIE_DOMAIN = /^(?:\.)?(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\.)*[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?$/;
4
+
5
+ /** SameSite policies supported by the portable cookie serializer. */
6
+
7
+ /** Runtime-neutral attributes used when serializing one response cookie. */
8
+
9
+ /**
10
+ * Attributes accepted when clearing a cookie.
11
+ *
12
+ * Only `path` and `domain` identify the browser cookie to delete. `httpOnly`,
13
+ * `secure`, and `sameSite` are deletion attributes, not cookie identity keys.
14
+ */
15
+
16
+ function readCookieOptions(options) {
17
+ const {
18
+ domain,
19
+ expires,
20
+ httpOnly,
21
+ maxAgeSeconds,
22
+ path,
23
+ sameSite,
24
+ secure
25
+ } = options;
26
+ return {
27
+ domain,
28
+ expires,
29
+ httpOnly,
30
+ maxAgeSeconds,
31
+ path,
32
+ sameSite,
33
+ secure
34
+ };
35
+ }
36
+ function validateCookieName(name) {
37
+ if (typeof name !== 'string' || !COOKIE_NAME_TOKEN.test(name)) {
38
+ throw new TypeError('Cookie names must be non-empty HTTP tokens.');
39
+ }
40
+ }
41
+ function validateOptionalBoolean(value, optionName) {
42
+ if (value !== undefined && typeof value !== 'boolean') {
43
+ throw new TypeError(`${optionName} must be a boolean when provided.`);
44
+ }
45
+ }
46
+ function validateDomain(domain) {
47
+ const host = domain.startsWith('.') ? domain.slice(1) : domain;
48
+ if (typeof domain !== 'string' || host.length === 0 || host.length > 253 || !COOKIE_DOMAIN.test(domain)) {
49
+ throw new TypeError('Cookie domains must be valid ASCII DNS names.');
50
+ }
51
+ }
52
+ function validatePath(path) {
53
+ if (typeof path !== 'string' || path.length === 0) {
54
+ throw new TypeError('Cookie paths must be non-empty RFC 6265 path values.');
55
+ }
56
+ for (const character of path) {
57
+ const codePoint = character.charCodeAt(0);
58
+ if (codePoint < 0x20 || codePoint === 0x3b || codePoint > 0x7e) {
59
+ throw new TypeError('Cookie paths must be RFC 6265 path values.');
60
+ }
61
+ }
62
+ }
63
+ function formatExpiry(expires) {
64
+ const timestamp = Date.prototype.getTime.call(expires);
65
+ if (!Number.isFinite(timestamp)) {
66
+ throw new TypeError('Cookie expiry must be a valid Date.');
67
+ }
68
+ const normalized = new Date(timestamp);
69
+ const year = normalized.getUTCFullYear();
70
+ if (year < 1601 || year > 9999) {
71
+ throw new TypeError('Cookie expiry must have a four-digit RFC 6265 year.');
72
+ }
73
+ return normalized.toUTCString();
74
+ }
75
+ function normalizeSameSite(sameSite, secure) {
76
+ if (sameSite === undefined) {
77
+ return undefined;
78
+ }
79
+ switch (sameSite) {
80
+ case 'lax':
81
+ return 'Lax';
82
+ case 'strict':
83
+ return 'Strict';
84
+ case 'none':
85
+ if (secure !== true) {
86
+ throw new TypeError('SameSite=None cookies require secure: true.');
87
+ }
88
+ return 'None';
89
+ default:
90
+ throw new TypeError('sameSite must be lax, none, or strict.');
91
+ }
92
+ }
93
+ function serializeCookie(name, value, options) {
94
+ validateCookieName(name);
95
+ if (typeof value !== 'string') {
96
+ throw new TypeError('Cookie values must be strings.');
97
+ }
98
+ validateOptionalBoolean(options.httpOnly, 'httpOnly');
99
+ validateOptionalBoolean(options.secure, 'secure');
100
+ if (options.maxAgeSeconds !== undefined) {
101
+ if (typeof options.maxAgeSeconds !== 'number' || !Number.isSafeInteger(options.maxAgeSeconds) || options.maxAgeSeconds < 0) {
102
+ throw new TypeError('maxAgeSeconds must be a non-negative safe integer.');
103
+ }
104
+ }
105
+ if (options.domain !== undefined) {
106
+ validateDomain(options.domain);
107
+ }
108
+ if (options.path !== undefined) {
109
+ validatePath(options.path);
110
+ }
111
+ const sameSite = normalizeSameSite(options.sameSite, options.secure);
112
+ const encodedValue = encodeURIComponent(value);
113
+ const parts = [`${name}=${encodedValue}`];
114
+ if (options.maxAgeSeconds !== undefined) {
115
+ parts.push(`Max-Age=${options.maxAgeSeconds}`);
116
+ }
117
+ if (options.expires !== undefined) {
118
+ parts.push(`Expires=${formatExpiry(options.expires)}`);
119
+ }
120
+ if (options.path !== undefined) {
121
+ parts.push(`Path=${options.path}`);
122
+ }
123
+ if (options.domain !== undefined) {
124
+ parts.push(`Domain=${options.domain}`);
125
+ }
126
+ if (options.secure === true) {
127
+ parts.push('Secure');
128
+ }
129
+ if (options.httpOnly === true) {
130
+ parts.push('HttpOnly');
131
+ }
132
+ if (sameSite !== undefined) {
133
+ parts.push(`SameSite=${sameSite}`);
134
+ }
135
+ return parts.join('; ');
136
+ }
137
+
138
+ /**
139
+ * Serialize one runtime-neutral response cookie as an independent `Set-Cookie` field.
140
+ *
141
+ * @param response Mutable response that receives the cookie header.
142
+ * @param name Cookie name, validated as an HTTP token.
143
+ * @param value Cookie value, percent-encoded before serialization.
144
+ * @param options Explicit cookie attributes shared by all supported adapters.
145
+ * @returns Nothing. The response receives one independent cookie field.
146
+ */
147
+ export function setCookie(response, name, value, options = {}) {
148
+ response.setHeader('Set-Cookie', serializeCookie(name, value, readCookieOptions(options)));
149
+ }
150
+
151
+ /**
152
+ * Expire one runtime-neutral response cookie while retaining its matching scope attributes.
153
+ *
154
+ * @param response Mutable response that receives the deletion cookie header.
155
+ * @param name Cookie name, validated as an HTTP token.
156
+ * @param options Original Path and Domain attributes required to target the same cookie.
157
+ * @returns Nothing. The response receives one independent deletion cookie field.
158
+ */
159
+ export function clearCookie(response, name, options = {}) {
160
+ const values = readCookieOptions(options);
161
+ response.setHeader('Set-Cookie', serializeCookie(name, '', {
162
+ ...values,
163
+ expires: COOKIE_DELETION_EXPIRES,
164
+ maxAgeSeconds: 0
165
+ }));
166
+ }
@@ -1,4 +1,4 @@
1
- import { type Constructor, type MetadataPropertyKey } from '@fluojs/core';
1
+ import type { Constructor, MetadataPropertyKey } from '@fluojs/core';
2
2
  import type { ConverterLike, GuardLike, InterceptorLike } from './types.js';
3
3
  type StandardClassDecoratorFn = (value: Function, context: ClassDecoratorContext) => void;
4
4
  type StandardMethodDecoratorFn = (value: Function, context: ClassMethodDecoratorContext) => void;
@@ -24,69 +24,90 @@ export declare function Version(version: string): ClassOrMethodDecoratorLike;
24
24
  /**
25
25
  * Registers a `GET` route handler.
26
26
  *
27
- * @param path Route path relative to the controller base path.
27
+ * @param path Relative route path; omission or `undefined` uses `''`, preserving the controller prefix.
28
28
  * @returns A method decorator that registers a `GET` handler mapping.
29
29
  */
30
- export declare const Get: (path: string) => MethodDecoratorLike;
30
+ export declare const Get: (path?: string) => MethodDecoratorLike;
31
31
  /**
32
32
  * Registers a server-sent events route handler as `GET` with `text/event-stream` produces metadata.
33
33
  *
34
- * @param path Route path relative to the controller base path.
34
+ * @param path Relative route path; omission or `undefined` uses `''`, preserving the controller prefix.
35
35
  * @returns A method decorator that registers a `GET` SSE handler mapping.
36
36
  *
37
37
  * @remarks
38
38
  * Handlers may return `SseResponse` for manual control or `AsyncIterable<SseMessage<T> | T>` for managed dispatcher streaming.
39
39
  */
40
- export declare const Sse: (path: string) => MethodDecoratorLike;
40
+ export declare const Sse: (path?: string) => MethodDecoratorLike;
41
+ /**
42
+ * Registers a route handler for one validated HTTP method token.
43
+ *
44
+ * @param method HTTP method token, canonicalized to uppercase before metadata registration.
45
+ * @param path Relative route path; omission or `undefined` uses `''`, preserving the controller prefix.
46
+ * @returns A method decorator that registers the method-specific handler mapping.
47
+ *
48
+ * @throws {InvalidHttpMethodError} When `method` is empty, contains non-token characters, or is the reserved `ALL` sentinel.
49
+ *
50
+ * @remarks
51
+ * Adapter wire support remains runtime-specific. `CONNECT` is outside ordinary routing conformance,
52
+ * and custom methods are not implied to be OpenAPI Path Item operations.
53
+ */
54
+ export declare function Route(method: string, path?: string): MethodDecoratorLike;
55
+ /**
56
+ * Registers an RFC `QUERY` route handler.
57
+ *
58
+ * @param path Relative route path; omission or `undefined` uses `''`, preserving the controller prefix.
59
+ * @returns A method decorator that registers a `QUERY` handler mapping.
60
+ */
61
+ export declare const Query: (path?: string) => MethodDecoratorLike;
41
62
  /**
42
63
  * Registers a `POST` route handler.
43
64
  *
44
- * @param path Route path relative to the controller base path.
65
+ * @param path Relative route path; omission or `undefined` uses `''`, preserving the controller prefix.
45
66
  * @returns A method decorator that registers a `POST` handler mapping.
46
67
  */
47
- export declare const Post: (path: string) => MethodDecoratorLike;
68
+ export declare const Post: (path?: string) => MethodDecoratorLike;
48
69
  /**
49
70
  * Registers a `PUT` route handler.
50
71
  *
51
- * @param path Route path relative to the controller base path.
72
+ * @param path Relative route path; omission or `undefined` uses `''`, preserving the controller prefix.
52
73
  * @returns A method decorator that registers a `PUT` handler mapping.
53
74
  */
54
- export declare const Put: (path: string) => MethodDecoratorLike;
75
+ export declare const Put: (path?: string) => MethodDecoratorLike;
55
76
  /**
56
77
  * Registers a `PATCH` route handler.
57
78
  *
58
- * @param path Route path relative to the controller base path.
79
+ * @param path Relative route path; omission or `undefined` uses `''`, preserving the controller prefix.
59
80
  * @returns A method decorator that registers a `PATCH` handler mapping.
60
81
  */
61
- export declare const Patch: (path: string) => MethodDecoratorLike;
82
+ export declare const Patch: (path?: string) => MethodDecoratorLike;
62
83
  /**
63
84
  * Registers a `DELETE` route handler.
64
85
  *
65
- * @param path Route path relative to the controller base path.
86
+ * @param path Relative route path; omission or `undefined` uses `''`, preserving the controller prefix.
66
87
  * @returns A method decorator that registers a `DELETE` handler mapping.
67
88
  */
68
- export declare const Delete: (path: string) => MethodDecoratorLike;
89
+ export declare const Delete: (path?: string) => MethodDecoratorLike;
69
90
  /**
70
91
  * Registers an `OPTIONS` route handler.
71
92
  *
72
- * @param path Route path relative to the controller base path.
93
+ * @param path Relative route path; omission or `undefined` uses `''`, preserving the controller prefix.
73
94
  * @returns A method decorator that registers an `OPTIONS` handler mapping.
74
95
  */
75
- export declare const Options: (path: string) => MethodDecoratorLike;
96
+ export declare const Options: (path?: string) => MethodDecoratorLike;
76
97
  /**
77
98
  * Registers a `HEAD` route handler.
78
99
  *
79
- * @param path Route path relative to the controller base path.
100
+ * @param path Relative route path; omission or `undefined` uses `''`, preserving the controller prefix.
80
101
  * @returns A method decorator that registers a `HEAD` handler mapping.
81
102
  */
82
- export declare const Head: (path: string) => MethodDecoratorLike;
103
+ export declare const Head: (path?: string) => MethodDecoratorLike;
83
104
  /**
84
105
  * Registers a route handler that matches all HTTP methods.
85
106
  *
86
- * @param path Route path relative to the controller base path.
107
+ * @param path Relative route path; omission or `undefined` uses `''`, preserving the controller prefix.
87
108
  * @returns A method decorator that registers an all-method handler mapping.
88
109
  */
89
- export declare const All: (path: string) => MethodDecoratorLike;
110
+ export declare const All: (path?: string) => MethodDecoratorLike;
90
111
  /**
91
112
  * Associates a DTO class used for request binding and validation.
92
113
  *
@@ -151,6 +172,18 @@ export declare const FromCookie: (key?: string) => FieldDecoratorLike;
151
172
  * @returns A field decorator that marks the binding source as `body`.
152
173
  */
153
174
  export declare const FromBody: (key?: string) => FieldDecoratorLike;
175
+ /**
176
+ * Binds a DTO field from portable multipart files.
177
+ *
178
+ * The binding always yields a readonly array when the request exposes a file
179
+ * collection, preserving adapter order and filtering by the optional field name.
180
+ * An absent file collection remains absent so `@Optional()` can opt out of the
181
+ * normal required-field error.
182
+ *
183
+ * @param key Optional multipart field-name filter. Defaults to the DTO field name.
184
+ * @returns A field decorator that marks the binding source as `files`.
185
+ */
186
+ export declare const FromFiles: (key?: string) => FieldDecoratorLike;
154
187
  /**
155
188
  * Marks a DTO field binding as optional.
156
189
  *
@@ -1 +1 @@
1
- {"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../src/decorators.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,mBAAmB,EAEzB,MAAM,cAAc,CAAC;AAgBtB,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAc,eAAe,EAAE,MAAM,YAAY,CAAC;AAGxF,KAAK,wBAAwB,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,qBAAqB,KAAK,IAAI,CAAC;AAC1F,KAAK,yBAAyB,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,2BAA2B,KAAK,IAAI,CAAC;AACjG,KAAK,wBAAwB,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,0BAA0B,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,IAAI,CAAC;AAI1H,KAAK,kBAAkB,GAAG,wBAAwB,CAAC;AACnD,KAAK,mBAAmB,GAAG,yBAAyB,CAAC;AACrD,KAAK,0BAA0B,GAAG,wBAAwB,GAAG,yBAAyB,CAAC;AACvF,KAAK,kBAAkB,GAAG,wBAAwB,CAAC;AA4UnD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,QAAQ,SAAK,GAAG,kBAAkB,CAa5D;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,0BAA0B,CAuBnE;AAED;;;;;GAKG;AACH,eAAO,MAAM,GAAG,SA/HA,MAAM,KAAG,mBA+HqB,CAAC;AAC/C;;;;;;;;GAQG;AACH,eAAO,MAAM,GAAG,SAzIA,MAAM,KAAG,mBAyI4C,CAAC;AACtE;;;;;GAKG;AACH,eAAO,MAAM,IAAI,SAhJD,MAAM,KAAG,mBAgJuB,CAAC;AACjD;;;;;GAKG;AACH,eAAO,MAAM,GAAG,SAvJA,MAAM,KAAG,mBAuJqB,CAAC;AAC/C;;;;;GAKG;AACH,eAAO,MAAM,KAAK,SA9JF,MAAM,KAAG,mBA8JyB,CAAC;AACnD;;;;;GAKG;AACH,eAAO,MAAM,MAAM,SArKH,MAAM,KAAG,mBAqK2B,CAAC;AACrD;;;;;GAKG;AACH,eAAO,MAAM,OAAO,SA5KJ,MAAM,KAAG,mBA4K6B,CAAC;AACvD;;;;;GAKG;AACH,eAAO,MAAM,IAAI,SAnLD,MAAM,KAAG,mBAmLuB,CAAC;AACjD;;;;;GAKG;AACH,eAAO,MAAM,GAAG,SA1LA,MAAM,KAAG,mBA0LqB,CAAC;AAE/C;;;;;GAKG;AACH,eAAO,MAAM,UAAU,0BAtKF,mBAwKnB,CAAC;AAEH;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,GAAG,UAAU,EAAE,MAAM,EAAE,GAAG,mBAAmB,CAIrE;AAED;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,qBA5LA,mBA8LnB,CAAC;AAEH;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,eAAe,EAAE,WAAW,EAAE,WAAW,EAAE,mBAAmB,GAAG,MAAM,EAAE,GAAG,SAAS,CAM7H;AAED;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,SAlML,MAAM,KAAG,kBAkM8B,CAAC;AACxD;;;;;GAKG;AACH,eAAO,MAAM,SAAS,SAzMN,MAAM,KAAG,kBAyMgC,CAAC;AAC1D;;;;;GAKG;AACH,eAAO,MAAM,UAAU,SAhNP,MAAM,KAAG,kBAgNkC,CAAC;AAC5D;;;;;GAKG;AACH,eAAO,MAAM,UAAU,SAvNP,MAAM,KAAG,kBAuNkC,CAAC;AAC5D;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,SA9NL,MAAM,KAAG,kBA8N8B,CAAC;AAExD;;;;GAIG;AACH,wBAAgB,QAAQ,IAAI,kBAAkB,CAa7C;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,SAAS,EAAE,aAAa,GAAG,kBAAkB,CAapE;AAED;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,mBAAmB,CAcvE;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,mBAAmB,CAa9E;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,GAAG,MAAM,EAAE,SAAS,EAAE,GAAG,0BAA0B,CAyB5E;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,YAAY,EAAE,eAAe,EAAE,GAAG,0BAA0B,CAyB9F"}
1
+ {"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../src/decorators.ts"],"names":[],"mappings":"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"}