hono 4.0.5 → 4.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/adapter/bun/serve-static.js +16 -37
  2. package/dist/adapter/cloudflare-workers/serve-static.js +12 -37
  3. package/dist/adapter/deno/serve-static.js +19 -35
  4. package/dist/cjs/adapter/bun/serve-static.js +16 -37
  5. package/dist/cjs/adapter/cloudflare-workers/serve-static.js +12 -37
  6. package/dist/cjs/adapter/deno/serve-static.js +19 -35
  7. package/dist/cjs/helper/streaming/sse.js +14 -2
  8. package/dist/cjs/helper/streaming/stream.js +14 -2
  9. package/dist/cjs/helper/streaming/text.js +2 -2
  10. package/dist/cjs/jsx/dom/render.js +30 -6
  11. package/dist/cjs/middleware/serve-static/index.js +84 -0
  12. package/dist/cjs/router/reg-exp-router/router.js +3 -7
  13. package/dist/cjs/utils/filepath.js +16 -6
  14. package/dist/helper/streaming/sse.js +14 -2
  15. package/dist/helper/streaming/stream.js +14 -2
  16. package/dist/helper/streaming/text.js +2 -2
  17. package/dist/jsx/dom/render.js +29 -5
  18. package/dist/middleware/serve-static/index.js +61 -0
  19. package/dist/router/reg-exp-router/router.js +3 -8
  20. package/dist/types/adapter/bun/serve-static.d.ts +2 -9
  21. package/dist/types/adapter/cloudflare-workers/serve-static.d.ts +3 -8
  22. package/dist/types/adapter/deno/serve-static.d.ts +2 -9
  23. package/dist/types/helper/streaming/sse.d.ts +1 -1
  24. package/dist/types/helper/streaming/stream.d.ts +1 -1
  25. package/dist/types/helper/streaming/text.d.ts +1 -1
  26. package/dist/types/jsx/dom/render.d.ts +4 -1
  27. package/dist/types/middleware/serve-static/index.d.ts +16 -0
  28. package/dist/types/types.d.ts +6 -2
  29. package/dist/types/utils/filepath.d.ts +1 -0
  30. package/dist/utils/filepath.js +14 -5
  31. package/package.json +1 -1
@@ -1,41 +1,20 @@
1
1
  // src/adapter/bun/serve-static.ts
