hono 3.10.0-rc.1 β 3.10.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.
- package/README.md +3 -3
- package/dist/adapter/aws-lambda/handler.js +8 -5
- package/dist/cjs/adapter/aws-lambda/handler.js +8 -5
- package/dist/cjs/helper/html/index.js +3 -2
- package/dist/cjs/helper/streaming/index.js +6 -2
- package/dist/cjs/hono-base.js +1 -1
- package/dist/cjs/jsx/index.js +20 -14
- package/dist/cjs/jsx/jsx-dev-runtime.js +4 -1
- package/dist/cjs/jsx/jsx-runtime.js +9 -0
- package/dist/cjs/jsx/streaming.js +44 -35
- package/dist/cjs/middleware/jsx-renderer/index.js +17 -7
- package/dist/cjs/utils/html.js +2 -4
- package/dist/helper/html/index.js +3 -2
- package/dist/helper/streaming/index.js +6 -2
- package/dist/hono-base.js +1 -1
- package/dist/jsx/index.js +14 -8
- package/dist/jsx/jsx-dev-runtime.js +4 -1
- package/dist/jsx/jsx-runtime.js +6 -0
- package/dist/jsx/streaming.js +44 -35
- package/dist/middleware/jsx-renderer/index.js +17 -7
- package/dist/types/context.d.ts +1 -1
- package/dist/types/helper/adapter/index.d.ts +1 -1
- package/dist/types/helper/factory/index.d.ts +0 -5
- package/dist/types/helper/html/index.d.ts +1 -1
- package/dist/types/hono-base.d.ts +0 -5
- package/dist/types/jsx/jsx-runtime.d.ts +4 -0
- package/dist/types/middleware/jsx-renderer/index.d.ts +1 -0
- package/dist/types/types.d.ts +10 -10
- package/dist/utils/html.js +2 -4
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
[](https://discord.gg/KMh2eNSdxV)
|
|
27
27
|
|
|
28
28
|
Hono - _**\[η\] means flameπ₯ in Japanese**_ - is a small, simple, and ultrafast web framework for the Edges.
|
|
29
|
-
It works on any JavaScript runtime: Cloudflare Workers, Fastly Compute
|
|
29
|
+
It works on any JavaScript runtime: Cloudflare Workers, Fastly Compute, Deno, Bun, Vercel, Lagon, AWS Lambda, Lambda@Edge, and Node.js.
|
|
30
30
|
|
|
31
31
|
Fast, but not only fast.
|
|
32
32
|
|
|
@@ -49,9 +49,9 @@ npm create hono@latest my-app
|
|
|
49
49
|
|
|
50
50
|
- **Ultrafast** π - The router `RegExpRouter` is really fast. Not using linear loops. Fast.
|
|
51
51
|
- **Lightweight** πͺΆ - The `hono/tiny` preset is under 12kB. Hono has zero dependencies and uses only the Web Standard API.
|
|
52
|
-
- **Multi-runtime** π - Works on Cloudflare Workers, Fastly Compute
|
|
52
|
+
- **Multi-runtime** π - Works on Cloudflare Workers, Fastly Compute, Deno, Bun, Lagon, AWS Lambda, Lambda@Edge, or Node.js. The same code runs on all platforms.
|
|
53
53
|
- **Batteries Included** π - Hono has built-in middleware, custom middleware, and third-party middleware. Batteries included.
|
|
54
|
-
- **Delightful DX**
|
|
54
|
+
- **Delightful DX** π - Super clean APIs. First-class TypeScript support. Now, we've got "Types".
|
|
55
55
|
|
|
56
56
|
## Benchmarks
|
|
57
57
|
|
|
@@ -23,12 +23,15 @@ var streamHandle = (app) => {
|
|
|
23
23
|
requestContext,
|
|
24
24
|
context
|
|
25
25
|
});
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
26
|
+
const httpResponseMetadata = {
|
|
27
|
+
statusCode: res.status,
|
|
28
|
+
headers: Object.fromEntries(res.headers.entries())
|
|
29
|
+
};
|
|
30
30
|
if (res.body) {
|
|
31
|
-
await streamToNodeStream(
|
|
31
|
+
await streamToNodeStream(
|
|
32
|
+
res.body.getReader(),
|
|
33
|
+
awslambda.HttpResponseStream.from(responseStream, httpResponseMetadata)
|
|
34
|
+
);
|
|
32
35
|
}
|
|
33
36
|
} catch (error) {
|
|
34
37
|
console.error("Error processing request:", error);
|
|
@@ -54,12 +54,15 @@ const streamHandle = (app) => {
|
|
|
54
54
|
requestContext,
|
|
55
55
|
context
|
|
56
56
|
});
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
57
|
+
const httpResponseMetadata = {
|
|
58
|
+
statusCode: res.status,
|
|
59
|
+
headers: Object.fromEntries(res.headers.entries())
|
|
60
|
+
};
|
|
61
61
|
if (res.body) {
|
|
62
|
-
await streamToNodeStream(
|
|
62
|
+
await streamToNodeStream(
|
|
63
|
+
res.body.getReader(),
|
|
64
|
+
awslambda.HttpResponseStream.from(responseStream, httpResponseMetadata)
|
|
65
|
+
);
|
|
63
66
|
}
|
|
64
67
|
} catch (error) {
|
|
65
68
|
console.error("Error processing request:", error);
|
|
@@ -23,9 +23,10 @@ __export(html_exports, {
|
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(html_exports);
|
|
25
25
|
var import_html = require("../../utils/html");
|
|
26
|
-
const raw = (value) => {
|
|
26
|
+
const raw = (value, promises) => {
|
|
27
27
|
const escapedString = new String(value);
|
|
28
28
|
escapedString.isEscaped = true;
|
|
29
|
+
escapedString.promises = promises;
|
|
29
30
|
return escapedString;
|
|
30
31
|
};
|
|
31
32
|
const html = (strings, ...values) => {
|
|
@@ -52,7 +53,7 @@ const html = (strings, ...values) => {
|
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
55
|
buffer[0] += strings[strings.length - 1];
|
|
55
|
-
return buffer.length === 1 ? raw(buffer[0]) : (0, import_html.stringBufferToString)(buffer)
|
|
56
|
+
return buffer.length === 1 ? raw(buffer[0]) : (0, import_html.stringBufferToString)(buffer);
|
|
56
57
|
};
|
|
57
58
|
// Annotate the CommonJS export names for ESM import in node:
|
|
58
59
|
0 && (module.exports = {
|
|
@@ -44,13 +44,17 @@ const streamSSE = (c, cb) => {
|
|
|
44
44
|
return c.stream(async (originalStream) => {
|
|
45
45
|
const { readable, writable } = new TransformStream();
|
|
46
46
|
const stream = new SSEStreamingApi(writable);
|
|
47
|
-
originalStream.pipe(readable)
|
|
47
|
+
originalStream.pipe(readable).catch((err) => {
|
|
48
|
+
console.error("Error in stream piping: ", err);
|
|
49
|
+
stream.close();
|
|
50
|
+
});
|
|
48
51
|
setSSEHeaders(c);
|
|
49
52
|
try {
|
|
50
53
|
await cb(stream);
|
|
51
54
|
} catch (err) {
|
|
52
55
|
console.error("Error during streaming: ", err);
|
|
53
|
-
|
|
56
|
+
} finally {
|
|
57
|
+
await stream.close();
|
|
54
58
|
}
|
|
55
59
|
});
|
|
56
60
|
};
|
package/dist/cjs/hono-base.js
CHANGED
package/dist/cjs/jsx/index.js
CHANGED
|
@@ -26,7 +26,8 @@ __export(jsx_exports, {
|
|
|
26
26
|
useContext: () => useContext
|
|
27
27
|
});
|
|
28
28
|
module.exports = __toCommonJS(jsx_exports);
|
|
29
|
-
var import_html = require("../
|
|
29
|
+
var import_html = require("../helper/html");
|
|
30
|
+
var import_html2 = require("../utils/html");
|
|
30
31
|
const emptyTags = [
|
|
31
32
|
"area",
|
|
32
33
|
"base",
|
|
@@ -75,7 +76,7 @@ const childrenToStringToBuffer = (children, buffer) => {
|
|
|
75
76
|
for (let i = 0, len = children.length; i < len; i++) {
|
|
76
77
|
const child = children[i];
|
|
77
78
|
if (typeof child === "string") {
|
|
78
|
-
(0,
|
|
79
|
+
(0, import_html2.escapeToBuffer)(child, buffer);
|
|
79
80
|
} else if (typeof child === "boolean" || child === null || child === void 0) {
|
|
80
81
|
continue;
|
|
81
82
|
} else if (child instanceof JSXNode) {
|
|
@@ -100,7 +101,7 @@ class JSXNode {
|
|
|
100
101
|
toString() {
|
|
101
102
|
const buffer = [""];
|
|
102
103
|
this.toStringToBuffer(buffer);
|
|
103
|
-
return buffer.length === 1 ? buffer[0] : (0,
|
|
104
|
+
return buffer.length === 1 ? buffer[0] : (0, import_html2.stringBufferToString)(buffer);
|
|
104
105
|
}
|
|
105
106
|
toStringToBuffer(buffer) {
|
|
106
107
|
const tag = this.tag;
|
|
@@ -119,7 +120,7 @@ class JSXNode {
|
|
|
119
120
|
buffer[0] += ` style="${styles}"`;
|
|
120
121
|
} else if (typeof v === "string") {
|
|
121
122
|
buffer[0] += ` ${key}="`;
|
|
122
|
-
(0,
|
|
123
|
+
(0, import_html2.escapeToBuffer)(v, buffer);
|
|
123
124
|
buffer[0] += '"';
|
|
124
125
|
} else if (typeof v === "number") {
|
|
125
126
|
buffer[0] += ` ${key}="${v}"`;
|
|
@@ -132,12 +133,10 @@ class JSXNode {
|
|
|
132
133
|
if (children.length > 0) {
|
|
133
134
|
throw "Can only set one of `children` or `props.dangerouslySetInnerHTML`.";
|
|
134
135
|
}
|
|
135
|
-
|
|
136
|
-
escapedString.isEscaped = true;
|
|
137
|
-
children = [escapedString];
|
|
136
|
+
children = [(0, import_html.raw)(v.__html)];
|
|
138
137
|
} else {
|
|
139
138
|
buffer[0] += ` ${key}="`;
|
|
140
|
-
(0,
|
|
139
|
+
(0, import_html2.escapeToBuffer)(v.toString(), buffer);
|
|
141
140
|
buffer[0] += '"';
|
|
142
141
|
}
|
|
143
142
|
}
|
|
@@ -164,7 +163,7 @@ class JSXFunctionNode extends JSXNode {
|
|
|
164
163
|
} else if (typeof res === "number" || res.isEscaped) {
|
|
165
164
|
buffer[0] += res;
|
|
166
165
|
} else {
|
|
167
|
-
(0,
|
|
166
|
+
(0, import_html2.escapeToBuffer)(res, buffer);
|
|
168
167
|
}
|
|
169
168
|
}
|
|
170
169
|
}
|
|
@@ -216,12 +215,19 @@ const createContext = (defaultValue) => {
|
|
|
216
215
|
values,
|
|
217
216
|
Provider(props) {
|
|
218
217
|
values.push(props.value);
|
|
219
|
-
const
|
|
220
|
-
props.children ? (Array.isArray(props.children) ? new JSXFragmentNode("", {}, props.children) : props.children).toString() : ""
|
|
221
|
-
);
|
|
222
|
-
res.isEscaped = true;
|
|
218
|
+
const string = props.children ? (Array.isArray(props.children) ? new JSXFragmentNode("", {}, props.children) : props.children).toString() : "";
|
|
223
219
|
values.pop();
|
|
224
|
-
|
|
220
|
+
if (string instanceof Promise) {
|
|
221
|
+
return Promise.resolve().then(async () => {
|
|
222
|
+
values.push(props.value);
|
|
223
|
+
const awaited = await string;
|
|
224
|
+
const promiseRes = (0, import_html.raw)(awaited, awaited.promises);
|
|
225
|
+
values.pop();
|
|
226
|
+
return promiseRes;
|
|
227
|
+
});
|
|
228
|
+
} else {
|
|
229
|
+
return (0, import_html.raw)(string);
|
|
230
|
+
}
|
|
225
231
|
}
|
|
226
232
|
};
|
|
227
233
|
};
|
|
@@ -25,7 +25,10 @@ module.exports = __toCommonJS(jsx_dev_runtime_exports);
|
|
|
25
25
|
var import__ = require(".");
|
|
26
26
|
var import__2 = require(".");
|
|
27
27
|
function jsxDEV(tag, props) {
|
|
28
|
-
|
|
28
|
+
if (!props?.children) {
|
|
29
|
+
return (0, import__.jsx)(tag, props);
|
|
30
|
+
}
|
|
31
|
+
const children = props.children;
|
|
29
32
|
delete props["children"];
|
|
30
33
|
return Array.isArray(children) ? (0, import__.jsx)(tag, props, ...children) : (0, import__.jsx)(tag, props, children);
|
|
31
34
|
}
|
|
@@ -20,14 +20,23 @@ var jsx_runtime_exports = {};
|
|
|
20
20
|
__export(jsx_runtime_exports, {
|
|
21
21
|
Fragment: () => import_jsx_dev_runtime.Fragment,
|
|
22
22
|
jsx: () => import_jsx_dev_runtime.jsxDEV,
|
|
23
|
+
jsxAttr: () => jsxAttr,
|
|
24
|
+
jsxEscape: () => jsxEscape,
|
|
25
|
+
jsxTemplate: () => import_html.html,
|
|
23
26
|
jsxs: () => import_jsx_dev_runtime2.jsxDEV
|
|
24
27
|
});
|
|
25
28
|
module.exports = __toCommonJS(jsx_runtime_exports);
|
|
26
29
|
var import_jsx_dev_runtime = require("./jsx-dev-runtime");
|
|
27
30
|
var import_jsx_dev_runtime2 = require("./jsx-dev-runtime");
|
|
31
|
+
var import_html = require("../helper/html");
|
|
32
|
+
const jsxAttr = (name, value) => (0, import_html.raw)(name + '="' + import_html.html`${value}` + '"');
|
|
33
|
+
const jsxEscape = (value) => value;
|
|
28
34
|
// Annotate the CommonJS export names for ESM import in node:
|
|
29
35
|
0 && (module.exports = {
|
|
30
36
|
Fragment,
|
|
31
37
|
jsx,
|
|
38
|
+
jsxAttr,
|
|
39
|
+
jsxEscape,
|
|
40
|
+
jsxTemplate,
|
|
32
41
|
jsxs
|
|
33
42
|
});
|
|
@@ -22,10 +22,11 @@ __export(streaming_exports, {
|
|
|
22
22
|
renderToReadableStream: () => renderToReadableStream
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(streaming_exports);
|
|
25
|
+
var import_html = require("../helper/html");
|
|
25
26
|
let suspenseCounter = 0;
|
|
26
27
|
async function childrenToString(children) {
|
|
27
28
|
try {
|
|
28
|
-
return children.toString();
|
|
29
|
+
return children.map((c) => c.toString());
|
|
29
30
|
} catch (e) {
|
|
30
31
|
if (e instanceof Promise) {
|
|
31
32
|
await e;
|
|
@@ -39,26 +40,25 @@ const Suspense = async ({ children, fallback }) => {
|
|
|
39
40
|
if (!children) {
|
|
40
41
|
return fallback.toString();
|
|
41
42
|
}
|
|
42
|
-
|
|
43
|
+
if (!Array.isArray(children)) {
|
|
44
|
+
children = [children];
|
|
45
|
+
}
|
|
46
|
+
let resArray = [];
|
|
43
47
|
try {
|
|
44
|
-
|
|
48
|
+
resArray = children.map((c) => c.toString());
|
|
45
49
|
} catch (e) {
|
|
46
50
|
if (e instanceof Promise) {
|
|
47
|
-
|
|
51
|
+
resArray = [e.then(() => childrenToString(children))];
|
|
48
52
|
} else {
|
|
49
53
|
throw e;
|
|
50
54
|
}
|
|
51
|
-
}
|
|
55
|
+
}
|
|
56
|
+
if (resArray.some((res) => res instanceof Promise)) {
|
|
52
57
|
const index = suspenseCounter++;
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
);
|
|
58
|
-
res.isEscaped = true;
|
|
59
|
-
res.promises = [
|
|
60
|
-
promise.then(async () => {
|
|
61
|
-
return `<template>${await childrenToString(children)}</template><script>
|
|
58
|
+
return (0, import_html.raw)(`<template id="H:${index}"></template>${fallback.toString()}<!--/$-->`, [
|
|
59
|
+
Promise.all(resArray).then((htmlArray) => {
|
|
60
|
+
htmlArray = htmlArray.flat();
|
|
61
|
+
const html = `<template>${htmlArray.join("")}</template><script>
|
|
62
62
|
((d,c,n) => {
|
|
63
63
|
c=d.currentScript.previousSibling
|
|
64
64
|
d=d.getElementById('H:${index}')
|
|
@@ -66,35 +66,44 @@ do{n=d.nextSibling;n.remove()}while(n.nodeType!=8||n.nodeValue!='/$')
|
|
|
66
66
|
d.replaceWith(c.content)
|
|
67
67
|
})(document)
|
|
68
68
|
<\/script>`;
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
if (htmlArray.every((html2) => !html2.promises?.length)) {
|
|
70
|
+
return html;
|
|
71
|
+
}
|
|
72
|
+
return (0, import_html.raw)(html, htmlArray.map((html2) => html2.promises || []).flat());
|
|
73
|
+
})
|
|
74
|
+
]);
|
|
75
|
+
} else {
|
|
76
|
+
return (0, import_html.raw)(resArray.join(""));
|
|
72
77
|
}
|
|
73
|
-
return res;
|
|
74
78
|
};
|
|
75
79
|
const textEncoder = new TextEncoder();
|
|
76
80
|
const renderToReadableStream = (str) => {
|
|
77
81
|
const reader = new ReadableStream({
|
|
78
82
|
async start(controller) {
|
|
79
|
-
const resolved = await str.toString();
|
|
83
|
+
const resolved = str instanceof Promise ? await str : await str.toString();
|
|
80
84
|
controller.enqueue(textEncoder.encode(resolved));
|
|
81
|
-
let
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
controller.
|
|
95
|
-
}
|
|
96
|
-
|
|
85
|
+
let resolvedCount = 0;
|
|
86
|
+
const promises = [];
|
|
87
|
+
const then = (promise) => {
|
|
88
|
+
promises.push(
|
|
89
|
+
promise.catch((err) => {
|
|
90
|
+
console.trace(err);
|
|
91
|
+
return "";
|
|
92
|
+
}).then((res) => {
|
|
93
|
+
if (res.promises) {
|
|
94
|
+
const resPromises = res.promises || [];
|
|
95
|
+
resPromises.forEach(then);
|
|
96
|
+
}
|
|
97
|
+
resolvedCount++;
|
|
98
|
+
controller.enqueue(textEncoder.encode(res));
|
|
99
|
+
})
|
|
100
|
+
);
|
|
101
|
+
};
|
|
102
|
+
resolved.promises?.map(then);
|
|
103
|
+
while (resolvedCount !== promises.length) {
|
|
104
|
+
await Promise.all(promises);
|
|
97
105
|
}
|
|
106
|
+
controller.close();
|
|
98
107
|
}
|
|
99
108
|
});
|
|
100
109
|
return reader;
|
|
@@ -23,17 +23,27 @@ __export(jsx_renderer_exports, {
|
|
|
23
23
|
useRequestContext: () => useRequestContext
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(jsx_renderer_exports);
|
|
26
|
+
var import_html = require("../../helper/html");
|
|
26
27
|
var import_jsx = require("../../jsx");
|
|
28
|
+
var import_streaming = require("../../jsx/streaming");
|
|
27
29
|
const RequestContext = (0, import_jsx.createContext)(null);
|
|
28
30
|
const createRenderer = (c, component, options) => (children, props) => {
|
|
29
31
|
const docType = typeof options?.docType === "string" ? options.docType : options?.docType === true ? "<!DOCTYPE html>" : "";
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
const body = import_html.html`${(0, import_html.raw)(docType)}${(0, import_jsx.jsx)(
|
|
33
|
+
RequestContext.Provider,
|
|
34
|
+
{ value: c },
|
|
35
|
+
component ? component({ children, ...props || {} }) : children
|
|
36
|
+
)}`;
|
|
37
|
+
if (options?.stream) {
|
|
38
|
+
return c.body((0, import_streaming.renderToReadableStream)(body), {
|
|
39
|
+
headers: options.stream === true ? {
|
|
40
|
+
"Transfer-Encoding": "chunked",
|
|
41
|
+
"Content-Type": "text/html; charset=UTF-8"
|
|
42
|
+
} : options.stream
|
|
43
|
+
});
|
|
44
|
+
} else {
|
|
45
|
+
return c.html(body);
|
|
46
|
+
}
|
|
37
47
|
};
|
|
38
48
|
const jsxRenderer = (component, options) => (c, next) => {
|
|
39
49
|
c.setRenderer(createRenderer(c, component, options));
|
package/dist/cjs/utils/html.js
CHANGED
|
@@ -22,6 +22,7 @@ __export(html_exports, {
|
|
|
22
22
|
stringBufferToString: () => stringBufferToString
|
|
23
23
|
});
|
|
24
24
|
module.exports = __toCommonJS(html_exports);
|
|
25
|
+
var import_html = require("../helper/html");
|
|
25
26
|
const escapeRe = /[&<>'"]/;
|
|
26
27
|
const stringBufferToString = async (buffer) => {
|
|
27
28
|
let str = "";
|
|
@@ -37,10 +38,7 @@ const stringBufferToString = async (buffer) => {
|
|
|
37
38
|
}
|
|
38
39
|
str += r;
|
|
39
40
|
}
|
|
40
|
-
|
|
41
|
-
res.isEscaped = true;
|
|
42
|
-
res.promises = promises;
|
|
43
|
-
return res;
|
|
41
|
+
return (0, import_html.raw)(str, promises);
|
|
44
42
|
};
|
|
45
43
|
const escapeToBuffer = (str, buffer) => {
|
|
46
44
|
const match = str.search(escapeRe);
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// src/helper/html/index.ts
|
|
2
2
|
import { escapeToBuffer, stringBufferToString } from "../../utils/html.js";
|
|
3
|
-
var raw = (value) => {
|
|
3
|
+
var raw = (value, promises) => {
|
|
4
4
|
const escapedString = new String(value);
|
|
5
5
|
escapedString.isEscaped = true;
|
|
6
|
+
escapedString.promises = promises;
|
|
6
7
|
return escapedString;
|
|
7
8
|
};
|
|
8
9
|
var html = (strings, ...values) => {
|
|
@@ -29,7 +30,7 @@ var html = (strings, ...values) => {
|
|
|
29
30
|
}
|
|
30
31
|
}
|
|
31
32
|
buffer[0] += strings[strings.length - 1];
|
|
32
|
-
return buffer.length === 1 ? raw(buffer[0]) : stringBufferToString(buffer)
|
|
33
|
+
return buffer.length === 1 ? raw(buffer[0]) : stringBufferToString(buffer);
|
|
33
34
|
};
|
|
34
35
|
export {
|
|
35
36
|
html,
|
|
@@ -22,13 +22,17 @@ var streamSSE = (c, cb) => {
|
|
|
22
22
|
return c.stream(async (originalStream) => {
|
|
23
23
|
const { readable, writable } = new TransformStream();
|
|
24
24
|
const stream = new SSEStreamingApi(writable);
|
|
25
|
-
originalStream.pipe(readable)
|
|
25
|
+
originalStream.pipe(readable).catch((err) => {
|
|
26
|
+
console.error("Error in stream piping: ", err);
|
|
27
|
+
stream.close();
|
|
28
|
+
});
|
|
26
29
|
setSSEHeaders(c);
|
|
27
30
|
try {
|
|
28
31
|
await cb(stream);
|
|
29
32
|
} catch (err) {
|
|
30
33
|
console.error("Error during streaming: ", err);
|
|
31
|
-
|
|
34
|
+
} finally {
|
|
35
|
+
await stream.close();
|
|
32
36
|
}
|
|
33
37
|
});
|
|
34
38
|
};
|
package/dist/hono-base.js
CHANGED
package/dist/jsx/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// src/jsx/index.ts
|
|
2
|
+
import { raw } from "../helper/html/index.js";
|
|
2
3
|
import { escapeToBuffer, stringBufferToString } from "../utils/html.js";
|
|
3
4
|
var emptyTags = [
|
|
4
5
|
"area",
|
|
@@ -105,9 +106,7 @@ var JSXNode = class {
|
|
|
105
106
|
if (children.length > 0) {
|
|
106
107
|
throw "Can only set one of `children` or `props.dangerouslySetInnerHTML`.";
|
|
107
108
|
}
|
|
108
|
-
|
|
109
|
-
escapedString.isEscaped = true;
|
|
110
|
-
children = [escapedString];
|
|
109
|
+
children = [raw(v.__html)];
|
|
111
110
|
} else {
|
|
112
111
|
buffer[0] += ` ${key}="`;
|
|
113
112
|
escapeToBuffer(v.toString(), buffer);
|
|
@@ -189,12 +188,19 @@ var createContext = (defaultValue) => {
|
|
|
189
188
|
values,
|
|
190
189
|
Provider(props) {
|
|
191
190
|
values.push(props.value);
|
|
192
|
-
const
|
|
193
|
-
props.children ? (Array.isArray(props.children) ? new JSXFragmentNode("", {}, props.children) : props.children).toString() : ""
|
|
194
|
-
);
|
|
195
|
-
res.isEscaped = true;
|
|
191
|
+
const string = props.children ? (Array.isArray(props.children) ? new JSXFragmentNode("", {}, props.children) : props.children).toString() : "";
|
|
196
192
|
values.pop();
|
|
197
|
-
|
|
193
|
+
if (string instanceof Promise) {
|
|
194
|
+
return Promise.resolve().then(async () => {
|
|
195
|
+
values.push(props.value);
|
|
196
|
+
const awaited = await string;
|
|
197
|
+
const promiseRes = raw(awaited, awaited.promises);
|
|
198
|
+
values.pop();
|
|
199
|
+
return promiseRes;
|
|
200
|
+
});
|
|
201
|
+
} else {
|
|
202
|
+
return raw(string);
|
|
203
|
+
}
|
|
198
204
|
}
|
|
199
205
|
};
|
|
200
206
|
};
|
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
import { jsx } from "./index.js";
|
|
3
3
|
import { Fragment } from "./index.js";
|
|
4
4
|
function jsxDEV(tag, props) {
|
|
5
|
-
|
|
5
|
+
if (!props?.children) {
|
|
6
|
+
return jsx(tag, props);
|
|
7
|
+
}
|
|
8
|
+
const children = props.children;
|
|
6
9
|
delete props["children"];
|
|
7
10
|
return Array.isArray(children) ? jsx(tag, props, ...children) : jsx(tag, props, children);
|
|
8
11
|
}
|
package/dist/jsx/jsx-runtime.js
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
// src/jsx/jsx-runtime.ts
|
|
2
2
|
import { jsxDEV, Fragment } from "./jsx-dev-runtime.js";
|
|
3
3
|
import { jsxDEV as jsxDEV2 } from "./jsx-dev-runtime.js";
|
|
4
|
+
import { raw, html } from "../helper/html/index.js";
|
|
5
|
+
var jsxAttr = (name, value) => raw(name + '="' + html`${value}` + '"');
|
|
6
|
+
var jsxEscape = (value) => value;
|
|
4
7
|
export {
|
|
5
8
|
Fragment,
|
|
6
9
|
jsxDEV as jsx,
|
|
10
|
+
jsxAttr,
|
|
11
|
+
jsxEscape,
|
|
12
|
+
html as jsxTemplate,
|
|
7
13
|
jsxDEV2 as jsxs
|
|
8
14
|
};
|
package/dist/jsx/streaming.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// src/jsx/streaming.ts
|
|
2
|
+
import { raw } from "../helper/html/index.js";
|
|
2
3
|
var suspenseCounter = 0;
|
|
3
4
|
async function childrenToString(children) {
|
|
4
5
|
try {
|
|
5
|
-
return children.toString();
|
|
6
|
+
return children.map((c) => c.toString());
|
|
6
7
|
} catch (e) {
|
|
7
8
|
if (e instanceof Promise) {
|
|
8
9
|
await e;
|
|
@@ -16,26 +17,25 @@ var Suspense = async ({ children, fallback }) => {
|
|
|
16
17
|
if (!children) {
|
|
17
18
|
return fallback.toString();
|
|
18
19
|
}
|
|
19
|
-
|
|
20
|
+
if (!Array.isArray(children)) {
|
|
21
|
+
children = [children];
|
|
22
|
+
}
|
|
23
|
+
let resArray = [];
|
|
20
24
|
try {
|
|
21
|
-
|
|
25
|
+
resArray = children.map((c) => c.toString());
|
|
22
26
|
} catch (e) {
|
|
23
27
|
if (e instanceof Promise) {
|
|
24
|
-
|
|
28
|
+
resArray = [e.then(() => childrenToString(children))];
|
|
25
29
|
} else {
|
|
26
30
|
throw e;
|
|
27
31
|
}
|
|
28
|
-
}
|
|
32
|
+
}
|
|
33
|
+
if (resArray.some((res) => res instanceof Promise)) {
|
|
29
34
|
const index = suspenseCounter++;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
);
|
|
35
|
-
res.isEscaped = true;
|
|
36
|
-
res.promises = [
|
|
37
|
-
promise.then(async () => {
|
|
38
|
-
return `<template>${await childrenToString(children)}</template><script>
|
|
35
|
+
return raw(`<template id="H:${index}"></template>${fallback.toString()}<!--/$-->`, [
|
|
36
|
+
Promise.all(resArray).then((htmlArray) => {
|
|
37
|
+
htmlArray = htmlArray.flat();
|
|
38
|
+
const html = `<template>${htmlArray.join("")}</template><script>
|
|
39
39
|
((d,c,n) => {
|
|
40
40
|
c=d.currentScript.previousSibling
|
|
41
41
|
d=d.getElementById('H:${index}')
|
|
@@ -43,35 +43,44 @@ do{n=d.nextSibling;n.remove()}while(n.nodeType!=8||n.nodeValue!='/$')
|
|
|
43
43
|
d.replaceWith(c.content)
|
|
44
44
|
})(document)
|
|
45
45
|
<\/script>`;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
if (htmlArray.every((html2) => !html2.promises?.length)) {
|
|
47
|
+
return html;
|
|
48
|
+
}
|
|
49
|
+
return raw(html, htmlArray.map((html2) => html2.promises || []).flat());
|
|
50
|
+
})
|
|
51
|
+
]);
|
|
52
|
+
} else {
|
|
53
|
+
return raw(resArray.join(""));
|
|
49
54
|
}
|
|
50
|
-
return res;
|
|
51
55
|
};
|
|
52
56
|
var textEncoder = new TextEncoder();
|
|
53
57
|
var renderToReadableStream = (str) => {
|
|
54
58
|
const reader = new ReadableStream({
|
|
55
59
|
async start(controller) {
|
|
56
|
-
const resolved = await str.toString();
|
|
60
|
+
const resolved = str instanceof Promise ? await str : await str.toString();
|
|
57
61
|
controller.enqueue(textEncoder.encode(resolved));
|
|
58
|
-
let
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
controller.
|
|
72
|
-
}
|
|
73
|
-
|
|
62
|
+
let resolvedCount = 0;
|
|
63
|
+
const promises = [];
|
|
64
|
+
const then = (promise) => {
|
|
65
|
+
promises.push(
|
|
66
|
+
promise.catch((err) => {
|
|
67
|
+
console.trace(err);
|
|
68
|
+
return "";
|
|
69
|
+
}).then((res) => {
|
|
70
|
+
if (res.promises) {
|
|
71
|
+
const resPromises = res.promises || [];
|
|
72
|
+
resPromises.forEach(then);
|
|
73
|
+
}
|
|
74
|
+
resolvedCount++;
|
|
75
|
+
controller.enqueue(textEncoder.encode(res));
|
|
76
|
+
})
|
|
77
|
+
);
|
|
78
|
+
};
|
|
79
|
+
resolved.promises?.map(then);
|
|
80
|
+
while (resolvedCount !== promises.length) {
|
|
81
|
+
await Promise.all(promises);
|
|
74
82
|
}
|
|
83
|
+
controller.close();
|
|
75
84
|
}
|
|
76
85
|
});
|
|
77
86
|
return reader;
|
|
@@ -1,15 +1,25 @@
|
|
|
1
1
|
// src/middleware/jsx-renderer/index.ts
|
|
2
|
+
import { html, raw } from "../../helper/html/index.js";
|
|
2
3
|
import { jsx, createContext, useContext } from "../../jsx/index.js";
|
|
4
|
+
import { renderToReadableStream } from "../../jsx/streaming.js";
|
|
3
5
|
var RequestContext = createContext(null);
|
|
4
6
|
var createRenderer = (c, component, options) => (children, props) => {
|
|
5
7
|
const docType = typeof options?.docType === "string" ? options.docType : options?.docType === true ? "<!DOCTYPE html>" : "";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
const body = html`${raw(docType)}${jsx(
|
|
9
|
+
RequestContext.Provider,
|
|
10
|
+
{ value: c },
|
|
11
|
+
component ? component({ children, ...props || {} }) : children
|
|
12
|
+
)}`;
|
|
13
|
+
if (options?.stream) {
|
|
14
|
+
return c.body(renderToReadableStream(body), {
|
|
15
|
+
headers: options.stream === true ? {
|
|
16
|
+
"Transfer-Encoding": "chunked",
|
|
17
|
+
"Content-Type": "text/html; charset=UTF-8"
|
|
18
|
+
} : options.stream
|
|
19
|
+
});
|
|
20
|
+
} else {
|
|
21
|
+
return c.html(body);
|
|
22
|
+
}
|
|
13
23
|
};
|
|
14
24
|
var jsxRenderer = (component, options) => (c, next) => {
|
|
15
25
|
c.setRenderer(createRenderer(c, component, options));
|
package/dist/types/context.d.ts
CHANGED
|
@@ -91,7 +91,7 @@ export declare class Context<E extends Env = any, P extends string = any, I exte
|
|
|
91
91
|
status: (status: StatusCode) => void;
|
|
92
92
|
set: Set<E>;
|
|
93
93
|
get: Get<E>;
|
|
94
|
-
get var(): Readonly<E['Variables']>;
|
|
94
|
+
get var(): Readonly<E['Variables'] & ContextVariableMap>;
|
|
95
95
|
newResponse: NewResponse;
|
|
96
96
|
body: BodyRespond;
|
|
97
97
|
text: TextRespond;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { Context } from '../../context';
|
|
2
2
|
export declare type Runtime = 'node' | 'deno' | 'bun' | 'workerd' | 'fastly' | 'edge-light' | 'lagon' | 'other';
|
|
3
|
-
export declare const env: <T extends Record<string,
|
|
3
|
+
export declare const env: <T extends Record<string, unknown>, C extends Context<any, any, {}> = Context<{}, any, {}>>(c: C, runtime?: Runtime) => T & C["env"];
|
|
4
4
|
export declare const getRuntimeKey: () => "other" | "node" | "deno" | "bun" | "workerd" | "fastly" | "edge-light" | "lagon";
|
|
@@ -1,7 +1,2 @@
|
|
|
1
1
|
import type { Env, Input, MiddlewareHandler } from '../../types';
|
|
2
|
-
/**
|
|
3
|
-
* @experimental
|
|
4
|
-
* `createMiddleware()` is an experimental feature.
|
|
5
|
-
* The API might be changed.
|
|
6
|
-
*/
|
|
7
2
|
export declare const createMiddleware: <E extends Env = any, P extends string = any, I extends Input = {}>(middleware: MiddlewareHandler<E, P, I>) => MiddlewareHandler<E, P, I>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { HtmlEscapedString } from '../../utils/html';
|
|
2
|
-
export declare const raw: (value: unknown) => HtmlEscapedString;
|
|
2
|
+
export declare const raw: (value: unknown, promises?: Promise<string>[]) => HtmlEscapedString;
|
|
3
3
|
export declare const html: (strings: TemplateStringsArray, ...values: unknown[]) => HtmlEscapedString | Promise<HtmlEscapedString>;
|
|
@@ -43,11 +43,6 @@ declare class Hono<E extends Env = Env, S extends Schema = {}, BasePath extends
|
|
|
43
43
|
onError(handler: ErrorHandler<E>): this;
|
|
44
44
|
notFound(handler: NotFoundHandler<E>): this;
|
|
45
45
|
showRoutes(): void;
|
|
46
|
-
/**
|
|
47
|
-
* @experimental
|
|
48
|
-
* `app.mount()` is an experimental feature.
|
|
49
|
-
* The API might be changed.
|
|
50
|
-
*/
|
|
51
46
|
mount(path: string, applicationHandler: (request: Request, ...args: any) => Response | Promise<Response>, optionHandler?: (c: Context) => unknown): Hono<E, S, BasePath>;
|
|
52
47
|
get routerName(): string;
|
|
53
48
|
/**
|
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
export { jsxDEV as jsx, Fragment } from './jsx-dev-runtime';
|
|
2
2
|
export { jsxDEV as jsxs } from './jsx-dev-runtime';
|
|
3
|
+
import { html } from '../helper/html';
|
|
4
|
+
export { html as jsxTemplate };
|
|
5
|
+
export declare const jsxAttr: (name: string, value: string) => import("../utils/html").HtmlEscapedString;
|
|
6
|
+
export declare const jsxEscape: (value: string) => string;
|
|
@@ -5,6 +5,7 @@ export declare const RequestContext: import("../../jsx").Context<Context<any, an
|
|
|
5
5
|
declare type PropsForRenderer = [...Required<Parameters<Renderer>>] extends [unknown, infer Props] ? Props : unknown;
|
|
6
6
|
declare type RendererOptions = {
|
|
7
7
|
docType?: boolean | string;
|
|
8
|
+
stream?: boolean | Record<string, string>;
|
|
8
9
|
};
|
|
9
10
|
export declare const jsxRenderer: (component?: FC<PropsForRenderer>, options?: RendererOptions) => MiddlewareHandler;
|
|
10
11
|
export declare const useRequestContext: <E extends Env = any, P extends string = any, I extends Input = {}>() => Context<E, P, I>;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -22,39 +22,39 @@ export declare type H<E extends Env = any, P extends string = any, I extends Inp
|
|
|
22
22
|
export declare type NotFoundHandler<E extends Env = any> = (c: Context<E>) => Response | Promise<Response>;
|
|
23
23
|
export declare type ErrorHandler<E extends Env = any> = (err: Error, c: Context<E>) => Response | Promise<Response>;
|
|
24
24
|
export interface HandlerInterface<E extends Env = Env, M extends string = string, S extends Schema = {}, BasePath extends string = '/'> {
|
|
25
|
-
<P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, I extends Input = {}, R extends HandlerResponse<any> = any, E2 extends Env = E>(handler: H<E2, P, I, R>): Hono<E, S & ToSchema<M, P, I['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
26
|
-
<P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, I extends Input = {}, R extends HandlerResponse<any> = any, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>>(...handlers: [H<E2, P, I, R>, H<E3, P, I, R>]): Hono<E, S & ToSchema<M, P, I['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
27
|
-
<P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, R extends HandlerResponse<any> = any, I extends Input = {}, 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, R>, H<E3, P, I2, R>, H<E4, P, I3, R>]): Hono<E, S & ToSchema<M, P, I3['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
28
|
-
<P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, R extends HandlerResponse<any> = any, I extends Input = {}, 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, R>, H<E3, P, I2, R>, H<E4, P, I3, R>, H<E5, P, I3, R>]): Hono<E, S & ToSchema<M, P, I4['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
25
|
+
<P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, I extends Input = {}, R extends HandlerResponse<any> = any, E2 extends Env = E>(handler: H<E2, P, I, R>): Hono<E & E2, S & ToSchema<M, P, I['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
26
|
+
<P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, I extends Input = {}, R extends HandlerResponse<any> = any, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>>(...handlers: [H<E2, P, I, R>, H<E3, P, I, R>]): Hono<E & E2 & E3, S & ToSchema<M, P, I['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
27
|
+
<P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, R extends HandlerResponse<any> = any, I extends Input = {}, 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, R>, H<E3, P, I2, R>, H<E4, P, I3, R>]): Hono<E & E2 & E3 & E4, S & ToSchema<M, P, I3['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
28
|
+
<P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, R extends HandlerResponse<any> = any, I extends Input = {}, 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, R>, H<E3, P, I2, R>, H<E4, P, I3, R>, H<E5, P, I3, R>]): Hono<E & E2 & E3 & E4 & E5, S & ToSchema<M, P, I4['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
29
29
|
<P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, R extends HandlerResponse<any> = any, I extends Input = {}, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = 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: [
|
|
30
30
|
H<E2, P, I, R>,
|
|
31
31
|
H<E3, P, I2, R>,
|
|
32
32
|
H<E4, P, I3, R>,
|
|
33
33
|
H<E5, P, I3, R>,
|
|
34
34
|
H<E6, P, I3, R>
|
|
35
|
-
]): Hono<E, S & ToSchema<M, P, I5['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
35
|
+
]): Hono<E & E2 & E3 & E4 & E5 & E6, S & ToSchema<M, P, I5['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
36
36
|
<P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, I extends Input = {}, R extends HandlerResponse<any> = any>(...handlers: H<E, P, I, R>[]): Hono<E, S & ToSchema<M, P, I['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
37
37
|
<P extends string, R extends HandlerResponse<any> = any, I extends Input = {}>(path: P): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
38
|
-
<P extends string, P2 extends string = P, R extends HandlerResponse<any> = any, I extends Input = {}, E2 extends Env = E>(path: P, handler: H<E2, MergePath<BasePath, P2>, I, R>): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
39
|
-
<P extends string, P2 extends string = P, P3 extends string = P, R extends HandlerResponse<any> = any, I extends Input = {}, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>>(path: P, ...handlers: [H<E2, MergePath<BasePath, P2>, I, R>, H<E3, MergePath<BasePath, P3>, I, R>]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
38
|
+
<P extends string, P2 extends string = P, R extends HandlerResponse<any> = any, I extends Input = {}, E2 extends Env = E>(path: P, handler: H<E2, MergePath<BasePath, P2>, I, R>): Hono<E & E2, S & ToSchema<M, MergePath<BasePath, P>, I['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
39
|
+
<P extends string, P2 extends string = P, P3 extends string = P, R extends HandlerResponse<any> = any, I extends Input = {}, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>>(path: P, ...handlers: [H<E2, MergePath<BasePath, P2>, I, R>, H<E3, MergePath<BasePath, P3>, I, R>]): Hono<E & E2 & E3, S & ToSchema<M, MergePath<BasePath, P>, I['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
40
40
|
<P extends string, P2 extends string = P, P3 extends string = P, P4 extends string = P, R extends HandlerResponse<any> = any, I extends Input = {}, 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: [
|
|
41
41
|
H<E2, MergePath<BasePath, P2>, I, R>,
|
|
42
42
|
H<E3, MergePath<BasePath, P3>, I2, R>,
|
|
43
43
|
H<E4, MergePath<BasePath, P4>, I3, R>
|
|
44
|
-
]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I3['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
44
|
+
]): Hono<E & E2 & E3 & E4, S & ToSchema<M, MergePath<BasePath, P>, I3['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
45
45
|
<P extends string, P2 extends string = P, P3 extends string = P, P4 extends string = P, P5 extends string = P, R extends HandlerResponse<any> = any, I extends Input = {}, 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: [
|
|
46
46
|
H<E2, MergePath<BasePath, P2>, I, R>,
|
|
47
47
|
H<E3, MergePath<BasePath, P3>, I2, R>,
|
|
48
48
|
H<E4, MergePath<BasePath, P4>, I3, R>,
|
|
49
49
|
H<E5, MergePath<BasePath, P5>, I4, R>
|
|
50
|
-
]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I4['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
50
|
+
]): Hono<E & E2 & E3 & E4 & E5, S & ToSchema<M, MergePath<BasePath, P>, I4['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
51
51
|
<P extends string, P2 extends string = P, P3 extends string = P, P4 extends string = P, P5 extends string = P, P6 extends string = P, R extends HandlerResponse<any> = any, I extends Input = {}, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = 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: [
|
|
52
52
|
H<E2, MergePath<BasePath, P2>, I, R>,
|
|
53
53
|
H<E3, MergePath<BasePath, P3>, I2, R>,
|
|
54
54
|
H<E4, MergePath<BasePath, P4>, I3, R>,
|
|
55
55
|
H<E5, MergePath<BasePath, P5>, I4, R>,
|
|
56
56
|
H<E6, MergePath<BasePath, P6>, I5, R>
|
|
57
|
-
]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I5['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
57
|
+
]): Hono<E & E2 & E3 & E4 & E5 & E6, S & ToSchema<M, MergePath<BasePath, P>, I5['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
58
58
|
<P extends string, I extends Input = {}, R extends HandlerResponse<any> = any>(path: P, ...handlers: H<E, MergePath<BasePath, P>, I, R>[]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
59
59
|
}
|
|
60
60
|
export interface MiddlewareHandlerInterface<E extends Env = Env, S extends Schema = {}, BasePath extends string = '/'> {
|
package/dist/utils/html.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// src/utils/html.ts
|
|
2
|
+
import { raw } from "../helper/html/index.js";
|
|
2
3
|
var escapeRe = /[&<>'"]/;
|
|
3
4
|
var stringBufferToString = async (buffer) => {
|
|
4
5
|
let str = "";
|
|
@@ -14,10 +15,7 @@ var stringBufferToString = async (buffer) => {
|
|
|
14
15
|
}
|
|
15
16
|
str += r;
|
|
16
17
|
}
|
|
17
|
-
|
|
18
|
-
res.isEscaped = true;
|
|
19
|
-
res.promises = promises;
|
|
20
|
-
return res;
|
|
18
|
+
return raw(str, promises);
|
|
21
19
|
};
|
|
22
20
|
var escapeToBuffer = (str, buffer) => {
|
|
23
21
|
const match = str.search(escapeRe);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hono",
|
|
3
|
-
"version": "3.10.0
|
|
3
|
+
"version": "3.10.0",
|
|
4
4
|
"description": "Ultrafast web framework for the Edges",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
],
|
|
12
12
|
"scripts": {
|
|
13
13
|
"test": "tsc --noEmit && vitest --run",
|
|
14
|
-
"test:deno": "env NAME=Deno deno test --allow-read --allow-env runtime_tests/deno",
|
|
14
|
+
"test:deno": "env NAME=Deno deno test --allow-read --allow-env 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
15
|
"test:bun": "env NAME=Bun bun test --jsx-import-source ../../src/jsx runtime_tests/bun/index.test.tsx",
|
|
16
16
|
"test:fastly": "jest --config ./runtime_tests/fastly/jest.config.js",
|
|
17
17
|
"test:lagon": "start-server-and-test \"lagon dev runtime_tests/lagon/index.ts -e runtime_tests/lagon/.env.lagon\" http://127.0.0.1:1234 \"yarn vitest --run runtime_tests/lagon/index.test.ts --config runtime_tests/lagon/vitest.config.ts\"",
|