hono 4.12.26 → 4.12.28

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/jsx/base.js CHANGED
@@ -2,7 +2,13 @@
2
2
  import { raw } from "../helper/html/index.js";
3
3
  import { escapeToBuffer, resolveCallbackSync, stringBufferToString } from "../utils/html.js";
4
4
  import { DOM_RENDERER, DOM_MEMO } from "./constants.js";
5
- import { createContext, globalContexts, useContext } from "./context.js";
5
+ import {
6
+ captureRenderContext,
7
+ createContext,
8
+ globalContexts,
9
+ runWithRenderContext,
10
+ useContext
11
+ } from "./context.js";
6
12
  import { domRenderers } from "./intrinsic-element/common.js";
7
13
  import * as intrinsicElementTags from "./intrinsic-element/components.js";
8
14
  import {
@@ -88,7 +94,7 @@ var JSXNode = class {
88
94
  key;
89
95
  children;
90
96
  isEscaped = true;
91
- localContexts;
97
+ suspendedContext;
92
98
  constructor(tag, props, children) {
93
99
  if (typeof tag !== "function" && !isValidTagName(tag)) {
94
100
  throw new Error(`Invalid JSX tag name: ${tag}`);
@@ -106,18 +112,12 @@ var JSXNode = class {
106
112
  return this.props.ref || null;
107
113
  }
108
114
  toString() {
109
- const buffer = [""];
110
- this.localContexts?.forEach(([context, value]) => {
111
- context.values.push(value);
112
- });
113
- try {
115
+ const render = () => {
116
+ const buffer = [""];
114
117
  this.toStringToBuffer(buffer);
115
- } finally {
116
- this.localContexts?.forEach(([context]) => {
117
- context.values.pop();
118
- });
119
- }
120
- return buffer.length === 1 ? "callbacks" in buffer ? resolveCallbackSync(raw(buffer[0], buffer.callbacks)).toString() : buffer[0] : stringBufferToString(buffer, buffer.callbacks);
118
+ return buffer.length === 1 ? "callbacks" in buffer ? resolveCallbackSync(raw(buffer[0], buffer.callbacks)).toString() : buffer[0] : stringBufferToString(buffer, buffer.callbacks);
119
+ };
120
+ return this.suspendedContext ? this.suspendedContext(render) : runWithRenderContext(render);
121
121
  }
122
122
  toStringToBuffer(buffer) {
123
123
  const tag = this.tag;
@@ -193,12 +193,12 @@ var JSXFunctionNode = class extends JSXNode {
193
193
  if (globalContexts.length === 0) {
194
194
  buffer.unshift("", res);
195
195
  } else {
196
- const currentContexts = globalContexts.map((c) => [c, c.values.at(-1)]);
196
+ const suspendedContext = captureRenderContext();
197
197
  buffer.unshift(
198
198
  "",
199
199
  res.then((childRes) => {
200
200
  if (childRes instanceof JSXNode) {
201
- childRes.localContexts = currentContexts;
201
+ childRes.suspendedContext = suspendedContext;
202
202
  }
203
203
  return childRes;
204
204
  })
@@ -3,7 +3,7 @@ import { raw } from "../helper/html/index.js";
3
3
  import { HtmlEscapedCallbackPhase, resolveCallback } from "../utils/html.js";
4
4
  import { jsx, Fragment } from "./base.js";
5
5
  import { DOM_RENDERER } from "./constants.js";
6
- import { useContext } from "./context.js";
6
+ import { captureRenderContext, useContext } from "./context.js";
7
7
  import { ErrorBoundary as ErrorBoundaryDomRenderer } from "./dom/components.js";
8
8
  import { StreamingContext } from "./streaming.js";
9
9
  var errorBoundaryCounter = 0;
@@ -12,8 +12,9 @@ var childrenToString = async (children) => {
12
12
  return children.flat().map((c) => c == null || typeof c === "boolean" ? "" : c.toString());
13
13
  } catch (e) {
14
14
  if (e instanceof Promise) {
15
+ const resume = captureRenderContext();
15
16
  await e;
16
- return childrenToString(children);
17
+ return resume(() => childrenToString(children));
17
18
  } else {
18
19
  throw e;
19
20
  }
@@ -41,51 +42,68 @@ var ErrorBoundary = async ({ children, fallback, fallbackRender, onError }) => {
41
42
  children = [children];
42
43
  }
43
44
  const nonce = useContext(StreamingContext)?.scriptNonce;
44
- let fallbackStr;
45
- const resolveFallbackStr = async () => {
45
+ let resume;
46
+ const getResume = () => resume ||= captureRenderContext();
47
+ let fallbackStrPromise;
48
+ const resolveFallbackStr = () => fallbackStrPromise ||= (async () => {
46
49
  const awaitedFallback = await fallback;
47
50
  if (typeof awaitedFallback === "string") {
48
- fallbackStr = awaitedFallback;
51
+ return awaitedFallback;
49
52
  } else {
50
- fallbackStr = await awaitedFallback?.toString();
51
- if (typeof fallbackStr === "string") {
52
- fallbackStr = raw(fallbackStr);
53
+ const fallbackResult = await getResume()(() => awaitedFallback?.toString());
54
+ if (typeof fallbackResult === "string") {
55
+ return raw(
56
+ fallbackResult,
57
+ fallbackResult.callbacks || awaitedFallback?.callbacks
58
+ );
53
59
  }
54
60
  }
55
- };
56
- const fallbackRes = (error) => {
57
- onError?.(error);
58
- return fallbackStr || fallbackRender && jsx(Fragment, {}, fallbackRender(error)) || "";
61
+ })();
62
+ const renderFallback = async (error) => {
63
+ const fallbackStr = await resolveFallbackStr();
64
+ return getResume()(async () => {
65
+ onError?.(error);
66
+ const fallbackRes = fallbackStr !== void 0 ? fallbackStr : fallbackRender && jsx(Fragment, {}, fallbackRender(error)) || "";
67
+ const fallbackResString = await Fragment({
68
+ children: fallbackRes
69
+ }).toString();
70
+ return raw(
71
+ fallbackResString,
72
+ fallbackResString.callbacks || fallbackRes.callbacks
73
+ );
74
+ });
59
75
  };
60
76
  let resArray = [];
61
77
  try {
62
78
  resArray = children.map(resolveChildEarly);
63
79
  } catch (e) {
64
- await resolveFallbackStr();
80
+ const resume2 = getResume();
65
81
  if (e instanceof Promise) {
66
82
  resArray = [
67
- e.then(() => childrenToString(children)).catch((e2) => fallbackRes(e2))
83
+ e.then(() => resume2(() => childrenToString(children))).catch((e2) => renderFallback(e2))
68
84
  ];
69
85
  } else {
70
- resArray = [fallbackRes(e)];
86
+ resArray = [await renderFallback(e)];
71
87
  }
72
88
  }
73
89
  if (resArray.some((res) => res instanceof Promise)) {
74
- await resolveFallbackStr();
90
+ getResume();
75
91
  const index = errorBoundaryCounter++;
76
92
  const replaceRe = RegExp(`(<template id="E:${index}"></template>.*?)(.*?)(<!--E:${index}-->)`);
77
- const caught = false;
93
+ let caught = false;
78
94
  const catchCallback = async ({ error: error2, buffer }) => {
79
95
  if (caught) {
80
96
  return "";
81
97
  }
82
- const fallbackResString = await Fragment({
83
- children: fallbackRes(error2)
84
- }).toString();
98
+ caught = true;
99
+ const fallbackResString = await renderFallback(error2);
100
+ const fallbackCallbacks = fallbackResString.callbacks;
85
101
  if (buffer) {
86
102
  buffer[0] = buffer[0].replace(replaceRe, fallbackResString);
103
+ return fallbackCallbacks?.length ? raw("", fallbackCallbacks) : "";
87
104
  }
88
- return buffer ? "" : `<template data-hono-target="E:${index}">${fallbackResString}</template><script>
105
+ return raw(
106
+ `<template data-hono-target="E:${index}">${fallbackResString}</template><script>
89
107
  ((d,c,n) => {
90
108
  c=d.currentScript.previousSibling
91
109
  d=d.getElementById('E:${index}')
@@ -93,7 +111,9 @@ if(!d)return
93
111
  do{n=d.nextSibling;n.remove()}while(n.nodeType!=8||n.nodeValue!='E:${index}')
94
112
  d.replaceWith(c.content)
95
113
  })(document)
96
- </script>`;
114
+ </script>`,
115
+ fallbackCallbacks
116
+ );
97
117
  };
98
118
  let error;
99
119
  const promiseAll = Promise.all(resArray).catch((e) => error = e);
@@ -4,21 +4,143 @@ import { JSXFragmentNode } from "./base.js";
4
4
  import { DOM_RENDERER } from "./constants.js";
5
5
  import { createContextProviderFunction } from "./dom/context.js";
6
6
  var globalContexts = [];
7
+ var alsProbed = false;
8
+ var asyncLocalStorage;
9
+ var fallbackStore;
10
+ var fallbackRendersInFlight = 0;
11
+ var warnedFallbackDefault = false;
12
+ var loadAsyncLocalStorage = () => {
13
+ if (alsProbed) {
14
+ return asyncLocalStorage;
15
+ }
16
+ alsProbed = true;
17
+ const global = globalThis;
18
+ let AsyncLocalStorage;
19
+ for (const probe of [
20
+ // Node.js >= 20.16, Deno, Bun, Cloudflare Workers (nodejs_compat). Property
21
+ // access only, so bundlers don't statically resolve `node:async_hooks`.
22
+ () => global.process?.getBuiltinModule?.("node:async_hooks")?.AsyncLocalStorage,
23
+ // Node.js < 20.16 has no `process.getBuiltinModule`, but a CJS entrypoint
24
+ // exposes the main module's `require` here.
25
+ () => global.process?.mainModule?.require?.("node:async_hooks")?.AsyncLocalStorage
26
+ ]) {
27
+ try {
28
+ AsyncLocalStorage = probe();
29
+ } catch {
30
+ }
31
+ if (AsyncLocalStorage) {
32
+ break;
33
+ }
34
+ }
35
+ if (AsyncLocalStorage) {
36
+ asyncLocalStorage = new AsyncLocalStorage();
37
+ }
38
+ return asyncLocalStorage;
39
+ };
40
+ var getCurrentStore = () => {
41
+ return loadAsyncLocalStorage()?.getStore() || fallbackStore;
42
+ };
43
+ var warnIfStorelessAccess = () => {
44
+ if (fallbackRendersInFlight > 0 && !warnedFallbackDefault) {
45
+ warnedFallbackDefault = true;
46
+ console.warn(
47
+ "hono/jsx: AsyncLocalStorage is unavailable in this runtime, so useContext() after an await in an async component falls back to the context default value during server-side rendering. To get provided values across await boundaries, use a runtime with AsyncLocalStorage (Node.js >= 20.16, Deno, Bun, or Cloudflare Workers with the nodejs_compat flag)."
48
+ );
49
+ }
50
+ };
51
+ var getContextValuesIn = (store, context) => {
52
+ if (!store) {
53
+ warnIfStorelessAccess();
54
+ return context.values;
55
+ }
56
+ let values = store.get(context);
57
+ if (!values) {
58
+ values = [context.values[0]];
59
+ store.set(context, values);
60
+ }
61
+ return values;
62
+ };
63
+ var readContextValueIn = (store, context) => {
64
+ if (!store) {
65
+ warnIfStorelessAccess();
66
+ return context.values.at(-1);
67
+ }
68
+ const values = store.get(context);
69
+ return values?.length ? values.at(-1) : context.values[0];
70
+ };
71
+ var captureContextValues = (store) => (store ? globalContexts.filter((c) => store.has(c)) : globalContexts).map((c) => [
72
+ c,
73
+ readContextValueIn(store, c)
74
+ ]);
75
+ var resumeWithContextValues = (callback, store, contexts) => runWithRenderContext(() => {
76
+ const currentStore = getCurrentStore();
77
+ const valuesPerContext = contexts.map(([context, value]) => {
78
+ const values = getContextValuesIn(currentStore, context);
79
+ values.push(value);
80
+ return values;
81
+ });
82
+ const popContextValues = () => {
83
+ valuesPerContext.forEach((values) => {
84
+ values.pop();
85
+ });
86
+ };
87
+ try {
88
+ const result = callback();
89
+ if (result instanceof Promise) {
90
+ return result.finally(popContextValues);
91
+ }
92
+ popContextValues();
93
+ return result;
94
+ } catch (e) {
95
+ popContextValues();
96
+ throw e;
97
+ }
98
+ }, store);
99
+ var runWithRenderContext = (callback, resumeStore) => {
100
+ if (getCurrentStore()) {
101
+ return callback();
102
+ }
103
+ const store = resumeStore ?? /* @__PURE__ */ new WeakMap();
104
+ const storage = loadAsyncLocalStorage();
105
+ if (storage) {
106
+ return storage.run(store, callback);
107
+ }
108
+ fallbackStore = store;
109
+ let result;
110
+ try {
111
+ result = callback();
112
+ } finally {
113
+ fallbackStore = void 0;
114
+ }
115
+ if (!warnedFallbackDefault && result instanceof Promise) {
116
+ fallbackRendersInFlight++;
117
+ result = result.finally(() => {
118
+ fallbackRendersInFlight--;
119
+ });
120
+ }
121
+ return result;
122
+ };
123
+ var captureRenderContext = () => {
124
+ const store = getCurrentStore();
125
+ const contexts = captureContextValues(store);
126
+ return (callback) => resumeWithContextValues(callback, store, contexts);
127
+ };
7
128
  var createContext = (defaultValue) => {
8
129
  const values = [defaultValue];
9
130
  const context = ((props) => {
10
- values.push(props.value);
131
+ const contextValues = getContextValuesIn(getCurrentStore(), context);
132
+ contextValues.push(props.value);
11
133
  let string;
12
134
  try {
13
135
  string = props.children ? (Array.isArray(props.children) ? new JSXFragmentNode("", {}, props.children) : props.children).toString() : "";
14
136
  } catch (e) {
15
- values.pop();
137
+ contextValues.pop();
16
138
  throw e;
17
139
  }
18
140
  if (string instanceof Promise) {
19
- return string.finally(() => values.pop()).then((resString) => raw(resString, resString.callbacks));
141
+ return string.finally(() => contextValues.pop()).then((resString) => raw(resString, resString.callbacks));
20
142
  } else {
21
- values.pop();
143
+ contextValues.pop();
22
144
  return raw(string);
23
145
  }
24
146
  });
@@ -29,10 +151,12 @@ var createContext = (defaultValue) => {
29
151
  return context;
30
152
  };
31
153
  var useContext = (context) => {
32
- return context.values.at(-1);
154
+ return readContextValueIn(getCurrentStore(), context);
33
155
  };
34
156
  export {
157
+ captureRenderContext,
35
158
  createContext,
36
159
  globalContexts,
160
+ runWithRenderContext,
37
161
  useContext
38
162
  };
@@ -4,7 +4,7 @@ import { HtmlEscapedCallbackPhase, resolveCallback } from "../utils/html.js";
4
4
  import { JSXNode } from "./base.js";
5
5
  import { childrenToString } from "./components.js";
6
6
  import { DOM_RENDERER, DOM_STASH } from "./constants.js";
7
- import { createContext, useContext } from "./context.js";
7
+ import { captureRenderContext, createContext, useContext } from "./context.js";
8
8
  import { Suspense as SuspenseDomRenderer } from "./dom/components.js";
9
9
  import { buildDataStack } from "./dom/render.js";
10
10
  var StreamingContext = createContext(null);
@@ -19,9 +19,8 @@ var Suspense = async ({
19
19
  const nonce = useContext(StreamingContext)?.scriptNonce;
20
20
  let resArray = [];
21
21
  const stackNode = { [DOM_STASH]: [0, []] };
22
- const popNodeStack = (value) => {
22
+ const popNodeStack = () => {
23
23
  buildDataStack.pop();
24
- return value;
25
24
  };
26
25
  try {
27
26
  stackNode[DOM_STASH][0] = 0;
@@ -31,12 +30,15 @@ var Suspense = async ({
31
30
  );
32
31
  } catch (e) {
33
32
  if (e instanceof Promise) {
33
+ const resume = captureRenderContext();
34
34
  resArray = [
35
- e.then(() => {
36
- stackNode[DOM_STASH][0] = 0;
37
- buildDataStack.push([[], stackNode]);
38
- return childrenToString(children).then(popNodeStack);
39
- })
35
+ e.then(
36
+ () => resume(() => {
37
+ stackNode[DOM_STASH][0] = 0;
38
+ buildDataStack.push([[], stackNode]);
39
+ return childrenToString(children).finally(popNodeStack);
40
+ })
41
+ )
40
42
  ];
41
43
  } else {
42
44
  throw e;
@@ -44,7 +44,7 @@ var serveStatic = (options) => {
44
44
  if (content instanceof Response) {
45
45
  return c.newResponse(content.body, content);
46
46
  }
47
- if (content) {
47
+ if (content != null) {
48
48
  const mimeType = options.mimes && getMimeType(path, options.mimes) || getMimeType(path);
49
49
  c.header("Content-Type", mimeType || "application/octet-stream");
50
50
  if (options.precompressed && (!mimeType || COMPRESSIBLE_CONTENT_TYPE_REGEX.test(mimeType))) {
@@ -23,7 +23,6 @@ export declare namespace JSX {
23
23
  }
24
24
  export declare const getNameSpaceContext: () => Context<string> | undefined;
25
25
  export declare const booleanAttributes: string[];
26
- type LocalContexts = [Context<unknown>, unknown][];
27
26
  export type Child = string | Promise<string> | number | JSXNode | null | undefined | boolean | Child[];
28
27
  export declare class JSXNode implements HtmlEscaped {
29
28
  tag: string | Function;
@@ -31,7 +30,7 @@ export declare class JSXNode implements HtmlEscaped {
31
30
  key?: string;
32
31
  children: Child[];
33
32
  isEscaped: true;
34
- localContexts?: LocalContexts;
33
+ suspendedContext?: <T>(callback: () => T) => T;
35
34
  constructor(tag: string | Function, props: Props, children: Child[]);
36
35
  get type(): string | Function;
37
36
  get ref(): any;
@@ -55,4 +54,3 @@ export declare const Fragment: ({ children, }: {
55
54
  export declare const isValidElement: (element: unknown) => element is JSXNode;
56
55
  export declare const cloneElement: <T extends JSXNode | JSX.Element>(element: T, props: Partial<Props>, ...children: Child[]) => T;
57
56
  export declare const reactAPICompatVersion = "19.0.0-hono-jsx";
58
- export {};
@@ -8,5 +8,44 @@ export interface Context<T> extends FC<PropsWithChildren<{
8
8
  }>>;
9
9
  }
10
10
  export declare const globalContexts: Context<unknown>[];
11
+ /** Per-render context store, isolated per request so values never leak across renders. */
12
+ type RenderStore = WeakMap<Context<unknown>, unknown[]>;
13
+ /**
14
+ * Establish the request-scoped context store for a render.
15
+ *
16
+ * `resumeStore` continues a suspended subtree in the same store on the fallback
17
+ * path (ignored when `AsyncLocalStorage` is available, where isolation is
18
+ * automatic).
19
+ *
20
+ * Without `AsyncLocalStorage` a render can't be followed across `await`, so the
21
+ * store lives in `fallbackStore` only during synchronous work (mirroring
22
+ * React's request storage). Reading context after `await` then finds no store
23
+ * and falls back to the default value — never another request's value.
24
+ */
25
+ export declare const runWithRenderContext: <T>(callback: () => T, resumeStore?: RenderStore) => T;
26
+ /**
27
+ * Capture the current render store and return a resumer that re-establishes it
28
+ * around a deferred continuation (e.g. a re-render after a suspended promise
29
+ * settles). Shared by every suspension point so none reimplements it.
30
+ */
31
+ export declare const captureRenderContext: () => (<T>(callback: () => T) => T);
32
+ /**
33
+ * Create a context whose value can be provided with `<Context.Provider>` and
34
+ * read with {@link useContext}.
35
+ *
36
+ * Server-side renders are isolated per request, so a provided value never leaks
37
+ * into a concurrent request — even across `await` in an async component, when
38
+ * `AsyncLocalStorage` is available (Node.js >= 20.16, Deno, Bun, Cloudflare
39
+ * Workers with `nodejs_compat`). Without it, reading context after `await`
40
+ * returns the default value; synchronous components and `use()`-based
41
+ * suspension are unaffected.
42
+ */
11
43
  export declare const createContext: <T>(defaultValue: T) => Context<T>;
44
+ /**
45
+ * Read the current value of a context created with {@link createContext}.
46
+ *
47
+ * Safe to call from async components after `await`. See {@link createContext}
48
+ * for the per-runtime isolation guarantees.
49
+ */
12
50
  export declare const useContext: <T>(context: Context<T>) => T;
51
+ export {};
@@ -24,11 +24,11 @@ import type { Env, MiddlewareHandler } from '../../types';
24
24
  * app.use(contextStorage())
25
25
  *
26
26
  * app.use(async (c, next) => {
27
- * c.set('message', 'Hono is hot!!)
27
+ * c.set('message', 'Hono is hot!!')
28
28
  * await next()
29
29
  * })
30
30
  *
31
- * app.get('/', async (c) => { c.text(getMessage()) })
31
+ * app.get('/', async (c) => c.text(getMessage()))
32
32
  *
33
33
  * const getMessage = () => {
34
34
  * return getContext<Env>().var.message
@@ -2,7 +2,7 @@
2
2
  * @module
3
3
  * Body utility.
4
4
  */
5
- import { HonoRequest } from '../request';
5
+ import type { HonoRequest } from '../request';
6
6
  type BodyDataValueDot = {
7
7
  [x: string]: string | File | BodyDataValueDot;
8
8
  };
@@ -1,16 +1,24 @@
1
1
  // src/utils/body.ts
2
- import { HonoRequest } from "../request.js";
2
+ import { bufferToFormData } from "./buffer.js";
3
+ var isRawRequest = (request) => "headers" in request;
3
4
  var parseBody = async (request, options = /* @__PURE__ */ Object.create(null)) => {
4
5
  const { all = false, dot = false } = options;
5
- const headers = request instanceof HonoRequest ? request.raw.headers : request.headers;
6
+ const headers = isRawRequest(request) ? request.headers : request.raw.headers;
6
7
  const contentType = headers.get("Content-Type");
7
- if (contentType?.startsWith("multipart/form-data") || contentType?.startsWith("application/x-www-form-urlencoded")) {
8
+ const mediaType = contentType?.split(";")[0].trim().toLowerCase();
9
+ if (mediaType === "multipart/form-data" || mediaType === "application/x-www-form-urlencoded") {
8
10
  return parseFormData(request, { all, dot });
9
11
  }
10
12
  return {};
11
13
  };
12
14
  async function parseFormData(request, options) {
13
- const formData = await request.formData();
15
+ const headers = isRawRequest(request) ? request.headers : request.raw.headers;
16
+ const arrayBuffer = await request.arrayBuffer();
17
+ const formDataPromise = bufferToFormData(arrayBuffer, headers.get("Content-Type") || "");
18
+ if (!isRawRequest(request)) {
19
+ request.bodyCache.formData = formDataPromise;
20
+ }
21
+ const formData = await formDataPromise;
14
22
  if (formData) {
15
23
  return convertFormDataToBodyData(formData, options);
16
24
  }
@@ -64,7 +64,8 @@ var bufferToString = (buffer) => {
64
64
  var bufferToFormData = (arrayBuffer, contentType) => {
65
65
  const response = new Response(arrayBuffer, {
66
66
  headers: {
67
- "Content-Type": contentType
67
+ // Normalize the media type (case-insensitive) while keeping parameters like the boundary
68
+ "Content-Type": contentType.replace(/^[^;]+/, (mediaType) => mediaType.toLowerCase())
68
69
  }
69
70
  });
70
71
  return response.formData();
@@ -2,9 +2,9 @@
2
2
  import { getCookie } from "../helper/cookie/index.js";
3
3
  import { HTTPException } from "../http-exception.js";
4
4
  import { bufferToFormData } from "../utils/buffer.js";
5
- var jsonRegex = /^application\/([a-z-\.]+\+)?json(;\s*[a-zA-Z0-9\-]+\=([^;]+))*$/;
6
- var multipartRegex = /^multipart\/form-data(;\s?boundary=[a-zA-Z0-9'"()+_,\-./:=?]+)?$/;
7
- var urlencodedRegex = /^application\/x-www-form-urlencoded(;\s*[a-zA-Z0-9\-]+\=([^;]+))*$/;
5
+ var jsonRegex = /^application\/([a-z-\.]+\+)?json(;\s*[a-zA-Z0-9\-]+\=([^;]+))*$/i;
6
+ var multipartRegex = /^multipart\/form-data(;\s?boundary=[a-zA-Z0-9'"()+_,\-./:=?]+)?$/i;
7
+ var urlencodedRegex = /^application\/x-www-form-urlencoded(;\s*[a-zA-Z0-9\-]+\=([^;]+))*$/i;
8
8
  var validator = (target, validationFunc) => {
9
9
  return async (c, next) => {
10
10
  let value = {};
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "hono",
3
- "version": "4.12.26",
3
+ "version": "4.12.28",
4
4
  "description": "Web framework built on Web Standards",
5
5
  "main": "dist/cjs/index.js",
6
6
  "type": "module",
7
7
  "module": "dist/index.js",
8
8
  "types": "dist/types/index.d.ts",
9
9
  "files": [
10
- "dist"
10
+ "dist",
11
+ "!dist/**/*.tsbuildinfo"
11
12
  ],
12
13
  "scripts": {
13
14
  "test": "tsc --noEmit && vitest --run",
@@ -678,17 +679,17 @@
678
679
  "eslint": "^9.39.3",
679
680
  "jsdom": "22.1.0",
680
681
  "msw": "^2.6.0",
681
- "np": "10.2.0",
682
+ "np": "11.2.1",
682
683
  "oxc-parser": "^0.96.0",
683
684
  "pkg-pr-new": "^0.0.53",
684
685
  "prettier": "3.7.4",
685
686
  "publint": "0.3.15",
686
687
  "typescript": "^5.9.2",
687
- "undici": "^6.21.3",
688
+ "undici": "^6.27.0",
688
689
  "vite-plugin-fastly-js-compute": "^0.4.2",
689
- "vitest": "^4.1.7",
690
- "wrangler": "4.12.0",
691
- "ws": "^8.18.0",
690
+ "vitest": "^4.1.9",
691
+ "wrangler": "4.107.0",
692
+ "ws": "^8.21.0",
692
693
  "zod": "^3.23.8"
693
694
  },
694
695
  "packageManager": "bun@1.2.20",