hono 3.7.3 → 3.8.0-rc.1
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/adapter/vercel/handler.js +1 -10
- package/dist/cjs/adapter/vercel/handler.js +1 -10
- package/dist/cjs/context.js +1 -2
- package/dist/cjs/helper/factory/index.js +3 -3
- package/dist/cjs/helper/streaming/index.js +61 -0
- package/dist/cjs/helper.js +2 -1
- package/dist/cjs/hono-base.js +1 -1
- package/dist/cjs/jsx/index.js +25 -3
- package/dist/cjs/middleware/jsx-renderer/index.js +51 -0
- package/dist/cjs/request.js +2 -2
- package/dist/cjs/utils/body.js +19 -11
- package/dist/context.js +1 -2
- package/dist/helper/factory/index.js +2 -2
- package/dist/helper/streaming/index.js +38 -0
- package/dist/helper.js +2 -1
- package/dist/hono-base.js +1 -1
- package/dist/jsx/index.js +22 -2
- package/dist/middleware/jsx-renderer/index.js +26 -0
- package/dist/request.js +2 -2
- package/dist/types/adapter/vercel/handler.d.ts +1 -1
- package/dist/types/context.d.ts +5 -4
- package/dist/types/helper/factory/index.d.ts +1 -1
- package/dist/types/helper/streaming/index.d.ts +13 -0
- package/dist/types/helper.d.ts +2 -1
- package/dist/types/hono-base.d.ts +1 -1
- package/dist/types/jsx/index.d.ts +9 -1
- package/dist/types/middleware/jsx-renderer/index.d.ts +8 -0
- package/dist/types/request.d.ts +2 -2
- package/dist/types/utils/body.d.ts +22 -2
- package/dist/utils/body.js +19 -11
- package/package.json +11 -3
|
@@ -1,15 +1,6 @@
|
|
|
1
1
|
// src/adapter/vercel/handler.ts
|
|
2
2
|
var handle = (app) => (req, requestContext) => {
|
|
3
|
-
return app.fetch(
|
|
4
|
-
req,
|
|
5
|
-
{},
|
|
6
|
-
{
|
|
7
|
-
waitUntil: requestContext?.waitUntil,
|
|
8
|
-
passThroughOnException: () => {
|
|
9
|
-
throw new Error("`passThroughOnException` is not implemented in the Vercel");
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
);
|
|
3
|
+
return app.fetch(req, {}, requestContext);
|
|
13
4
|
};
|
|
14
5
|
export {
|
|
15
6
|
handle
|
|
@@ -22,16 +22,7 @@ __export(handler_exports, {
|
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(handler_exports);
|
|
24
24
|
const handle = (app) => (req, requestContext) => {
|
|
25
|
-
return app.fetch(
|
|
26
|
-
req,
|
|
27
|
-
{},
|
|
28
|
-
{
|
|
29
|
-
waitUntil: requestContext?.waitUntil,
|
|
30
|
-
passThroughOnException: () => {
|
|
31
|
-
throw new Error("`passThroughOnException` is not implemented in the Vercel");
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
);
|
|
25
|
+
return app.fetch(req, {}, requestContext);
|
|
35
26
|
};
|
|
36
27
|
// Annotate the CommonJS export names for ESM import in node:
|
|
37
28
|
0 && (module.exports = {
|
package/dist/cjs/context.js
CHANGED
|
@@ -21,7 +21,6 @@ __export(context_exports, {
|
|
|
21
21
|
Context: () => Context
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(context_exports);
|
|
24
|
-
var import_types = require("./types");
|
|
25
24
|
var import_cookie = require("./utils/cookie");
|
|
26
25
|
var import_stream = require("./utils/stream");
|
|
27
26
|
const TEXT_PLAIN = "text/plain; charset=UTF-8";
|
|
@@ -200,7 +199,7 @@ class Context {
|
|
|
200
199
|
}
|
|
201
200
|
}
|
|
202
201
|
get event() {
|
|
203
|
-
if (this._exCtx instanceof
|
|
202
|
+
if (this._exCtx instanceof FetchEvent) {
|
|
204
203
|
return this._exCtx;
|
|
205
204
|
} else {
|
|
206
205
|
throw Error("This context has no FetchEvent");
|
|
@@ -18,11 +18,11 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var factory_exports = {};
|
|
20
20
|
__export(factory_exports, {
|
|
21
|
-
|
|
21
|
+
createMiddleware: () => createMiddleware
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(factory_exports);
|
|
24
|
-
const
|
|
24
|
+
const createMiddleware = (middleware) => middleware;
|
|
25
25
|
// Annotate the CommonJS export names for ESM import in node:
|
|
26
26
|
0 && (module.exports = {
|
|
27
|
-
|
|
27
|
+
createMiddleware
|
|
28
28
|
});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var streaming_exports = {};
|
|
20
|
+
__export(streaming_exports, {
|
|
21
|
+
streamSSE: () => streamSSE
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(streaming_exports);
|
|
24
|
+
var import_stream = require("../../utils/stream");
|
|
25
|
+
class SSEStreamingApi extends import_stream.StreamingApi {
|
|
26
|
+
constructor(writable) {
|
|
27
|
+
super(writable);
|
|
28
|
+
}
|
|
29
|
+
async writeSSE(message) {
|
|
30
|
+
const sseData = [
|
|
31
|
+
message.event && `event: ${message.event}`,
|
|
32
|
+
message.id && `id: ${message.id}`,
|
|
33
|
+
`data: ${message.data}`
|
|
34
|
+
].filter(Boolean).join("\n") + "\n";
|
|
35
|
+
await this.write(sseData);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const setSSEHeaders = (context) => {
|
|
39
|
+
context.header("Transfer-Encoding", "chunked");
|
|
40
|
+
context.header("Content-Type", "text/event-stream");
|
|
41
|
+
context.header("Cache-Control", "no-cache");
|
|
42
|
+
context.header("Connection", "keep-alive");
|
|
43
|
+
};
|
|
44
|
+
const streamSSE = (c, cb) => {
|
|
45
|
+
return c.stream(async (originalStream) => {
|
|
46
|
+
const { readable, writable } = new TransformStream();
|
|
47
|
+
const stream = new SSEStreamingApi(writable);
|
|
48
|
+
originalStream.pipe(readable);
|
|
49
|
+
setSSEHeaders(c);
|
|
50
|
+
try {
|
|
51
|
+
await cb(stream);
|
|
52
|
+
} catch (err) {
|
|
53
|
+
console.error("Error during streaming: ", err);
|
|
54
|
+
stream.close();
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
59
|
+
0 && (module.exports = {
|
|
60
|
+
streamSSE
|
|
61
|
+
});
|
package/dist/cjs/helper.js
CHANGED
|
@@ -15,7 +15,8 @@ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "defau
|
|
|
15
15
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
16
16
|
var helper_exports = {};
|
|
17
17
|
module.exports = __toCommonJS(helper_exports);
|
|
18
|
+
__reExport(helper_exports, require("./helper/adapter"), module.exports);
|
|
18
19
|
__reExport(helper_exports, require("./helper/cookie"), module.exports);
|
|
19
20
|
__reExport(helper_exports, require("./helper/html"), module.exports);
|
|
20
|
-
__reExport(helper_exports, require("./helper/
|
|
21
|
+
__reExport(helper_exports, require("./helper/streaming"), module.exports);
|
|
21
22
|
__reExport(helper_exports, require("./helper/testing"), module.exports);
|
package/dist/cjs/hono-base.js
CHANGED
|
@@ -209,10 +209,10 @@ class Hono extends defineDynamicClass() {
|
|
|
209
209
|
throw err;
|
|
210
210
|
}
|
|
211
211
|
dispatch(request, executionCtx, env, method) {
|
|
212
|
-
const path = this.getPath(request, { env });
|
|
213
212
|
if (method === "HEAD") {
|
|
214
213
|
return (async () => new Response(null, await this.dispatch(request, executionCtx, env, "GET")))();
|
|
215
214
|
}
|
|
215
|
+
const path = this.getPath(request, { env });
|
|
216
216
|
const { handlers, params } = this.matchRoute(method, path);
|
|
217
217
|
const c = new import_context.Context(new import_request.HonoRequest(request, path, params), {
|
|
218
218
|
env,
|
package/dist/cjs/jsx/index.js
CHANGED
|
@@ -20,8 +20,10 @@ var jsx_exports = {};
|
|
|
20
20
|
__export(jsx_exports, {
|
|
21
21
|
Fragment: () => Fragment,
|
|
22
22
|
JSXNode: () => JSXNode,
|
|
23
|
+
createContext: () => createContext,
|
|
23
24
|
jsx: () => jsxFn,
|
|
24
|
-
memo: () => memo
|
|
25
|
+
memo: () => memo,
|
|
26
|
+
useContext: () => useContext
|
|
25
27
|
});
|
|
26
28
|
module.exports = __toCommonJS(jsx_exports);
|
|
27
29
|
var import_html = require("../utils/html");
|
|
@@ -198,12 +200,32 @@ const memo = (component, propsAreEqual = shallowEqual) => {
|
|
|
198
200
|
};
|
|
199
201
|
};
|
|
200
202
|
const Fragment = (props) => {
|
|
201
|
-
return new JSXFragmentNode("", {}, props.children
|
|
203
|
+
return new JSXFragmentNode("", {}, props.children ? [props.children] : []);
|
|
204
|
+
};
|
|
205
|
+
const createContext = (defaultValue) => {
|
|
206
|
+
const values = [defaultValue];
|
|
207
|
+
return {
|
|
208
|
+
values,
|
|
209
|
+
Provider(props) {
|
|
210
|
+
values.push(props.value);
|
|
211
|
+
const res = new String(
|
|
212
|
+
props.children ? (Array.isArray(props.children) ? new JSXFragmentNode("", {}, props.children) : props.children).toString() : ""
|
|
213
|
+
);
|
|
214
|
+
res.isEscaped = true;
|
|
215
|
+
values.pop();
|
|
216
|
+
return res;
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
};
|
|
220
|
+
const useContext = (context) => {
|
|
221
|
+
return context.values[context.values.length - 1];
|
|
202
222
|
};
|
|
203
223
|
// Annotate the CommonJS export names for ESM import in node:
|
|
204
224
|
0 && (module.exports = {
|
|
205
225
|
Fragment,
|
|
206
226
|
JSXNode,
|
|
227
|
+
createContext,
|
|
207
228
|
jsx,
|
|
208
|
-
memo
|
|
229
|
+
memo,
|
|
230
|
+
useContext
|
|
209
231
|
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var jsx_renderer_exports = {};
|
|
20
|
+
__export(jsx_renderer_exports, {
|
|
21
|
+
RequestContext: () => RequestContext,
|
|
22
|
+
jsxRenderer: () => jsxRenderer,
|
|
23
|
+
useRequestContext: () => useRequestContext
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(jsx_renderer_exports);
|
|
26
|
+
var import_jsx = require("../../jsx");
|
|
27
|
+
const RequestContext = (0, import_jsx.createContext)(null);
|
|
28
|
+
const createRenderer = (c, component) => (children, props) => c.html(
|
|
29
|
+
(0, import_jsx.jsx)(
|
|
30
|
+
RequestContext.Provider,
|
|
31
|
+
{ value: c },
|
|
32
|
+
component ? component({ children, ...props || {} }) : children
|
|
33
|
+
)
|
|
34
|
+
);
|
|
35
|
+
const jsxRenderer = (component) => (c, next) => {
|
|
36
|
+
c.setRenderer(createRenderer(c, component));
|
|
37
|
+
return next();
|
|
38
|
+
};
|
|
39
|
+
const useRequestContext = () => {
|
|
40
|
+
const c = (0, import_jsx.useContext)(RequestContext);
|
|
41
|
+
if (!c) {
|
|
42
|
+
throw new Error("RequestContext is not provided.");
|
|
43
|
+
}
|
|
44
|
+
return c;
|
|
45
|
+
};
|
|
46
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
47
|
+
0 && (module.exports = {
|
|
48
|
+
RequestContext,
|
|
49
|
+
jsxRenderer,
|
|
50
|
+
useRequestContext
|
|
51
|
+
});
|
package/dist/cjs/request.js
CHANGED
|
@@ -88,10 +88,10 @@ class HonoRequest {
|
|
|
88
88
|
return obj;
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
|
-
async parseBody() {
|
|
91
|
+
async parseBody(options) {
|
|
92
92
|
if (this.bodyCache.parsedBody)
|
|
93
93
|
return this.bodyCache.parsedBody;
|
|
94
|
-
const parsedBody = await (0, import_body.parseBody)(this);
|
|
94
|
+
const parsedBody = await (0, import_body.parseBody)(this, options);
|
|
95
95
|
this.bodyCache.parsedBody = parsedBody;
|
|
96
96
|
return parsedBody;
|
|
97
97
|
}
|
package/dist/cjs/utils/body.js
CHANGED
|
@@ -21,7 +21,12 @@ __export(body_exports, {
|
|
|
21
21
|
parseBody: () => parseBody
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(body_exports);
|
|
24
|
-
const
|
|
24
|
+
const isArrayField = (value) => {
|
|
25
|
+
return Array.isArray(value);
|
|
26
|
+
};
|
|
27
|
+
const parseBody = async (request, options = {
|
|
28
|
+
all: false
|
|
29
|
+
}) => {
|
|
25
30
|
let body = {};
|
|
26
31
|
const contentType = request.headers.get("Content-Type");
|
|
27
32
|
if (contentType && (contentType.startsWith("multipart/form-data") || contentType.startsWith("application/x-www-form-urlencoded"))) {
|
|
@@ -29,18 +34,21 @@ const parseBody = async (request) => {
|
|
|
29
34
|
if (formData) {
|
|
30
35
|
const form = {};
|
|
31
36
|
formData.forEach((value, key) => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
form[key] = [value.toString()];
|
|
35
|
-
} else {
|
|
36
|
-
if (Array.isArray(form[key])) {
|
|
37
|
-
;
|
|
38
|
-
form[key].push(value.toString());
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
} else {
|
|
37
|
+
const shouldParseAllValues = options.all || key.slice(-2) === "[]";
|
|
38
|
+
if (!shouldParseAllValues) {
|
|
42
39
|
form[key] = value;
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (form[key] && isArrayField(form[key])) {
|
|
43
|
+
;
|
|
44
|
+
form[key].push(value);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (form[key]) {
|
|
48
|
+
form[key] = [form[key], value];
|
|
49
|
+
return;
|
|
43
50
|
}
|
|
51
|
+
form[key] = value;
|
|
44
52
|
});
|
|
45
53
|
body = form;
|
|
46
54
|
}
|
package/dist/context.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
// src/context.ts
|
|
2
|
-
import { FetchEventLike } from "./types.js";
|
|
3
2
|
import { serialize } from "./utils/cookie.js";
|
|
4
3
|
import { StreamingApi } from "./utils/stream.js";
|
|
5
4
|
var TEXT_PLAIN = "text/plain; charset=UTF-8";
|
|
@@ -178,7 +177,7 @@ var Context = class {
|
|
|
178
177
|
}
|
|
179
178
|
}
|
|
180
179
|
get event() {
|
|
181
|
-
if (this._exCtx instanceof
|
|
180
|
+
if (this._exCtx instanceof FetchEvent) {
|
|
182
181
|
return this._exCtx;
|
|
183
182
|
} else {
|
|
184
183
|
throw Error("This context has no FetchEvent");
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// src/helper/streaming/index.ts
|
|
2
|
+
import { StreamingApi } from "../../utils/stream.js";
|
|
3
|
+
var SSEStreamingApi = class extends StreamingApi {
|
|
4
|
+
constructor(writable) {
|
|
5
|
+
super(writable);
|
|
6
|
+
}
|
|
7
|
+
async writeSSE(message) {
|
|
8
|
+
const sseData = [
|
|
9
|
+
message.event && `event: ${message.event}`,
|
|
10
|
+
message.id && `id: ${message.id}`,
|
|
11
|
+
`data: ${message.data}`
|
|
12
|
+
].filter(Boolean).join("\n") + "\n";
|
|
13
|
+
await this.write(sseData);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
var setSSEHeaders = (context) => {
|
|
17
|
+
context.header("Transfer-Encoding", "chunked");
|
|
18
|
+
context.header("Content-Type", "text/event-stream");
|
|
19
|
+
context.header("Cache-Control", "no-cache");
|
|
20
|
+
context.header("Connection", "keep-alive");
|
|
21
|
+
};
|
|
22
|
+
var streamSSE = (c, cb) => {
|
|
23
|
+
return c.stream(async (originalStream) => {
|
|
24
|
+
const { readable, writable } = new TransformStream();
|
|
25
|
+
const stream = new SSEStreamingApi(writable);
|
|
26
|
+
originalStream.pipe(readable);
|
|
27
|
+
setSSEHeaders(c);
|
|
28
|
+
try {
|
|
29
|
+
await cb(stream);
|
|
30
|
+
} catch (err) {
|
|
31
|
+
console.error("Error during streaming: ", err);
|
|
32
|
+
stream.close();
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
export {
|
|
37
|
+
streamSSE
|
|
38
|
+
};
|
package/dist/helper.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// src/helper.ts
|
|
2
|
+
export * from "./helper/adapter/index.js";
|
|
2
3
|
export * from "./helper/cookie/index.js";
|
|
3
4
|
export * from "./helper/html/index.js";
|
|
4
|
-
export * from "./helper/
|
|
5
|
+
export * from "./helper/streaming/index.js";
|
|
5
6
|
export * from "./helper/testing/index.js";
|
package/dist/hono-base.js
CHANGED
|
@@ -187,10 +187,10 @@ var Hono = class extends defineDynamicClass() {
|
|
|
187
187
|
throw err;
|
|
188
188
|
}
|
|
189
189
|
dispatch(request, executionCtx, env, method) {
|
|
190
|
-
const path = this.getPath(request, { env });
|
|
191
190
|
if (method === "HEAD") {
|
|
192
191
|
return (async () => new Response(null, await this.dispatch(request, executionCtx, env, "GET")))();
|
|
193
192
|
}
|
|
193
|
+
const path = this.getPath(request, { env });
|
|
194
194
|
const { handlers, params } = this.matchRoute(method, path);
|
|
195
195
|
const c = new Context(new HonoRequest(request, path, params), {
|
|
196
196
|
env,
|
package/dist/jsx/index.js
CHANGED
|
@@ -173,11 +173,31 @@ var memo = (component, propsAreEqual = shallowEqual) => {
|
|
|
173
173
|
};
|
|
174
174
|
};
|
|
175
175
|
var Fragment = (props) => {
|
|
176
|
-
return new JSXFragmentNode("", {}, props.children
|
|
176
|
+
return new JSXFragmentNode("", {}, props.children ? [props.children] : []);
|
|
177
|
+
};
|
|
178
|
+
var createContext = (defaultValue) => {
|
|
179
|
+
const values = [defaultValue];
|
|
180
|
+
return {
|
|
181
|
+
values,
|
|
182
|
+
Provider(props) {
|
|
183
|
+
values.push(props.value);
|
|
184
|
+
const res = new String(
|
|
185
|
+
props.children ? (Array.isArray(props.children) ? new JSXFragmentNode("", {}, props.children) : props.children).toString() : ""
|
|
186
|
+
);
|
|
187
|
+
res.isEscaped = true;
|
|
188
|
+
values.pop();
|
|
189
|
+
return res;
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
};
|
|
193
|
+
var useContext = (context) => {
|
|
194
|
+
return context.values[context.values.length - 1];
|
|
177
195
|
};
|
|
178
196
|
export {
|
|
179
197
|
Fragment,
|
|
180
198
|
JSXNode,
|
|
199
|
+
createContext,
|
|
181
200
|
jsxFn as jsx,
|
|
182
|
-
memo
|
|
201
|
+
memo,
|
|
202
|
+
useContext
|
|
183
203
|
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// src/middleware/jsx-renderer/index.ts
|
|
2
|
+
import { jsx, createContext, useContext } from "../../jsx/index.js";
|
|
3
|
+
var RequestContext = createContext(null);
|
|
4
|
+
var createRenderer = (c, component) => (children, props) => c.html(
|
|
5
|
+
jsx(
|
|
6
|
+
RequestContext.Provider,
|
|
7
|
+
{ value: c },
|
|
8
|
+
component ? component({ children, ...props || {} }) : children
|
|
9
|
+
)
|
|
10
|
+
);
|
|
11
|
+
var jsxRenderer = (component) => (c, next) => {
|
|
12
|
+
c.setRenderer(createRenderer(c, component));
|
|
13
|
+
return next();
|
|
14
|
+
};
|
|
15
|
+
var useRequestContext = () => {
|
|
16
|
+
const c = useContext(RequestContext);
|
|
17
|
+
if (!c) {
|
|
18
|
+
throw new Error("RequestContext is not provided.");
|
|
19
|
+
}
|
|
20
|
+
return c;
|
|
21
|
+
};
|
|
22
|
+
export {
|
|
23
|
+
RequestContext,
|
|
24
|
+
jsxRenderer,
|
|
25
|
+
useRequestContext
|
|
26
|
+
};
|
package/dist/request.js
CHANGED
|
@@ -66,10 +66,10 @@ var HonoRequest = class {
|
|
|
66
66
|
return obj;
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
|
-
async parseBody() {
|
|
69
|
+
async parseBody(options) {
|
|
70
70
|
if (this.bodyCache.parsedBody)
|
|
71
71
|
return this.bodyCache.parsedBody;
|
|
72
|
-
const parsedBody = await parseBody(this);
|
|
72
|
+
const parsedBody = await parseBody(this, options);
|
|
73
73
|
this.bodyCache.parsedBody = parsedBody;
|
|
74
74
|
return parsedBody;
|
|
75
75
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { Hono } from '../../hono';
|
|
2
|
-
export declare const handle: (app: Hono<any, any, any>) => (req: Request, requestContext:
|
|
2
|
+
export declare const handle: (app: Hono<any, any, any>) => (req: Request, requestContext: FetchEvent) => Response | Promise<Response>;
|
package/dist/types/context.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
/// <reference lib="es2022" />
|
|
2
|
+
/// <reference lib="webworker" />
|
|
1
3
|
import type { HonoRequest } from './request';
|
|
2
|
-
import { FetchEventLike } from './types';
|
|
3
4
|
import type { Env, NotFoundHandler, Input, TypedResponse } from './types';
|
|
4
5
|
import type { CookieOptions } from './utils/cookie';
|
|
5
6
|
import type { StatusCode } from './utils/http-status';
|
|
@@ -19,7 +20,7 @@ export interface ContextRenderer {
|
|
|
19
20
|
interface DefaultRenderer {
|
|
20
21
|
(content: string): Response | Promise<Response>;
|
|
21
22
|
}
|
|
22
|
-
declare type Renderer = ContextRenderer extends Function ? ContextRenderer : DefaultRenderer;
|
|
23
|
+
export declare type Renderer = ContextRenderer extends Function ? ContextRenderer : DefaultRenderer;
|
|
23
24
|
interface Get<E extends Env> {
|
|
24
25
|
<Key extends keyof ContextVariableMap>(key: Key): ContextVariableMap[Key];
|
|
25
26
|
<Key extends keyof E['Variables']>(key: Key): E['Variables'][Key];
|
|
@@ -52,7 +53,7 @@ interface HTMLRespond {
|
|
|
52
53
|
}
|
|
53
54
|
declare type ContextOptions<E extends Env> = {
|
|
54
55
|
env: E['Bindings'];
|
|
55
|
-
executionCtx?:
|
|
56
|
+
executionCtx?: FetchEvent | ExecutionContext | undefined;
|
|
56
57
|
notFoundHandler?: NotFoundHandler<E>;
|
|
57
58
|
};
|
|
58
59
|
export declare class Context<E extends Env = any, P extends string = any, I extends Input = {}> {
|
|
@@ -70,7 +71,7 @@ export declare class Context<E extends Env = any, P extends string = any, I exte
|
|
|
70
71
|
private _renderer;
|
|
71
72
|
private notFoundHandler;
|
|
72
73
|
constructor(req: HonoRequest<P, I['out']>, options?: ContextOptions<E>);
|
|
73
|
-
get event():
|
|
74
|
+
get event(): FetchEvent;
|
|
74
75
|
get executionCtx(): ExecutionContext;
|
|
75
76
|
get res(): Response;
|
|
76
77
|
set res(_res: Response | undefined);
|
|
@@ -4,4 +4,4 @@ import type { Env, Input, MiddlewareHandler } from '../../types';
|
|
|
4
4
|
* `middleware()` is an experimental feature.
|
|
5
5
|
* The API might be changed.
|
|
6
6
|
*/
|
|
7
|
-
export declare const
|
|
7
|
+
export declare const createMiddleware: <E extends Env = any, P extends string = any, I extends Input = {}>(middleware: MiddlewareHandler<E, P, I>) => MiddlewareHandler<E, P, I>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Context } from '../../context';
|
|
2
|
+
import { StreamingApi } from '../../utils/stream';
|
|
3
|
+
interface SSEMessage {
|
|
4
|
+
data: string;
|
|
5
|
+
event?: string;
|
|
6
|
+
id?: string;
|
|
7
|
+
}
|
|
8
|
+
declare class SSEStreamingApi extends StreamingApi {
|
|
9
|
+
constructor(writable: WritableStream);
|
|
10
|
+
writeSSE(message: SSEMessage): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
export declare const streamSSE: (c: Context, cb: (stream: SSEStreamingApi) => Promise<void>) => Response;
|
|
13
|
+
export {};
|
package/dist/types/helper.d.ts
CHANGED
|
@@ -10,11 +10,11 @@ interface RouterRoute {
|
|
|
10
10
|
}
|
|
11
11
|
declare const Hono_base: new <E_1 extends Env = Env, S_1 extends Schema = {}, BasePath_1 extends string = "/">() => {
|
|
12
12
|
all: HandlerInterface<E_1, "all", S_1, BasePath_1>;
|
|
13
|
-
options: HandlerInterface<E_1, "options", S_1, BasePath_1>;
|
|
14
13
|
get: HandlerInterface<E_1, "get", S_1, BasePath_1>;
|
|
15
14
|
post: HandlerInterface<E_1, "post", S_1, BasePath_1>;
|
|
16
15
|
put: HandlerInterface<E_1, "put", S_1, BasePath_1>;
|
|
17
16
|
delete: HandlerInterface<E_1, "delete", S_1, BasePath_1>;
|
|
17
|
+
options: HandlerInterface<E_1, "options", S_1, BasePath_1>;
|
|
18
18
|
patch: HandlerInterface<E_1, "patch", S_1, BasePath_1>;
|
|
19
19
|
} & {
|
|
20
20
|
on: OnHandlerInterface<E_1, S_1, BasePath_1>;
|
|
@@ -29,5 +29,13 @@ export declare type FC<T = Props> = (props: T & {
|
|
|
29
29
|
export declare const memo: <T>(component: FC<T>, propsAreEqual?: (prevProps: Readonly<T>, nextProps: Readonly<T>) => boolean) => FC<T>;
|
|
30
30
|
export declare const Fragment: (props: {
|
|
31
31
|
key?: string;
|
|
32
|
-
children?: Child
|
|
32
|
+
children?: Child | HtmlEscapedString;
|
|
33
33
|
}) => HtmlEscapedString;
|
|
34
|
+
export interface Context<T> {
|
|
35
|
+
values: T[];
|
|
36
|
+
Provider: FC<{
|
|
37
|
+
value: T;
|
|
38
|
+
}>;
|
|
39
|
+
}
|
|
40
|
+
export declare const createContext: <T>(defaultValue: T) => Context<T>;
|
|
41
|
+
export declare const useContext: <T>(context: Context<T>) => T;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Context, Renderer } from '../../context';
|
|
2
|
+
import type { FC } from '../../jsx';
|
|
3
|
+
import type { Env, Input, MiddlewareHandler } from '../../types';
|
|
4
|
+
export declare const RequestContext: import("../../jsx").Context<Context<any, any, {}> | null>;
|
|
5
|
+
declare type PropsForRenderer = [...Parameters<Renderer>] extends [unknown, infer Props] ? Props : unknown;
|
|
6
|
+
export declare const jsxRenderer: (component?: FC<PropsForRenderer>) => MiddlewareHandler;
|
|
7
|
+
export declare const useRequestContext: <E extends Env = any, P extends string = any, I extends Input = {}>() => Context<E, P, I>;
|
|
8
|
+
export {};
|
package/dist/types/request.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Input, InputToDataByTarget, ParamKeys, ParamKeyToRecord, RemoveQuestion, UndefinedIfHavingQuestion, ValidationTargets } from './types';
|
|
2
|
-
import type { BodyData } from './utils/body';
|
|
2
|
+
import type { BodyData, ParseBodyOptions } from './utils/body';
|
|
3
3
|
import type { Cookie } from './utils/cookie';
|
|
4
4
|
import type { UnionToIntersection } from './utils/types';
|
|
5
5
|
declare type Body = {
|
|
@@ -47,7 +47,7 @@ export declare class HonoRequest<P extends string = '/', I extends Input['out']
|
|
|
47
47
|
* app.get('/', (c) => c.json(getCookie(c)))
|
|
48
48
|
*/
|
|
49
49
|
cookie(): Cookie;
|
|
50
|
-
parseBody<T extends BodyData = BodyData>(): Promise<T>;
|
|
50
|
+
parseBody<T extends BodyData = BodyData>(options?: ParseBodyOptions): Promise<T>;
|
|
51
51
|
private cachedBody;
|
|
52
52
|
json<T = any>(): Promise<T>;
|
|
53
53
|
text(): Promise<string>;
|
|
@@ -1,3 +1,23 @@
|
|
|
1
1
|
import type { HonoRequest } from '../request';
|
|
2
|
-
export declare type BodyData = Record<string, string | string
|
|
3
|
-
export declare
|
|
2
|
+
export declare type BodyData = Record<string, string | File | (string | File)[]>;
|
|
3
|
+
export declare type ParseBodyOptions = {
|
|
4
|
+
/**
|
|
5
|
+
* Parse all fields with multiple values should be parsed as an array.
|
|
6
|
+
* @default false
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* const data = new FormData()
|
|
10
|
+
* data.append('file', 'aaa')
|
|
11
|
+
* data.append('file', 'bbb')
|
|
12
|
+
* data.append('message', 'hello')
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* If `all` is `false`:
|
|
16
|
+
* parseBody should return `{ file: 'bbb', message: 'hello' }`
|
|
17
|
+
*
|
|
18
|
+
* If `all` is `true`:
|
|
19
|
+
* parseBody should return `{ file: ['aaa', 'bbb'], message: 'hello' }`
|
|
20
|
+
*/
|
|
21
|
+
all?: boolean;
|
|
22
|
+
};
|
|
23
|
+
export declare const parseBody: <T extends BodyData = BodyData>(request: HonoRequest | Request, options?: ParseBodyOptions) => Promise<T>;
|
package/dist/utils/body.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
// src/utils/body.ts
|
|
2
|
-
var
|
|
2
|
+
var isArrayField = (value) => {
|
|
3
|
+
return Array.isArray(value);
|
|
4
|
+
};
|
|
5
|
+
var parseBody = async (request, options = {
|
|
6
|
+
all: false
|
|
7
|
+
}) => {
|
|
3
8
|
let body = {};
|
|
4
9
|
const contentType = request.headers.get("Content-Type");
|
|
5
10
|
if (contentType && (contentType.startsWith("multipart/form-data") || contentType.startsWith("application/x-www-form-urlencoded"))) {
|
|
@@ -7,18 +12,21 @@ var parseBody = async (request) => {
|
|
|
7
12
|
if (formData) {
|
|
8
13
|
const form = {};
|
|
9
14
|
formData.forEach((value, key) => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
form[key] = [value.toString()];
|
|
13
|
-
} else {
|
|
14
|
-
if (Array.isArray(form[key])) {
|
|
15
|
-
;
|
|
16
|
-
form[key].push(value.toString());
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
} else {
|
|
15
|
+
const shouldParseAllValues = options.all || key.slice(-2) === "[]";
|
|
16
|
+
if (!shouldParseAllValues) {
|
|
20
17
|
form[key] = value;
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (form[key] && isArrayField(form[key])) {
|
|
21
|
+
;
|
|
22
|
+
form[key].push(value);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (form[key]) {
|
|
26
|
+
form[key] = [form[key], value];
|
|
27
|
+
return;
|
|
21
28
|
}
|
|
29
|
+
form[key] = value;
|
|
22
30
|
});
|
|
23
31
|
body = form;
|
|
24
32
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hono",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.8.0-rc.1",
|
|
4
4
|
"description": "Ultrafast web framework for the Edges",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"lint:fix": "eslint --ext js,ts src runtime_tests .eslintrc.cjs --fix",
|
|
25
25
|
"format": "prettier --check 'src/**/*.{js,ts}' 'runtime_tests/**/*.{js,ts}'",
|
|
26
26
|
"format:fix": "prettier --write 'src/**/*.{js,ts}' 'runtime_tests/**/*.{js,ts}'",
|
|
27
|
-
"denoify": "rimraf deno_dist && denoify && rimraf 'deno_dist/**/*.test.ts'",
|
|
27
|
+
"denoify": "rimraf deno_dist && denoify && rimraf 'deno_dist/**/*.test.{ts,tsx}'",
|
|
28
28
|
"copy:package.cjs.json": "cp ./package.cjs.json ./dist/cjs/package.json && cp ./package.cjs.json ./dist/types/package.json ",
|
|
29
29
|
"build": "rimraf dist && tsx ./build.ts && yarn copy:package.cjs.json",
|
|
30
30
|
"postbuild": "publint",
|
|
@@ -109,6 +109,11 @@
|
|
|
109
109
|
"import": "./dist/jsx/jsx-runtime.js",
|
|
110
110
|
"require": "./dist/cjs/jsx/jsx-runtime.js"
|
|
111
111
|
},
|
|
112
|
+
"./jsx-renderer": {
|
|
113
|
+
"types": "./dist/types/middleware/jsx-renderer/index.d.ts",
|
|
114
|
+
"import": "./dist/middleware/jsx-renderer/index.js",
|
|
115
|
+
"require": "./dist/cjs/middleware/jsx-renderer/index.js"
|
|
116
|
+
},
|
|
112
117
|
"./jwt": {
|
|
113
118
|
"types": "./dist/types/middleware/jwt/index.d.ts",
|
|
114
119
|
"import": "./dist/middleware/jwt/index.js",
|
|
@@ -284,6 +289,9 @@
|
|
|
284
289
|
"jsx/jsx-dev-runtime": [
|
|
285
290
|
"./dist/types/jsx/jsx-dev-runtime.d.ts"
|
|
286
291
|
],
|
|
292
|
+
"jsx-renderer": [
|
|
293
|
+
"./dist/types/middleware/jsx-renderer"
|
|
294
|
+
],
|
|
287
295
|
"jwt": [
|
|
288
296
|
"./dist/types/middleware/jwt"
|
|
289
297
|
],
|
|
@@ -398,7 +406,7 @@
|
|
|
398
406
|
"@types/crypto-js": "^4.1.1",
|
|
399
407
|
"@types/glob": "^8.0.0",
|
|
400
408
|
"@types/jest": "^29.4.0",
|
|
401
|
-
"@types/node": "^
|
|
409
|
+
"@types/node": "^20.8.2",
|
|
402
410
|
"@types/node-fetch": "^2.6.2",
|
|
403
411
|
"@types/supertest": "^2.0.12",
|
|
404
412
|
"@typescript-eslint/eslint-plugin": "^5.59.2",
|