hono 4.4.9 → 4.4.11

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.
@@ -152,11 +152,15 @@ const hc = (baseUrl, options) => createProxy(function proxyCallback(opts) {
152
152
  return new URL(url);
153
153
  }
154
154
  if (method === "ws") {
155
- const targetUrl = (0, import_utils.replaceUrlProtocol)(
155
+ const webSocketUrl = (0, import_utils.replaceUrlProtocol)(
156
156
  opts.args[0] && opts.args[0].param ? (0, import_utils.replaceUrlParam)(url, opts.args[0].param) : url,
157
157
  "ws"
158
158
  );
159
- return new WebSocket(targetUrl);
159
+ const targetUrl = new URL(webSocketUrl);
160
+ for (const key in opts.args[0]?.query) {
161
+ targetUrl.searchParams.set(key, opts.args[0].query[key]);
162
+ }
163
+ return new WebSocket(targetUrl.toString());
160
164
  }
161
165
  const req = new ClientRequestImpl(url, method);
162
166
  if (method) {
@@ -57,9 +57,16 @@ const run = async (stream, cb, onError) => {
57
57
  stream.close();
58
58
  }
59
59
  };
60
+ const contextStash = /* @__PURE__ */ new WeakMap();
60
61
  const streamSSE = (c, cb, onError) => {
61
62
  const { readable, writable } = new TransformStream();
62
63
  const stream = new SSEStreamingApi(writable, readable);
64
+ c.req.raw.signal.addEventListener("abort", () => {
65
+ if (!stream.closed) {
66
+ stream.abort();
67
+ }
68
+ });
69
+ contextStash.set(stream.responseReadable, c);
63
70
  c.header("Transfer-Encoding", "chunked");
64
71
  c.header("Content-Type", "text/event-stream");
65
72
  c.header("Cache-Control", "no-cache");
@@ -22,9 +22,16 @@ __export(stream_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(stream_exports);
24
24
  var import_stream = require("../../utils/stream");
25
+ const contextStash = /* @__PURE__ */ new WeakMap();
25
26
  const stream = (c, cb, onError) => {
26
27
  const { readable, writable } = new TransformStream();
27
28
  const stream2 = new import_stream.StreamingApi(writable, readable);
29
+ c.req.raw.signal.addEventListener("abort", () => {
30
+ if (!stream2.closed) {
31
+ stream2.abort();
32
+ }
33
+ });
34
+ contextStash.set(stream2.responseReadable, c);
28
35
  (async () => {
29
36
  try {
30
37
  await cb(stream2);
@@ -27,6 +27,8 @@ class StreamingApi {
27
27
  writable;
28
28
  abortSubscribers = [];
29
29
  responseReadable;
30
+ aborted = false;
31
+ closed = false;
30
32
  constructor(writable, _readable) {
31
33
  this.writable = writable;
32
34
  this.writer = writable.getWriter();
@@ -41,7 +43,7 @@ class StreamingApi {
41
43
  done ? controller.close() : controller.enqueue(value);
42
44
  },
43
45
  cancel: () => {
44
- this.abortSubscribers.forEach((subscriber) => subscriber());
46
+ this.abort();
45
47
  }
46
48
  });
47
49
  }
@@ -67,6 +69,7 @@ class StreamingApi {
67
69
  await this.writer.close();
68
70
  } catch (e) {
69
71
  }
72
+ this.closed = true;
70
73
  }
71
74
  async pipe(body) {
72
75
  this.writer.releaseLock();
@@ -76,6 +79,12 @@ class StreamingApi {
76
79
  onAbort(listener) {
77
80
  this.abortSubscribers.push(listener);
78
81
  }
82
+ abort() {
83
+ if (!this.aborted) {
84
+ this.aborted = true;
85
+ this.abortSubscribers.forEach((subscriber) => subscriber());
86
+ }
87
+ }
79
88
  }
80
89
  // Annotate the CommonJS export names for ESM import in node:
81
90
  0 && (module.exports = {
@@ -45,33 +45,34 @@ const validator = (target, validationFunc) => {
45
45
  if (!contentType) {
46
46
  break;
47
47
  }
48
+ let formData;
48
49
  if (c.req.bodyCache.formData) {
49
- value = await c.req.bodyCache.formData;
50
- break;
50
+ formData = await c.req.bodyCache.formData;
51
+ } else {
52
+ try {
53
+ const arrayBuffer = await c.req.arrayBuffer();
54
+ formData = await (0, import_buffer.bufferToFormData)(arrayBuffer, contentType);
55
+ c.req.bodyCache.formData = formData;
56
+ } catch (e) {
57
+ let message = "Malformed FormData request.";
58
+ message += e instanceof Error ? ` ${e.message}` : ` ${String(e)}`;
59
+ throw new import_http_exception.HTTPException(400, { message });
60
+ }
51
61
  }
52
- try {
53
- const arrayBuffer = await c.req.arrayBuffer();
54
- const formData = await (0, import_buffer.bufferToFormData)(arrayBuffer, contentType);
55
- const form = {};
56
- formData.forEach((value2, key) => {
57
- if (key.endsWith("[]")) {
58
- if (form[key] === void 0) {
59
- form[key] = [value2];
60
- } else if (Array.isArray(form[key])) {
61
- ;
62
- form[key].push(value2);
63
- }
64
- } else {
65
- form[key] = value2;
62
+ const form = {};
63
+ formData.forEach((value2, key) => {
64
+ if (key.endsWith("[]")) {
65
+ if (form[key] === void 0) {
66
+ form[key] = [value2];
67
+ } else if (Array.isArray(form[key])) {
68
+ ;
69
+ form[key].push(value2);
66
70
  }
67
- });
68
- value = form;
69
- c.req.bodyCache.formData = formData;
70
- } catch (e) {
71
- let message = "Malformed FormData request.";
72
- message += e instanceof Error ? ` ${e.message}` : ` ${String(e)}`;
73
- throw new import_http_exception.HTTPException(400, { message });
74
- }
71
+ } else {
72
+ form[key] = value2;
73
+ }
74
+ });
75
+ value = form;
75
76
  break;
76
77
  }
77
78
  case "query":
@@ -136,11 +136,15 @@ var hc = (baseUrl, options) => createProxy(function proxyCallback(opts) {
136
136
  return new URL(url);
137
137
  }
138
138
  if (method === "ws") {
139
- const targetUrl = replaceUrlProtocol(
139
+ const webSocketUrl = replaceUrlProtocol(
140
140
  opts.args[0] && opts.args[0].param ? replaceUrlParam(url, opts.args[0].param) : url,
141
141
  "ws"
142
142
  );
143
- return new WebSocket(targetUrl);
143
+ const targetUrl = new URL(webSocketUrl);
144
+ for (const key in opts.args[0]?.query) {
145
+ targetUrl.searchParams.set(key, opts.args[0].query[key]);
146
+ }
147
+ return new WebSocket(targetUrl.toString());
144
148
  }
145
149
  const req = new ClientRequestImpl(url, method);
146
150
  if (method) {
@@ -34,9 +34,16 @@ var run = async (stream, cb, onError) => {
34
34
  stream.close();
35
35
  }
36
36
  };
37
+ var contextStash = /* @__PURE__ */ new WeakMap();
37
38
  var streamSSE = (c, cb, onError) => {
38
39
  const { readable, writable } = new TransformStream();
39
40
  const stream = new SSEStreamingApi(writable, readable);
41
+ c.req.raw.signal.addEventListener("abort", () => {
42
+ if (!stream.closed) {
43
+ stream.abort();
44
+ }
45
+ });
46
+ contextStash.set(stream.responseReadable, c);
40
47
  c.header("Transfer-Encoding", "chunked");
41
48
  c.header("Content-Type", "text/event-stream");
42
49
  c.header("Cache-Control", "no-cache");
@@ -1,8 +1,15 @@
1
1
  // src/helper/streaming/stream.ts
2
2
  import { StreamingApi } from "../../utils/stream.js";
3
+ var contextStash = /* @__PURE__ */ new WeakMap();
3
4
  var stream = (c, cb, onError) => {
4
5
  const { readable, writable } = new TransformStream();
5
6
  const stream2 = new StreamingApi(writable, readable);
7
+ c.req.raw.signal.addEventListener("abort", () => {
8
+ if (!stream2.closed) {
9
+ stream2.abort();
10
+ }
11
+ });
12
+ contextStash.set(stream2.responseReadable, c);
6
13
  (async () => {
7
14
  try {
8
15
  await cb(stream2);
@@ -79,7 +79,7 @@ type InferResponseTypeFromEndpoint<T extends Endpoint, U extends StatusCode> = T
79
79
  } ? S extends U ? O : never : never;
80
80
  export type InferRequestType<T> = T extends (args: infer R, options: any | undefined) => Promise<ClientResponse<unknown>> ? NonNullable<R> : never;
81
81
  export type InferRequestOptionsType<T> = T extends (args: any, options: infer R) => Promise<ClientResponse<unknown>> ? NonNullable<R> : never;
82
- type PathToChain<Path extends string, E extends Schema, Original extends string = ''> = Path extends `/${infer P}` ? PathToChain<P, E, Path> : Path extends `${infer P}/${infer R}` ? {
82
+ type PathToChain<Path extends string, E extends Schema, Original extends string = Path> = Path extends `/${infer P}` ? PathToChain<P, E, Path> : Path extends `${infer P}/${infer R}` ? {
83
83
  [K in P]: PathToChain<R, E, Original>;
84
84
  } : {
85
85
  [K in Path extends '' ? 'index' : Path]: ClientRequest<E extends Record<string, unknown> ? E[Original] : never>;
@@ -38,26 +38,19 @@ export interface HTTPResponseError extends Error {
38
38
  export type ErrorHandler<E extends Env = any> = (err: Error | HTTPResponseError, c: Context<E>) => Response | Promise<Response>;
39
39
  export interface HandlerInterface<E extends Env = Env, M extends string = string, S extends Schema = BlankSchema, BasePath extends string = '/'> {
40
40
  <P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, I extends Input = BlankInput, R extends HandlerResponse<any> = any, E2 extends Env = E>(handler: H<E2, P, I, R>): Hono<IntersectNonAnyTypes<[E, E2]>, S & ToSchema<M, P, I, MergeTypedResponse<R>>, BasePath>;
41
- <P extends string, MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, E2 extends Env = E>(path: P, handler: H<E2, MergedPath, I, R>): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I, MergeTypedResponse<R>>, BasePath>;
42
41
  <P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, I extends Input = BlankInput, I2 extends Input = I, R extends HandlerResponse<any> = any, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>>(...handlers: [H<E2, P, I>, H<E3, P, I2, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3]>, S & ToSchema<M, P, I2, MergeTypedResponse<R>>, BasePath>;
43
- <P extends string, MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>>(path: P, ...handlers: [H<E2, MergedPath, I>, H<E3, MergedPath, I2, R>]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I2, MergeTypedResponse<R>>, BasePath>;
42
+ <P extends string, MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, E2 extends Env = E>(path: P, handler: H<E2, MergedPath, I, R>): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I, MergeTypedResponse<R>>, BasePath>;
44
43
  <P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, E2 extends Env = E, E3 extends Env = E, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>>(...handlers: [H<E2, P, I>, H<E3, P, I2>, H<E4, P, I3, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4]>, S & ToSchema<M, P, I3, MergeTypedResponse<R>>, BasePath>;
45
- <P extends string, MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, E2 extends Env = E, E3 extends Env = E, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>>(path: P, ...handlers: [H<E2, MergedPath, I>, H<E3, MergedPath, I2>, H<E4, MergedPath, I3, R>]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I3, MergeTypedResponse<R>>, BasePath>;
44
+ <P extends string, MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>>(path: P, ...handlers: [H<E2, MergedPath, I>, H<E3, MergedPath, I2, R>]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I2, MergeTypedResponse<R>>, BasePath>;
46
45
  <P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>>(...handlers: [H<E2, P, I>, H<E3, P, I2>, H<E4, P, I3>, H<E5, P, I4, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, S & ToSchema<M, P, I4, MergeTypedResponse<R>>, BasePath>;
46
+ <P extends string, MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, E2 extends Env = E, E3 extends Env = E, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>>(path: P, ...handlers: [H<E2, MergedPath, I>, H<E3, MergedPath, I2>, H<E4, MergedPath, I3, R>]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I3, MergeTypedResponse<R>>, BasePath>;
47
+ <P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>>(...handlers: [H<E2, P, I>, H<E3, P, I2>, H<E4, P, I3>, H<E5, P, I4>, H<E6, P, I5, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, S & ToSchema<M, P, I5, MergeTypedResponse<R>>, BasePath>;
47
48
  <P extends string, MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>>(path: P, ...handlers: [
48
49
  H<E2, MergedPath, I>,
49
50
  H<E3, MergedPath, I2>,
50
51
  H<E4, MergedPath, I3>,
51
52
  H<E5, MergedPath, I4, R>
52
53
  ]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I4, MergeTypedResponse<R>>, BasePath>;
53
- <P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>>(...handlers: [H<E2, P, I>, H<E3, P, I2>, H<E4, P, I3>, H<E5, P, I4>, H<E6, P, I5, R>]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, S & ToSchema<M, P, I5, MergeTypedResponse<R>>, BasePath>;
54
- <P extends string, MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>>(path: P, ...handlers: [
55
- H<E2, MergedPath, I>,
56
- H<E3, MergedPath, I2>,
57
- H<E4, MergedPath, I3>,
58
- H<E5, MergedPath, I4>,
59
- H<E6, MergedPath, I5, R>
60
- ]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I5, MergeTypedResponse<R>>, BasePath>;
61
54
  <P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>>(...handlers: [
62
55
  H<E2, P, I>,
63
56
  H<E3, P, I2>,
@@ -66,14 +59,13 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
66
59
  H<E6, P, I5>,
67
60
  H<E7, P, I6, R>
68
61
  ]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, S & ToSchema<M, P, I6, MergeTypedResponse<R>>, BasePath>;
69
- <P extends string, MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>>(path: P, ...handlers: [
62
+ <P extends string, MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>>(path: P, ...handlers: [
70
63
  H<E2, MergedPath, I>,
71
64
  H<E3, MergedPath, I2>,
72
65
  H<E4, MergedPath, I3>,
73
66
  H<E5, MergedPath, I4>,
74
- H<E6, MergedPath, I5>,
75
- H<E7, MergedPath, I6, R>
76
- ]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I6, MergeTypedResponse<R>>, BasePath>;
67
+ H<E6, MergedPath, I5, R>
68
+ ]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I5, MergeTypedResponse<R>>, BasePath>;
77
69
  <P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = E, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>>(...handlers: [
78
70
  H<E2, P, I>,
79
71
  H<E3, P, I2>,
@@ -83,15 +75,14 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
83
75
  H<E7, P, I6>,
84
76
  H<E8, P, I7, R>
85
77
  ]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, S & ToSchema<M, P, I7, MergeTypedResponse<R>>, BasePath>;
86
- <P extends string, MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = E, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>>(path: P, ...handlers: [
78
+ <P extends string, MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>>(path: P, ...handlers: [
87
79
  H<E2, MergedPath, I>,
88
80
  H<E3, MergedPath, I2>,
89
81
  H<E4, MergedPath, I3>,
90
82
  H<E5, MergedPath, I4>,
91
83
  H<E6, MergedPath, I5>,
92
- H<E7, MergedPath, I6>,
93
- H<E8, MergedPath, I7, R>
94
- ]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I7, MergeTypedResponse<R>>, BasePath>;
84
+ H<E7, MergedPath, I6, R>
85
+ ]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I6, MergeTypedResponse<R>>, BasePath>;
95
86
  <P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = E, E8 extends Env = E, E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>>(...handlers: [
96
87
  H<E2, P, I>,
97
88
  H<E3, P, I2>,
@@ -102,16 +93,15 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
102
93
  H<E8, P, I7>,
103
94
  H<E9, P, I8, R>
104
95
  ]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>, S & ToSchema<M, P, I8, MergeTypedResponse<R>>, BasePath>;
105
- <P extends string, MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = E, E8 extends Env = E, E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>>(path: P, ...handlers: [
96
+ <P extends string, MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = E, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>>(path: P, ...handlers: [
106
97
  H<E2, MergedPath, I>,
107
98
  H<E3, MergedPath, I2>,
108
99
  H<E4, MergedPath, I3>,
109
100
  H<E5, MergedPath, I4>,
110
101
  H<E6, MergedPath, I5>,
111
102
  H<E7, MergedPath, I6>,
112
- H<E8, MergedPath, I7>,
113
- H<E9, MergedPath, I8, R>
114
- ]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I8, MergeTypedResponse<R>>, BasePath>;
103
+ H<E8, MergedPath, I7, R>
104
+ ]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I7, MergeTypedResponse<R>>, BasePath>;
115
105
  <P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = E, E8 extends Env = E, E9 extends Env = E, E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>>(...handlers: [
116
106
  H<E2, P, I>,
117
107
  H<E3, P, I2>,
@@ -123,7 +113,7 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
123
113
  H<E9, P, I8>,
124
114
  H<E10, P, I9, R>
125
115
  ]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>, S & ToSchema<M, P, I9, MergeTypedResponse<R>>, BasePath>;
126
- <P extends string, MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = E, E8 extends Env = E, E9 extends Env = E, E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>>(path: P, ...handlers: [
116
+ <P extends string, MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = E, E8 extends Env = E, E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>>(path: P, ...handlers: [
127
117
  H<E2, MergedPath, I>,
128
118
  H<E3, MergedPath, I2>,
129
119
  H<E4, MergedPath, I3>,
@@ -131,9 +121,8 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
131
121
  H<E6, MergedPath, I5>,
132
122
  H<E7, MergedPath, I6>,
133
123
  H<E8, MergedPath, I7>,
134
- H<E9, MergedPath, I8>,
135
- H<E10, MergedPath, I9, R>
136
- ]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I9, MergeTypedResponse<R>>, BasePath>;
124
+ H<E9, MergedPath, I8, R>
125
+ ]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I8, MergeTypedResponse<R>>, BasePath>;
137
126
  <P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, I10 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8 & I9, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = E, E8 extends Env = E, E9 extends Env = E, E10 extends Env = E, E11 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>>(...handlers: [
138
127
  H<E2, P, I>,
139
128
  H<E3, P, I2>,
@@ -146,6 +135,17 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
146
135
  H<E10, P, I9>,
147
136
  H<E11, P, I10, R>
148
137
  ]): Hono<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11]>, S & ToSchema<M, P, I10, MergeTypedResponse<R>>, BasePath>;
138
+ <P extends string, MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = E, E8 extends Env = E, E9 extends Env = E, E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>>(path: P, ...handlers: [
139
+ H<E2, MergedPath, I>,
140
+ H<E3, MergedPath, I2>,
141
+ H<E4, MergedPath, I3>,
142
+ H<E5, MergedPath, I4>,
143
+ H<E6, MergedPath, I5>,
144
+ H<E7, MergedPath, I6>,
145
+ H<E8, MergedPath, I7>,
146
+ H<E9, MergedPath, I8>,
147
+ H<E10, MergedPath, I9, R>
148
+ ]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I9, MergeTypedResponse<R>>, BasePath>;
149
149
  <P extends string, MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, I10 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8 & I9, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = E, E8 extends Env = E, E9 extends Env = E, E10 extends Env = E, E11 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>>(path: P, ...handlers: [
150
150
  H<E2, MergedPath, I>,
151
151
  H<E3, MergedPath, I2>,
@@ -8,6 +8,14 @@ export declare class StreamingApi {
8
8
  private writable;
9
9
  private abortSubscribers;
10
10
  responseReadable: ReadableStream;
11
+ /**
12
+ * Whether the stream has been aborted.
13
+ */
14
+ aborted: boolean;
15
+ /**
16
+ * Whether the stream has been closed normally.
17
+ */
18
+ closed: boolean;
11
19
  constructor(writable: WritableStream, _readable: ReadableStream);
12
20
  write(input: Uint8Array | string): Promise<StreamingApi>;
13
21
  writeln(input: string): Promise<StreamingApi>;
@@ -15,4 +23,9 @@ export declare class StreamingApi {
15
23
  close(): Promise<void>;
16
24
  pipe(body: ReadableStream): Promise<void>;
17
25
  onAbort(listener: () => void | Promise<void>): void;
26
+ /**
27
+ * Abort the stream.
28
+ * You can call this method when stream is aborted by external event.
29
+ */
30
+ abort(): void;
18
31
  }
@@ -5,6 +5,8 @@ var StreamingApi = class {
5
5
  writable;
6
6
  abortSubscribers = [];
7
7
  responseReadable;
8
+ aborted = false;
9
+ closed = false;
8
10
  constructor(writable, _readable) {
9
11
  this.writable = writable;
10
12
  this.writer = writable.getWriter();
@@ -19,7 +21,7 @@ var StreamingApi = class {
19
21
  done ? controller.close() : controller.enqueue(value);
20
22
  },
21
23
  cancel: () => {
22
- this.abortSubscribers.forEach((subscriber) => subscriber());
24
+ this.abort();
23
25
  }
24
26
  });
25
27
  }
@@ -45,6 +47,7 @@ var StreamingApi = class {
45
47
  await this.writer.close();
46
48
  } catch (e) {
47
49
  }
50
+ this.closed = true;
48
51
  }
49
52
  async pipe(body) {
50
53
  this.writer.releaseLock();
@@ -54,6 +57,12 @@ var StreamingApi = class {
54
57
  onAbort(listener) {
55
58
  this.abortSubscribers.push(listener);
56
59
  }
60
+ abort() {
61
+ if (!this.aborted) {
62
+ this.aborted = true;
63
+ this.abortSubscribers.forEach((subscriber) => subscriber());
64
+ }
65
+ }
57
66
  };
58
67
  export {
59
68
  StreamingApi
@@ -23,33 +23,34 @@ var validator = (target, validationFunc) => {
23
23
  if (!contentType) {
24
24
  break;
25
25
  }
26
+ let formData;
26
27
  if (c.req.bodyCache.formData) {
27
- value = await c.req.bodyCache.formData;
28
- break;
28
+ formData = await c.req.bodyCache.formData;
29
+ } else {
30
+ try {
31
+ const arrayBuffer = await c.req.arrayBuffer();
32
+ formData = await bufferToFormData(arrayBuffer, contentType);
33
+ c.req.bodyCache.formData = formData;
34
+ } catch (e) {
35
+ let message = "Malformed FormData request.";
36
+ message += e instanceof Error ? ` ${e.message}` : ` ${String(e)}`;
37
+ throw new HTTPException(400, { message });
38
+ }
29
39
  }
30
- try {
31
- const arrayBuffer = await c.req.arrayBuffer();
32
- const formData = await bufferToFormData(arrayBuffer, contentType);
33
- const form = {};
34
- formData.forEach((value2, key) => {
35
- if (key.endsWith("[]")) {
36
- if (form[key] === void 0) {
37
- form[key] = [value2];
38
- } else if (Array.isArray(form[key])) {
39
- ;
40
- form[key].push(value2);
41
- }
42
- } else {
43
- form[key] = value2;
40
+ const form = {};
41
+ formData.forEach((value2, key) => {
42
+ if (key.endsWith("[]")) {
43
+ if (form[key] === void 0) {
44
+ form[key] = [value2];
45
+ } else if (Array.isArray(form[key])) {
46
+ ;
47
+ form[key].push(value2);
44
48
  }
45
- });
46
- value = form;
47
- c.req.bodyCache.formData = formData;
48
- } catch (e) {
49
- let message = "Malformed FormData request.";
50
- message += e instanceof Error ? ` ${e.message}` : ` ${String(e)}`;
51
- throw new HTTPException(400, { message });
52
- }
49
+ } else {
50
+ form[key] = value2;
51
+ }
52
+ });
53
+ value = form;
53
54
  break;
54
55
  }
55
56
  case "query":
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hono",
3
- "version": "4.4.9",
3
+ "version": "4.4.11",
4
4
  "description": "Web framework built on Web Standards",
5
5
  "main": "dist/cjs/index.js",
6
6
  "type": "module",
@@ -12,7 +12,7 @@
12
12
  "scripts": {
13
13
  "test": "tsc --noEmit && vitest --run && vitest -c .vitest.config/jsx-runtime-default.ts --run && vitest -c .vitest.config/jsx-runtime-dom.ts --run",
14
14
  "test:watch": "vitest --watch",
15
- "test:deno": "deno test --allow-read --allow-env --allow-write -c runtime_tests/deno/deno.json runtime_tests/deno && deno test --no-lock -c runtime_tests/deno-jsx/deno.precompile.json runtime_tests/deno-jsx && deno test --no-lock -c runtime_tests/deno-jsx/deno.react-jsx.json runtime_tests/deno-jsx",
15
+ "test:deno": "deno test --allow-read --allow-env --allow-write --allow-net -c runtime_tests/deno/deno.json runtime_tests/deno && deno test --no-lock -c runtime_tests/deno-jsx/deno.precompile.json runtime_tests/deno-jsx && deno test --no-lock -c runtime_tests/deno-jsx/deno.react-jsx.json runtime_tests/deno-jsx",
16
16
  "test:bun": "bun test --jsx-import-source ../../src/jsx runtime_tests/bun/index.test.tsx",
17
17
  "test:fastly": "vitest --run --config ./runtime_tests/fastly/vitest.config.ts",
18
18
  "test:node": "vitest --run --config ./runtime_tests/node/vitest.config.ts",