2
- import { getFilePath } from "../../utils/filepath.js";
3
- import { getMimeType } from "../../utils/mime.js";
4
- var DEFAULT_DOCUMENT = "index.html";
5
- var serveStatic = (options = { root: "" }) => {
6
- return async (c, next) => {
7
- if (c.finalized) {
8
- await next();
9
- return;
10
- }
11
- const url = new URL(c.req.url);
12
- const filename = options.path ?? decodeURI(url.pathname);
13
- let path = getFilePath({
14
- filename: options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename,
15
- root: options.root,
16
- defaultDocument: DEFAULT_DOCUMENT
17
- });
18
- if (!path) {
19
- return await next();
20
- }
21
- path = `./${path}`;
22
- const file = Bun.file(path);
23
- const isExists = await file.exists();
24
- if (isExists) {
25
- let mimeType = void 0;
26
- if (options.mimes) {
27
- mimeType = getMimeType(path, options.mimes) ?? getMimeType(path);
28
- } else {
29
- mimeType = getMimeType(path);
30
- }
31
- if (mimeType) {
32
- c.header("Content-Type", mimeType);
33
- }
34
- return c.body(file);
35
- }
36
- await options.onNotFound?.(path, c);
37
- await next();
38
- return;
2
+ import { serveStatic as baseServeStatic } from "../../middleware/serve-static/index.js";
3
+ var serveStatic = (options) => {
4
+ return async function serveStatic2(c, next) {
5
+ const getContent = async (path) => {
6
+ path = `./${path}`;
7
+ const file = Bun.file(path);
8
+ return await file.exists() ? file : null;
9
+ };
10
+ const pathResolve = (path) => {
11
+ return `./${path}`;
12
+ };
13
+ return baseServeStatic({
14
+ ...options,
15
+ getContent,
16
+ pathResolve
17
+ })(c, next);
39
18
  };
40
19
  };
41
20
  export {
@@ -1,43 +1,18 @@
1
1
  // src/adapter/cloudflare-workers/serve-static.ts
2
- import { getFilePath } from "../../utils/filepath.js";
3
- import { getMimeType } from "../../utils/mime.js";
2
+ import { serveStatic as baseServeStatic } from "../../middleware/serve-static/index.js";
4
3
  import { getContentFromKVAsset } from "./utils.js";
5
- var DEFAULT_DOCUMENT = "index.html";
6
4
  var serveStatic = (options) => {
7
- return async (c, next) => {
8
- if (c.finalized) {
9
- await next();
10
- return;
11
- }
12
- const url = new URL(c.req.url);
13
- const filename = options.path ?? decodeURI(url.pathname);
14
- const path = getFilePath({
15
- filename: options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename,
16
- root: options.root,
17
- defaultDocument: DEFAULT_DOCUMENT
18
- });
19
- if (!path) {
20
- return await next();
21
- }
22
- const content = await getContentFromKVAsset(path, {
23
- manifest: options.manifest,
24
- namespace: options.namespace ? options.namespace : c.env ? c.env.__STATIC_CONTENT : void 0
25
- });
26
- if (content) {
27
- let mimeType = void 0;
28
- if (options.mimes) {
29
- mimeType = getMimeType(path, options.mimes) ?? getMimeType(path);
30
- } else {
31
- mimeType = getMimeType(path);
32
- }
33
- if (mimeType) {
34
- c.header("Content-Type", mimeType);
35
- }
36
- return c.body(content);
37
- }
38
- await options.onNotFound?.(path, c);
39
- await next();
40
- return;
5
+ return async function serveStatic2(c, next) {
6
+ const getContent = async (path) => {
7
+ return getContentFromKVAsset(path, {
8
+ manifest: options.manifest,
9
+ namespace: options.namespace ? options.namespace : c.env ? c.env.__STATIC_CONTENT : void 0
10
+ });
11
+ };
12
+ return baseServeStatic({
13
+ ...options,
14
+ getContent
15
+ })(c, next);
41
16
  };
42
17
  };
43
18
  export {
@@ -1,41 +1,25 @@
1
1
  // src/adapter/deno/serve-static.ts
2
- import { getFilePath } from "../../utils/filepath.js";
3
- import { getMimeType } from "../../utils/mime.js";
2
+ import { serveStatic as baseServeStatic } from "../../middleware/serve-static/index.js";
4
3
  var { open } = Deno;
5
- var DEFAULT_DOCUMENT = "index.html";
6
- var serveStatic = (options = { root: "" }) => {
7
- return async (c, next) => {
8
- if (c.finalized) {
9
- await next();
10
- return;
11
- }
12
- const url = new URL(c.req.url);
13
- const filename = options.path ?? decodeURI(url.pathname);
14
- let path = getFilePath({
15
- filename: options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename,
16
- root: options.root,
17
- defaultDocument: DEFAULT_DOCUMENT
18
- });
19
- if (!path) {
20
- return await next();
21
- }
22
- path = `./${path}`;
23
- let file;
24
- try {
25
- file = await open(path);
26
- } catch (e) {
27
- console.warn(`${e}`);
28
- }
29
- if (file) {
30
- const mimeType = getMimeType(path);
31
- if (mimeType) {
32
- c.header("Content-Type", mimeType);
4
+ var serveStatic = (options) => {
5
+ return async function serveStatic2(c, next) {
6
+ const getContent = async (path) => {
7
+ let file;
8
+ try {
9
+ file = await open(path);
10
+ } catch (e) {
11
+ console.warn(`${e}`);
33
12
  }
34
- return c.body(file.readable);
35
- }
36
- await options.onNotFound?.(path, c);
37
- await next();
38
- return;
13
+ return file ? file.readable : void 0;
14
+ };
15
+ const pathResolve = (path) => {
16
+ return `./${path}`;
17
+ };
18
+ return baseServeStatic({
19
+ ...options,
20
+ getContent,
21
+ pathResolve
22
+ })(c, next);
39
23
  };
40
24
  };
41
25
  export {
@@ -21,43 +21,22 @@ __export(serve_static_exports, {
21
21
  serveStatic: () => serveStatic
22
22
  });
23
23
  module.exports = __toCommonJS(serve_static_exports);
24
- var import_filepath = require("../../utils/filepath");
25
- var import_mime = require("../../utils/mime");
26
- const DEFAULT_DOCUMENT = "index.html";
27
- const serveStatic = (options = { root: "" }) => {
28
- return async (c, next) => {
29
- if (c.finalized) {
30
- await next();
31
- return;
32
- }
33
- const url = new URL(c.req.url);
34
- const filename = options.path ?? decodeURI(url.pathname);
35
- let path = (0, import_filepath.getFilePath)({
36
- filename: options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename,
37
- root: options.root,
38
- defaultDocument: DEFAULT_DOCUMENT
39
- });
40
- if (!path) {
41
- return await next();
42
- }
43
- path = `./${path}`;
44
- const file = Bun.file(path);
45
- const isExists = await file.exists();
46
- if (isExists) {
47
- let mimeType = void 0;
48
- if (options.mimes) {
49
- mimeType = (0, import_mime.getMimeType)(path, options.mimes) ?? (0, import_mime.getMimeType)(path);
50
- } else {
51
- mimeType = (0, import_mime.getMimeType)(path);
52
- }
53
- if (mimeType) {
54
- c.header("Content-Type", mimeType);
55
- }
56
- return c.body(file);
57
- }
58
- await options.onNotFound?.(path, c);
59
- await next();
60
- return;
24
+ var import_serve_static = require("../../middleware/serve-static");
25
+ const serveStatic = (options) => {
26
+ return async function serveStatic2(c, next) {
27
+ const getContent = async (path) => {
28
+ path = `./${path}`;
29
+ const file = Bun.file(path);
30
+ return await file.exists() ? file : null;
31
+ };
32
+ const pathResolve = (path) => {
33
+ return `./${path}`;
34
+ };
35
+ return (0, import_serve_static.serveStatic)({
36
+ ...options,
37
+ getContent,
38
+ pathResolve
39
+ })(c, next);
61
40
  };
62
41
  };
63
42
  // Annotate the CommonJS export names for ESM import in node:
@@ -21,45 +21,20 @@ __export(serve_static_exports, {
21
21
  serveStatic: () => serveStatic
22
22
  });
23
23
  module.exports = __toCommonJS(serve_static_exports);
24
- var import_filepath = require("../../utils/filepath");
25
- var import_mime = require("../../utils/mime");
24
+ var import_serve_static = require("../../middleware/serve-static");
26
25
  var import_utils = require("./utils");
27
- const DEFAULT_DOCUMENT = "index.html";
28
26
  const serveStatic = (options) => {
29
- return async (c, next) => {
30
- if (c.finalized) {
31
- await next();
32
- return;
33
- }
34
- const url = new URL(c.req.url);
35
- const filename = options.path ?? decodeURI(url.pathname);
36
- const path = (0, import_filepath.getFilePath)({
37
- filename: options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename,
38
- root: options.root,
39
- defaultDocument: DEFAULT_DOCUMENT
40
- });
41
- if (!path) {
42
- return await next();
43
- }
44
- const content = await (0, import_utils.getContentFromKVAsset)(path, {
45
- manifest: options.manifest,
46
- namespace: options.namespace ? options.namespace : c.env ? c.env.__STATIC_CONTENT : void 0
47
- });
48
- if (content) {
49
- let mimeType = void 0;
50
- if (options.mimes) {
51
- mimeType = (0, import_mime.getMimeType)(path, options.mimes) ?? (0, import_mime.getMimeType)(path);
52
- } else {
53
- mimeType = (0, import_mime.getMimeType)(path);
54
- }
55
- if (mimeType) {
56
- c.header("Content-Type", mimeType);
57
- }
58
- return c.body(content);
59
- }
60
- await options.onNotFound?.(path, c);
61
- await next();
62
- return;
27
+ return async function serveStatic2(c, next) {
28
+ const getContent = async (path) => {
29
+ return (0, import_utils.getContentFromKVAsset)(path, {
30
+ manifest: options.manifest,
31
+ namespace: options.namespace ? options.namespace : c.env ? c.env.__STATIC_CONTENT : void 0
32
+ });
33
+ };
34
+ return (0, import_serve_static.serveStatic)({
35
+ ...options,
36
+ getContent
37
+ })(c, next);
63
38
  };
64
39
  };
65
40
  // Annotate the CommonJS export names for ESM import in node:
@@ -21,43 +21,27 @@ __export(serve_static_exports, {
21
21
  serveStatic: () => serveStatic
22
22
  });
23
23
  module.exports = __toCommonJS(serve_static_exports);
24
- var import_filepath = require("../../utils/filepath");
25
- var import_mime = require("../../utils/mime");
24
+ var import_serve_static = require("../../middleware/serve-static");
26
25
  const { open } = Deno;
27
- const DEFAULT_DOCUMENT = "index.html";
28
- const serveStatic = (options = { root: "" }) => {
29
- return async (c, next) => {
30
- if (c.finalized) {
31
- await next();
32
- return;
33
- }
34
- const url = new URL(c.req.url);
35
- const filename = options.path ?? decodeURI(url.pathname);
36
- let path = (0, import_filepath.getFilePath)({
37
- filename: options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename,
38
- root: options.root,
39
- defaultDocument: DEFAULT_DOCUMENT
40
- });
41
- if (!path) {
42
- return await next();
43
- }
44
- path = `./${path}`;
45
- let file;
46
- try {
47
- file = await open(path);
48
- } catch (e) {
49
- console.warn(`${e}`);
50
- }
51
- if (file) {
52
- const mimeType = (0, import_mime.getMimeType)(path);
53
- if (mimeType) {
54
- c.header("Content-Type", mimeType);
26
+ const serveStatic = (options) => {
27
+ return async function serveStatic2(c, next) {
28
+ const getContent = async (path) => {
29
+ let file;
30
+ try {
31
+ file = await open(path);
32
+ } catch (e) {
33
+ console.warn(`${e}`);
55
34
  }
56
- return c.body(file.readable);
57
- }
58
- await options.onNotFound?.(path, c);
59
- await next();
60
- return;
35
+ return file ? file.readable : void 0;
36
+ };
37
+ const pathResolve = (path) => {
38
+ return `./${path}`;
39
+ };
40
+ return (0, import_serve_static.serveStatic)({
41
+ ...options,
42
+ getContent,
43
+ pathResolve
44
+ })(c, next);
61
45
  };
62
46
  };
63
47
  // Annotate the CommonJS export names for ESM import in node:
@@ -46,10 +46,22 @@ const setSSEHeaders = (context) => {
46
46
  context.header("Cache-Control", "no-cache");
47
47
  context.header("Connection", "keep-alive");
48
48
  };
49
- const streamSSE = (c, cb) => {
49
+ const streamSSE = (c, cb, onError) => {
50
50
  const { readable, writable } = new TransformStream();
51
51
  const stream = new SSEStreamingApi(writable, readable);
52
- cb(stream).finally(() => stream.close());
52
+ (async () => {
53
+ try {
54
+ await cb(stream);
55
+ } catch (e) {
56
+ if (e instanceof Error && onError) {
57
+ await onError(e, stream);
58
+ } else {
59
+ console.error(e);
60
+ }
61
+ } finally {
62
+ stream.close();
63
+ }
64
+ })();
53
65
  setSSEHeaders(c);
54
66
  return c.newResponse(stream.responseReadable);
55
67
  };
@@ -22,10 +22,22 @@ __export(stream_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(stream_exports);
24
24
  var import_stream = require("../../utils/stream");
25
- const stream = (c, cb) => {
25
+ const stream = (c, cb, onError) => {
26
26
  const { readable, writable } = new TransformStream();
27
27
  const stream2 = new import_stream.StreamingApi(writable, readable);
28
- cb(stream2).finally(() => stream2.close());
28
+ (async () => {
29
+ try {
30
+ await cb(stream2);
31
+ } catch (e) {
32
+ if (e instanceof Error && onError) {
33
+ await onError(e, stream2);
34
+ } else {
35
+ console.error(e);
36
+ }
37
+ } finally {
38
+ stream2.close();
39
+ }
40
+ })();
29
41
  return c.newResponse(stream2.responseReadable);
30
42
  };
31
43
  // Annotate the CommonJS export names for ESM import in node:
@@ -23,11 +23,11 @@ __export(text_exports, {
23
23
  module.exports = __toCommonJS(text_exports);
24
24
  var import_context = require("../../context");
25
25
  var import__ = require(".");
26
- const streamText = (c, cb) => {
26
+ const streamText = (c, cb, onError) => {
27
27
  c.header("Content-Type", import_context.TEXT_PLAIN);
28
28
  c.header("X-Content-Type-Options", "nosniff");
29
29
  c.header("Transfer-Encoding", "chunked");
30
- return (0, import__.stream)(c, cb);
30
+ return (0, import__.stream)(c, cb, onError);
31
31
  };
32
32
  // Annotate the CommonJS export names for ESM import in node:
33
33
  0 && (module.exports = {
@@ -27,7 +27,7 @@ module.exports = __toCommonJS(render_exports);
27
27
  var import_constants = require("../constants");
28
28
  var import_context = require("../context");
29
29
  var import_hooks = require("../hooks");
30
- var import__ = require(".");
30
+ var import_context2 = require("./context");
31
31
  const eventAliasMap = {
32
32
  Change: "Input",
33
33
  DoubleClick: "DblClick"
@@ -76,6 +76,26 @@ const applyProps = (container, attributes, oldAttributes) => {
76
76
  Object.assign(container.style, value);
77
77
  }
78
78
  } else {
79
+ const nodeName = container.nodeName;
80
+ if (key === "value") {
81
+ if (nodeName === "INPUT" || nodeName === "TEXTAREA" || nodeName === "SELECT") {
82
+ ;
83
+ container.value = value === null || value === void 0 || value === false ? null : value;
84
+ if (nodeName === "TEXTAREA") {
85
+ container.textContent = value;
86
+ continue;
87
+ } else if (nodeName === "SELECT") {
88
+ if (container.selectedIndex === -1) {
89
+ ;
90
+ container.selectedIndex = 0;
91
+ }
92
+ continue;
93
+ }
94
+ }
95
+ } else if (key === "checked" && nodeName === "INPUT" || key === "selected" && nodeName === "OPTION") {
96
+ ;
97
+ container[key] = value;
98
+ }
79
99
  if (value === null || value === void 0 || value === false) {
80
100
  container.removeAttribute(key);
81
101
  } else if (value === true) {
@@ -206,9 +226,10 @@ const applyNodeObject = (node, container) => {
206
226
  const child = next[i];
207
227
  let el;
208
228
  if (isNodeString(child)) {
209
- if (child.e) {
229
+ if (child.e && child[1]) {
210
230
  child.e.textContent = child[0];
211
231
  }
232
+ child[1] = false;
212
233
  el = child.e || (child.e = document.createTextNode(child[0]));
213
234
  } else {
214
235
  el = child.e || (child.e = child.n ? document.createElementNS(child.n, child.tag) : document.createElement(child.tag));
@@ -261,7 +282,10 @@ const build = (context, node, topLevelErrorHandlerNode, children) => {
261
282
  if (!isNodeString(oldChild)) {
262
283
  vChildrenToRemove.push(oldChild);
263
284
  } else {
264
- oldChild[0] = child[0];
285
+ if (oldChild[0] !== child[0]) {
286
+ oldChild[0] = child[0];
287
+ oldChild[1] = true;
288
+ }
265
289
  child = oldChild;
266
290
  }
267
291
  } else if (oldChild.tag !== child.tag) {
@@ -273,7 +297,7 @@ const build = (context, node, topLevelErrorHandlerNode, children) => {
273
297
  child = oldChild;
274
298
  }
275
299
  } else if (!isNodeString(child) && nameSpaceContext) {
276
- const ns = (0, import__.useContext)(nameSpaceContext);
300
+ const ns = (0, import_context.useContext)(nameSpaceContext);
277
301
  if (ns) {
278
302
  child.n = ns;
279
303
  }
@@ -309,7 +333,7 @@ const buildNode = (node) => {
309
333
  if (node === void 0 || node === null || typeof node === "boolean") {
310
334
  return void 0;
311
335
  } else if (typeof node === "string" || typeof node === "number") {
312
- return [node.toString()];
336
+ return [node.toString(), true];
313
337
  } else {
314
338
  if (typeof node.tag === "function") {
315
339
  ;
@@ -319,7 +343,7 @@ const buildNode = (node) => {
319
343
  if (ns) {
320
344
  ;
321
345
  node.n = ns;
322
- nameSpaceContext || (nameSpaceContext = (0, import__.createContext)(""));
346
+ nameSpaceContext || (nameSpaceContext = (0, import_context2.createContext)(""));
323
347
  node.children = [
324
348
  {
325
349
  tag: nameSpaceContext.Provider,
@@ -0,0 +1,84 @@
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 serve_static_exports = {};
20
+ __export(serve_static_exports, {
21
+ serveStatic: () => serveStatic
22
+ });
23
+ module.exports = __toCommonJS(serve_static_exports);
24
+ var import_filepath = require("../../utils/filepath");
25
+ var import_mime = require("../../utils/mime");
26
+ const DEFAULT_DOCUMENT = "index.html";
27
+ const defaultPathResolve = (path) => path;
28
+ const serveStatic = (options) => {
29
+ return async (c, next) => {
30
+ if (c.finalized) {
31
+ await next();
32
+ return;
33
+ }
34
+ const url = new URL(c.req.url);
35
+ let filename = options.path ?? decodeURI(url.pathname);
36
+ filename = options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename;
37
+ const root = options.root;
38
+ let path = (0, import_filepath.getFilePath)({
39
+ filename,
40
+ root,
41
+ defaultDocument: DEFAULT_DOCUMENT
42
+ });
43
+ if (!path) {
44
+ return await next();
45
+ }
46
+ const getContent = options.getContent;
47
+ const pathResolve = options.pathResolve ?? defaultPathResolve;
48
+ path = pathResolve(path);
49
+ let content = await getContent(path);
50
+ if (!content) {
51
+ let pathWithOutDefaultDocument = (0, import_filepath.getFilePathWithoutDefaultDocument)({
52
+ filename,
53
+ root
54
+ });
55
+ if (!pathWithOutDefaultDocument) {
56
+ return await next();
57
+ }
58
+ pathWithOutDefaultDocument = pathResolve(pathWithOutDefaultDocument);
59
+ content = await getContent(pathWithOutDefaultDocument);
60
+ if (content) {
61
+ path = pathWithOutDefaultDocument;
62
+ }
63
+ }
64
+ if (content) {
65
+ let mimeType = void 0;
66
+ if (options.mimes) {
67
+ mimeType = (0, import_mime.getMimeType)(path, options.mimes) ?? (0, import_mime.getMimeType)(path);
68
+ } else {
69
+ mimeType = (0, import_mime.getMimeType)(path);
70
+ }
71
+ if (mimeType) {
72
+ c.header("Content-Type", mimeType);
73
+ }
74
+ return c.body(content);
75
+ }
76
+ await options.onNotFound?.(path, c);
77
+ await next();
78
+ return;
79
+ };
80
+ };
81
+ // Annotate the CommonJS export names for ESM import in node:
82
+ 0 && (module.exports = {
83
+ serveStatic
84
+ });
@@ -25,7 +25,6 @@ var import_router = require("../../router");
25
25
  var import_url = require("../../utils/url");
26
26
  var import_node = require("./node");
27
27
  var import_trie = require("./trie");
28
- const methodNames = [import_router.METHOD_NAME_ALL, ...import_router.METHODS].map((method) => method.toUpperCase());
29
28
  const emptyParam = [];
30
29
  const nullMatcher = [/^$/, [], {}];
31
30
  let wildcardRegExpCache = {};
@@ -117,9 +116,6 @@ class RegExpRouter {
117
116
  if (!middleware || !routes) {
118
117
  throw new Error(import_router.MESSAGE_MATCHER_IS_ALREADY_BUILT);
119
118
  }
120
- if (methodNames.indexOf(method) === -1) {
121
- methodNames.push(method);
122
- }
123
119
  if (!middleware[method]) {
124
120
  ;
125
121
  [middleware, routes].forEach((handlerMap) => {
@@ -177,7 +173,7 @@ class RegExpRouter {
177
173
  clearWildcardRegExpCache();
178
174
  const matchers = this.buildAllMatchers();
179
175
  this.match = (method2, path2) => {
180
- const matcher = matchers[method2];
176
+ const matcher = matchers[method2] || matchers[import_router.METHOD_NAME_ALL];
181
177
  const staticMatch = matcher[2][path2];
182
178
  if (staticMatch) {
183
179
  return staticMatch;
@@ -193,8 +189,8 @@ class RegExpRouter {
193
189
  }
194
190
  buildAllMatchers() {
195
191
  const matchers = {};
196
- methodNames.forEach((method) => {
197
- matchers[method] = this.buildMatcher(method) || matchers[import_router.METHOD_NAME_ALL];
192
+ [...Object.keys(this.routes), ...Object.keys(this.middleware)].forEach((method) => {
193
+ matchers[method] || (matchers[method] = this.buildMatcher(method));
198
194
  });
199
195
  this.middleware = this.routes = void 0;
200
196
  return matchers;
@@ -18,21 +18,30 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var filepath_exports = {};
20
20
  __export(filepath_exports, {
21
- getFilePath: () => getFilePath
21
+ getFilePath: () => getFilePath,
22
+ getFilePathWithoutDefaultDocument: () => getFilePathWithoutDefaultDocument
22
23
  });
23
24
  module.exports = __toCommonJS(filepath_exports);
24
25
  const getFilePath = (options) => {
25
26
  let filename = options.filename;
26
- if (/(?:^|[\/\\])\.\.(?:$|[\/\\])/.test(filename)) {
27
- return;
28
- }
29
- let root = options.root || "";
30
27
  const defaultDocument = options.defaultDocument || "index.html";
31
28
  if (filename.endsWith("/")) {
32
29
  filename = filename.concat(defaultDocument);
33
30
  } else if (!filename.match(/\.[a-zA-Z0-9]+$/)) {
34
31
  filename = filename.concat("/" + defaultDocument);
35
32
  }
33
+ const path = getFilePathWithoutDefaultDocument({
34
+ root: options.root,
35
+ filename
36
+ });
37
+ return path;
38
+ };
39
+ const getFilePathWithoutDefaultDocument = (options) => {
40
+ let root = options.root || "";
41
+ let filename = options.filename;
42
+ if (/(?:^|[\/\\])\.\.(?:$|[\/\\])/.test(filename)) {
43
+ return;
44
+ }
36
45
  filename = filename.replace(/^\.?[\/\\]/, "");
37
46
  filename = filename.replace(/\\/, "/");
38
47
  root = root.replace(/\/$/, "");
@@ -42,5 +51,6 @@ const getFilePath = (options) => {
42
51
  };
43
52
  // Annotate the CommonJS export names for ESM import in node:
44
53
  0 && (module.exports = {
45
- getFilePath
54
+ getFilePath,
55
+ getFilePathWithoutDefaultDocument
46
56
  });
@@ -23,10 +23,22 @@ var setSSEHeaders = (context) => {
23
23
  context.header("Cache-Control", "no-cache");
24
24
  context.header("Connection", "keep-alive");
25
25
  };
26
- var streamSSE = (c, cb) => {
26
+ var streamSSE = (c, cb, onError) => {
27
27
  const { readable, writable } = new TransformStream();
28
28
  const stream = new SSEStreamingApi(writable, readable);
29
- cb(stream).finally(() => stream.close());
29
+ (async () => {
30
+ try {
31
+ await cb(stream);
32
+ } catch (e) {
33
+ if (e instanceof Error && onError) {
34
+ await onError(e, stream);
35
+ } else {
36
+ console.error(e);
37
+ }
38
+ } finally {
39
+ stream.close();
40
+ }
41
+ })();
30
42
  setSSEHeaders(c);
31
43
  return c.newResponse(stream.responseReadable);
32
44
  };
@@ -1,9 +1,21 @@
1
1
  // src/helper/streaming/stream.ts
2
2
  import { StreamingApi } from "../../utils/stream.js";
3
- var stream = (c, cb) => {
3
+ var stream = (c, cb, onError) => {
4
4
  const { readable, writable } = new TransformStream();
5
5
  const stream2 = new StreamingApi(writable, readable);
6
- cb(stream2).finally(() => stream2.close());
6
+ (async () => {
7
+ try {
8
+ await cb(stream2);
9
+ } catch (e) {
10
+ if (e instanceof Error && onError) {
11
+ await onError(e, stream2);
12
+ } else {
13
+ console.error(e);
14
+ }
15
+ } finally {
16
+ stream2.close();
17
+ }
18
+ })();
7
19
  return c.newResponse(stream2.responseReadable);
8
20
  };
9
21
  export {
@@ -1,11 +1,11 @@
1
1
  // src/helper/streaming/text.ts
2
2
  import { TEXT_PLAIN } from "../../context.js";
3
3
  import { stream } from "./index.js";
4
- var streamText = (c, cb) => {
4
+ var streamText = (c, cb, onError) => {
5
5
  c.header("Content-Type", TEXT_PLAIN);
6
6
  c.header("X-Content-Type-Options", "nosniff");
7
7
  c.header("Transfer-Encoding", "chunked");
8
- return stream(c, cb);
8
+ return stream(c, cb, onError);
9
9
  };
10
10
  export {
11
11
  streamText
@@ -1,8 +1,8 @@
1
1
  // src/jsx/dom/render.ts
2
2
  import { DOM_RENDERER, DOM_ERROR_HANDLER, DOM_STASH } from "../constants.js";
3
- import { globalContexts as globalJSXContexts } from "../context.js";
3
+ import { globalContexts as globalJSXContexts, useContext } from "../context.js";
4
4
  import { STASH_EFFECT } from "../hooks/index.js";
5
- import { useContext, createContext } from "./index.js";
5
+ import { createContext } from "./context.js";
6
6
  var eventAliasMap = {
7
7
  Change: "Input",
8
8
  DoubleClick: "DblClick"
@@ -51,6 +51,26 @@ var applyProps = (container, attributes, oldAttributes) => {
51
51
  Object.assign(container.style, value);
52
52
  }
53
53
  } else {
54
+ const nodeName = container.nodeName;
55
+ if (key === "value") {
56
+ if (nodeName === "INPUT" || nodeName === "TEXTAREA" || nodeName === "SELECT") {
57
+ ;
58
+ container.value = value === null || value === void 0 || value === false ? null : value;
59
+ if (nodeName === "TEXTAREA") {
60
+ container.textContent = value;
61
+ continue;
62
+ } else if (nodeName === "SELECT") {
63
+ if (container.selectedIndex === -1) {
64
+ ;
65
+ container.selectedIndex = 0;
66
+ }
67
+ continue;
68
+ }
69
+ }
70
+ } else if (key === "checked" && nodeName === "INPUT" || key === "selected" && nodeName === "OPTION") {
71
+ ;
72
+ container[key] = value;
73
+ }
54
74
  if (value === null || value === void 0 || value === false) {
55
75
  container.removeAttribute(key);
56
76
  } else if (value === true) {
@@ -181,9 +201,10 @@ var applyNodeObject = (node, container) => {
181
201
  const child = next[i];
182
202
  let el;
183
203
  if (isNodeString(child)) {
184
- if (child.e) {
204
+ if (child.e && child[1]) {
185
205
  child.e.textContent = child[0];
186
206
  }
207
+ child[1] = false;
187
208
  el = child.e || (child.e = document.createTextNode(child[0]));
188
209
  } else {
189
210
  el = child.e || (child.e = child.n ? document.createElementNS(child.n, child.tag) : document.createElement(child.tag));
@@ -236,7 +257,10 @@ var build = (context, node, topLevelErrorHandlerNode, children) => {
236
257
  if (!isNodeString(oldChild)) {
237
258
  vChildrenToRemove.push(oldChild);
238
259
  } else {
239
- oldChild[0] = child[0];
260
+ if (oldChild[0] !== child[0]) {
261
+ oldChild[0] = child[0];
262
+ oldChild[1] = true;
263
+ }
240
264
  child = oldChild;
241
265
  }
242
266
  } else if (oldChild.tag !== child.tag) {
@@ -284,7 +308,7 @@ var buildNode = (node) => {
284
308
  if (node === void 0 || node === null || typeof node === "boolean") {
285
309
  return void 0;
286
310
  } else if (typeof node === "string" || typeof node === "number") {
287
- return [node.toString()];
311
+ return [node.toString(), true];
288
312
  } else {
289
313
  if (typeof node.tag === "function") {
290
314
  ;
@@ -0,0 +1,61 @@
1
+ // src/middleware/serve-static/index.ts
2
+ import { getFilePath, getFilePathWithoutDefaultDocument } from "../../utils/filepath.js";
3
+ import { getMimeType } from "../../utils/mime.js";
4
+ var DEFAULT_DOCUMENT = "index.html";
5
+ var defaultPathResolve = (path) => path;
6
+ var serveStatic = (options) => {
7
+ return async (c, next) => {
8
+ if (c.finalized) {
9
+ await next();
10
+ return;
11
+ }
12
+ const url = new URL(c.req.url);
13
+ let filename = options.path ?? decodeURI(url.pathname);
14
+ filename = options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename;
15
+ const root = options.root;
16
+ let path = getFilePath({
17
+ filename,
18
+ root,
19
+ defaultDocument: DEFAULT_DOCUMENT
20
+ });
21
+ if (!path) {
22
+ return await next();
23
+ }
24
+ const getContent = options.getContent;
25
+ const pathResolve = options.pathResolve ?? defaultPathResolve;
26
+ path = pathResolve(path);
27
+ let content = await getContent(path);
28
+ if (!content) {
29
+ let pathWithOutDefaultDocument = getFilePathWithoutDefaultDocument({
30
+ filename,
31
+ root
32
+ });
33
+ if (!pathWithOutDefaultDocument) {
34
+ return await next();
35
+ }
36
+ pathWithOutDefaultDocument = pathResolve(pathWithOutDefaultDocument);
37
+ content = await getContent(pathWithOutDefaultDocument);
38
+ if (content) {
39
+ path = pathWithOutDefaultDocument;
40
+ }
41
+ }
42
+ if (content) {
43
+ let mimeType = void 0;
44
+ if (options.mimes) {
45
+ mimeType = getMimeType(path, options.mimes) ?? getMimeType(path);
46
+ } else {
47
+ mimeType = getMimeType(path);
48
+ }
49
+ if (mimeType) {
50
+ c.header("Content-Type", mimeType);
51
+ }
52
+ return c.body(content);
53
+ }
54
+ await options.onNotFound?.(path, c);
55
+ await next();
56
+ return;
57
+ };
58
+ };
59
+ export {
60
+ serveStatic
61
+ };
@@ -1,14 +1,12 @@
1
1
  // src/router/reg-exp-router/router.ts
2
2
  import {
3
3
  METHOD_NAME_ALL,
4
- METHODS,
5
4
  UnsupportedPathError,
6
5
  MESSAGE_MATCHER_IS_ALREADY_BUILT
7
6
  } from "../../router.js";
8
7
  import { checkOptionalParameter } from "../../utils/url.js";
9
8
  import { PATH_ERROR } from "./node.js";
10
9
  import { Trie } from "./trie.js";
11
- var methodNames = [METHOD_NAME_ALL, ...METHODS].map((method) => method.toUpperCase());
12
10
  var emptyParam = [];
13
11
  var nullMatcher = [/^$/, [], {}];
14
12
  var wildcardRegExpCache = {};
@@ -100,9 +98,6 @@ var RegExpRouter = class {
100
98
  if (!middleware || !routes) {
101
99
  throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);
102
100
  }
103
- if (methodNames.indexOf(method) === -1) {
104
- methodNames.push(method);
105
- }
106
101
  if (!middleware[method]) {
107
102
  ;
108
103
  [middleware, routes].forEach((handlerMap) => {
@@ -160,7 +155,7 @@ var RegExpRouter = class {
160
155
  clearWildcardRegExpCache();
161
156
  const matchers = this.buildAllMatchers();
162
157
  this.match = (method2, path2) => {
163
- const matcher = matchers[method2];
158
+ const matcher = matchers[method2] || matchers[METHOD_NAME_ALL];
164
159
  const staticMatch = matcher[2][path2];
165
160
  if (staticMatch) {
166
161
  return staticMatch;
@@ -176,8 +171,8 @@ var RegExpRouter = class {
176
171
  }
177
172
  buildAllMatchers() {
178
173
  const matchers = {};
179
- methodNames.forEach((method) => {
180
- matchers[method] = this.buildMatcher(method) || matchers[METHOD_NAME_ALL];
174
+ [...Object.keys(this.routes), ...Object.keys(this.middleware)].forEach((method) => {
175
+ matchers[method] || (matchers[method] = this.buildMatcher(method));
181
176
  });
182
177
  this.middleware = this.routes = void 0;
183
178
  return matchers;
@@ -1,10 +1,3 @@
1
- import type { Context } from '../../context';
1
+ import type { ServeStaticOptions } from '../../middleware/serve-static';
2
2
  import type { Env, MiddlewareHandler } from '../../types';
3
- export type ServeStaticOptions<E extends Env = Env> = {
4
- root?: string;
5
- path?: string;
6
- mimes?: Record<string, string>;
7
- rewriteRequestPath?: (path: string) => string;
8
- onNotFound?: (path: string, c: Context<E>) => void | Promise<void>;
9
- };
10
- export declare const serveStatic: <E extends Env = Env>(options?: ServeStaticOptions<E>) => MiddlewareHandler;
3
+ export declare const serveStatic: <E extends Env = Env>(options: ServeStaticOptions<E>) => MiddlewareHandler;
@@ -1,13 +1,8 @@
1
1
  import type { KVNamespace } from '@cloudflare/workers-types';
2
- import type { Context } from '../../context';
2
+ import type { ServeStaticOptions as BaseServeStaticOptions } from '../../middleware/serve-static';
3
3
  import type { Env, MiddlewareHandler } from '../../types';
4
- export type ServeStaticOptions<E extends Env = Env> = {
5
- root?: string;
6
- path?: string;
7
- mimes?: Record<string, string>;
8
- manifest: object | string;
4
+ export type ServeStaticOptions<E extends Env = Env> = BaseServeStaticOptions<E> & {
9
5
  namespace?: KVNamespace;
10
- rewriteRequestPath?: (path: string) => string;
11
- onNotFound?: (path: string, c: Context<E>) => void | Promise<void>;
6
+ manifest: object | string;
12
7
  };
13
8
  export declare const serveStatic: <E extends Env = Env>(options: ServeStaticOptions<E>) => MiddlewareHandler;
@@ -1,10 +1,3 @@
1
- import type { Context } from '../../context';
1
+ import type { ServeStaticOptions } from '../../middleware/serve-static';
2
2
  import type { Env, MiddlewareHandler } from '../../types';
3
- export type ServeStaticOptions<E extends Env = Env> = {
4
- root?: string;
5
- path?: string;
6
- mimes?: Record<string, string>;
7
- rewriteRequestPath?: (path: string) => string;
8
- onNotFound?: (path: string, c: Context<E>) => void | Promise<void>;
9
- };
10
- export declare const serveStatic: <E extends Env = Env>(options?: ServeStaticOptions<E>) => MiddlewareHandler;
3
+ export declare const serveStatic: <E extends Env = Env>(options: ServeStaticOptions<E>) => MiddlewareHandler;
@@ -10,4 +10,4 @@ export declare class SSEStreamingApi extends StreamingApi {
10
10
  constructor(writable: WritableStream, readable: ReadableStream);
11
11
  writeSSE(message: SSEMessage): Promise<void>;
12
12
  }
13
- export declare const streamSSE: (c: Context, cb: (stream: SSEStreamingApi) => Promise<void>) => Response;
13
+ export declare const streamSSE: (c: Context, cb: (stream: SSEStreamingApi) => Promise<void>, onError?: ((e: Error, stream: SSEStreamingApi) => Promise<void>) | undefined) => Response;
@@ -1,3 +1,3 @@
1
1
  import type { Context } from '../../context';
2
2
  import { StreamingApi } from '../../utils/stream';
3
- export declare const stream: (c: Context, cb: (stream: StreamingApi) => Promise<void>) => Response;
3
+ export declare const stream: (c: Context, cb: (stream: StreamingApi) => Promise<void>, onError?: ((e: Error, stream: StreamingApi) => Promise<void>) | undefined) => Response;
@@ -1,3 +1,3 @@
1
1
  import type { Context } from '../../context';
2
2
  import type { StreamingApi } from '../../utils/stream';
3
- export declare const streamText: (c: Context, cb: (stream: StreamingApi) => Promise<void>) => Response;
3
+ export declare const streamText: (c: Context, cb: (stream: StreamingApi) => Promise<void>, onError?: ((e: Error, stream: StreamingApi) => Promise<void>) | undefined) => Response;
@@ -27,7 +27,10 @@ export type NodeObject = {
27
27
  any[][]
28
28
  ];
29
29
  } & JSXNode;
30
- type NodeString = [string] & {
30
+ type NodeString = [
31
+ string,
32
+ boolean
33
+ ] & {
31
34
  e?: Text;
32
35
  vC: undefined;
33
36
  nN: undefined;
@@ -0,0 +1,16 @@
1
+ import type { Context } from '../../context';
2
+ import type { Env, MiddlewareHandler } from '../../types';
3
+ export type ServeStaticOptions<E extends Env = Env> = {
4
+ root?: string;
5
+ path?: string;
6
+ mimes?: Record<string, string>;
7
+ rewriteRequestPath?: (path: string) => string;
8
+ onNotFound?: (path: string, c: Context<E>) => void | Promise<void>;
9
+ };
10
+ /**
11
+ * This middleware is not directly used by the user. Create a wrapper specifying `getContent()` by the environment such as Deno or Bun.
12
+ */
13
+ export declare const serveStatic: <E extends Env = Env>(options: ServeStaticOptions<E> & {
14
+ getContent: (path: string) => any;
15
+ pathResolve?: ((path: string) => string) | undefined;
16
+ }) => MiddlewareHandler;
@@ -396,9 +396,13 @@ export type MergeSchemaPath<OrigSchema extends Schema, SubPath extends string> =
396
396
  input: Input extends {
397
397
  param: infer _;
398
398
  } ? ExtractParams<SubPath> extends never ? Input : FlattenIfIntersect<Input & {
399
- param: ExtractParams<SubPath>;
399
+ param: {
400
+ [K in keyof ExtractParams<SubPath> as K extends `${infer Prefix}{${infer _}}` ? Prefix : K]: string;
401
+ };
400
402
  }> : RemoveBlankRecord<ExtractParams<SubPath>> extends never ? Input : Input & {
401
- param: ExtractParams<SubPath>;
403
+ param: {
404
+ [K in keyof ExtractParams<SubPath> as K extends `${infer Prefix}{${infer _}}` ? Prefix : K]: string;
405
+ };
402
406
  };
403
407
  output: Output;
404
408
  } : never;
@@ -4,4 +4,5 @@ type FilePathOptions = {
4
4
  defaultDocument?: string;
5
5
  };
6
6
  export declare const getFilePath: (options: FilePathOptions) => string | undefined;
7
+ export declare const getFilePathWithoutDefaultDocument: (options: Omit<FilePathOptions, 'defaultDocument'>) => string | undefined;
7
8
  export {};
@@ -1,16 +1,24 @@
1
1
  // src/utils/filepath.ts
2
2
  var getFilePath = (options) => {
3
3
  let filename = options.filename;
4
- if (/(?:^|[\/\\])\.\.(?:$|[\/\\])/.test(filename)) {
5
- return;
6
- }
7
- let root = options.root || "";
8
4
  const defaultDocument = options.defaultDocument || "index.html";
9
5
  if (filename.endsWith("/")) {
10
6
  filename = filename.concat(defaultDocument);
11
7
  } else if (!filename.match(/\.[a-zA-Z0-9]+$/)) {
12
8
  filename = filename.concat("/" + defaultDocument);
13
9
  }
10
+ const path = getFilePathWithoutDefaultDocument({
11
+ root: options.root,
12
+ filename
13
+ });
14
+ return path;
15
+ };
16
+ var getFilePathWithoutDefaultDocument = (options) => {
17
+ let root = options.root || "";
18
+ let filename = options.filename;
19
+ if (/(?:^|[\/\\])\.\.(?:$|[\/\\])/.test(filename)) {
20
+ return;
21
+ }
14
22
  filename = filename.replace(/^\.?[\/\\]/, "");
15
23
  filename = filename.replace(/\\/, "/");
16
24
  root = root.replace(/\/$/, "");
@@ -19,5 +27,6 @@ var getFilePath = (options) => {
19
27
  return path;
20
28
  };
21
29
  export {
22
- getFilePath
30
+ getFilePath,
31
+ getFilePathWithoutDefaultDocument
23
32
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hono",
3
- "version": "4.0.5",
3
+ "version": "4.0.7",
4
4
  "description": "Ultrafast web framework for the Edges",
5
5
  "main": "dist/cjs/index.js",
6
6
  "type": "module",