hono 4.5.4 → 4.5.5

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.
@@ -1,5 +1,6 @@
1
1
  // src/adapter/bun/serve-static.ts
2
2
  import { serveStatic as baseServeStatic } from "../../middleware/serve-static/index.js";
3
+ import { stat } from "node:fs/promises";
3
4
  var serveStatic = (options) => {
4
5
  return async function serveStatic2(c, next) {
5
6
  const getContent = async (path) => {
@@ -10,10 +11,20 @@ var serveStatic = (options) => {
10
11
  const pathResolve = (path) => {
11
12
  return `./${path}`;
12
13
  };
14
+ const isDir = async (path) => {
15
+ let isDir2;
16
+ try {
17
+ const stats = await stat(path);
18
+ isDir2 = stats.isDirectory();
19
+ } catch {
20
+ }
21
+ return isDir2;
22
+ };
13
23
  return baseServeStatic({
14
24
  ...options,
15
25
  getContent,
16
- pathResolve
26
+ pathResolve,
27
+ isDir
17
28
  })(c, next);
18
29
  };
19
30
  };
@@ -1,6 +1,6 @@
1
1
  // src/adapter/deno/serve-static.ts
2
2
  import { serveStatic as baseServeStatic } from "../../middleware/serve-static/index.js";
3
- var { open } = Deno;
3
+ var { open, lstatSync } = Deno;
4
4
  var serveStatic = (options) => {
5
5
  return async function serveStatic2(c, next) {
6
6
  const getContent = async (path) => {
@@ -14,10 +14,20 @@ var serveStatic = (options) => {
14
14
  const pathResolve = (path) => {
15
15
  return `./${path}`;
16
16
  };
17
+ const isDir = (path) => {
18
+ let isDir2;
19
+ try {
20
+ const stat = lstatSync(path);
21
+ isDir2 = stat.isDirectory;
22
+ } catch {
23
+ }
24
+ return isDir2;
25
+ };
17
26
  return baseServeStatic({
18
27
  ...options,
19
28
  getContent,
20
- pathResolve
29
+ pathResolve,
30
+ isDir
21
31
  })(c, next);
22
32
  };
23
33
  };
@@ -22,6 +22,7 @@ __export(serve_static_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(serve_static_exports);
24
24
  var import_serve_static = require("../../middleware/serve-static");
25
+ var import_promises = require("node:fs/promises");
25
26
  const serveStatic = (options) => {
26
27
  return async function serveStatic2(c, next) {
27
28
  const getContent = async (path) => {
@@ -32,10 +33,20 @@ const serveStatic = (options) => {
32
33
  const pathResolve = (path) => {
33
34
  return `./${path}`;
34
35
  };
36
+ const isDir = async (path) => {
37
+ let isDir2;
38
+ try {
39
+ const stats = await (0, import_promises.stat)(path);
40
+ isDir2 = stats.isDirectory();
41
+ } catch {
42
+ }
43
+ return isDir2;
44
+ };
35
45
  return (0, import_serve_static.serveStatic)({
36
46
  ...options,
37
47
  getContent,
38
- pathResolve
48
+ pathResolve,
49
+ isDir
39
50
  })(c, next);
40
51
  };
41
52
  };
@@ -22,7 +22,7 @@ __export(serve_static_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(serve_static_exports);
24
24
  var import_serve_static = require("../../middleware/serve-static");
25
- const { open } = Deno;
25
+ const { open, lstatSync } = Deno;
26
26
  const serveStatic = (options) => {
27
27
  return async function serveStatic2(c, next) {
28
28
  const getContent = async (path) => {
@@ -36,10 +36,20 @@ const serveStatic = (options) => {
36
36
  const pathResolve = (path) => {
37
37
  return `./${path}`;
38
38
  };
39
+ const isDir = (path) => {
40
+ let isDir2;
41
+ try {
42
+ const stat = lstatSync(path);
43
+ isDir2 = stat.isDirectory;
44
+ } catch {
45
+ }
46
+ return isDir2;
47
+ };
39
48
  return (0, import_serve_static.serveStatic)({
40
49
  ...options,
41
50
  getContent,
42
- pathResolve
51
+ pathResolve,
52
+ isDir
43
53
  })(c, next);
44
54
  };
45
55
  };
@@ -208,7 +208,9 @@ class JSXFunctionNode extends JSXNode {
208
208
  ...this.props,
209
209
  children: children.length <= 1 ? children[0] : children
210
210
  });
211
- if (res instanceof Promise) {
211
+ if (typeof res === "boolean" || res == null) {
212
+ return;
213
+ } else if (res instanceof Promise) {
212
214
  if (import_context.globalContexts.length === 0) {
213
215
  buffer.unshift("", res);
214
216
  } else {
@@ -303,11 +305,11 @@ const shallowEqual = (a, b) => {
303
305
  return true;
304
306
  };
305
307
  const memo = (component, propsAreEqual = shallowEqual) => {
306
- let computed = void 0;
308
+ let computed = null;
307
309
  let prevProps = void 0;
308
310
  return (props) => {
309
311
  if (prevProps && !propsAreEqual(prevProps, props)) {
310
- computed = void 0;
312
+ computed = null;
311
313
  }
312
314
  prevProps = props;
313
315
  return computed ||= component(props);
@@ -34,6 +34,15 @@ const serveStatic = (options) => {
34
34
  let filename = options.path ?? decodeURI(c.req.path);
35
35
  filename = options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename;
36
36
  const root = options.root;
37
+ if (!filename.endsWith("/") && options.isDir) {
38
+ const path2 = (0, import_filepath.getFilePathWithoutDefaultDocument)({
39
+ filename,
40
+ root
41
+ });
42
+ if (path2 && await options.isDir(path2)) {
43
+ filename = filename + "/";
44
+ }
45
+ }
37
46
  let path = (0, import_filepath.getFilePath)({
38
47
  filename,
39
48
  root,
package/dist/jsx/base.js CHANGED
@@ -171,7 +171,9 @@ var JSXFunctionNode = class extends JSXNode {
171
171
  ...this.props,
172
172
  children: children.length <= 1 ? children[0] : children
173
173
  });
174
- if (res instanceof Promise) {
174
+ if (typeof res === "boolean" || res == null) {
175
+ return;
176
+ } else if (res instanceof Promise) {
175
177
  if (globalContexts.length === 0) {
176
178
  buffer.unshift("", res);
177
179
  } else {
@@ -266,11 +268,11 @@ var shallowEqual = (a, b) => {
266
268
  return true;
267
269
  };
268
270
  var memo = (component, propsAreEqual = shallowEqual) => {
269
- let computed = void 0;
271
+ let computed = null;
270
272
  let prevProps = void 0;
271
273
  return (props) => {
272
274
  if (prevProps && !propsAreEqual(prevProps, props)) {
273
- computed = void 0;
275
+ computed = null;
274
276
  }
275
277
  prevProps = props;
276
278
  return computed ||= component(props);
@@ -12,6 +12,15 @@ var serveStatic = (options) => {
12
12
  let filename = options.path ?? decodeURI(c.req.path);
13
13
  filename = options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename;
14
14
  const root = options.root;
15
+ if (!filename.endsWith("/") && options.isDir) {
16
+ const path2 = getFilePathWithoutDefaultDocument({
17
+ filename,
18
+ root
19
+ });
20
+ if (path2 && await options.isDir(path2)) {
21
+ filename = filename + "/";
22
+ }
23
+ }
15
24
  let path = getFilePath({
16
25
  filename,
17
26
  root,
@@ -3,7 +3,8 @@ import type { Result } from './router';
3
3
  import type { Env, FetchEventLike, H, Input, NotFoundHandler, RouterRoute, TypedResponse } from './types';
4
4
  import type { RedirectStatusCode, StatusCode } from './utils/http-status';
5
5
  import type { InvalidJSONValue, IsAny, JSONParsed, JSONValue, SimplifyDeepArray } from './utils/types';
6
- type HeaderRecord = Record<string, string | string[]>;
6
+ import type { BaseMime } from './utils/mime';
7
+ type HeaderRecord = Record<'Content-Type', BaseMime> | Record<ResponseHeader, string | string[]> | Record<string, string | string[]>;
7
8
  /**
8
9
  * Data type can be a string, ArrayBuffer, or ReadableStream.
9
10
  */
@@ -158,6 +159,21 @@ type ContextOptions<E extends Env> = {
158
159
  matchResult?: Result<[H, RouterRoute]>;
159
160
  path?: string;
160
161
  };
162
+ interface SetHeadersOptions {
163
+ append?: boolean;
164
+ }
165
+ type ResponseHeader = 'Access-Control-Allow-Credentials' | 'Access-Control-Allow-Headers' | 'Access-Control-Allow-Methods' | 'Access-Control-Allow-Origin' | 'Access-Control-Expose-Headers' | 'Access-Control-Max-Age' | 'Age' | 'Allow' | 'Cache-Control' | 'Clear-Site-Data' | 'Content-Disposition' | 'Content-Encoding' | 'Content-Language' | 'Content-Length' | 'Content-Location' | 'Content-Range' | 'Content-Security-Policy' | 'Content-Security-Policy-Report-Only' | 'Content-Type' | 'Cookie' | 'Cross-Origin-Embedder-Policy' | 'Cross-Origin-Opener-Policy' | 'Cross-Origin-Resource-Policy' | 'Date' | 'ETag' | 'Expires' | 'Last-Modified' | 'Location' | 'Permissions-Policy' | 'Pragma' | 'Retry-After' | 'Save-Data' | 'Sec-CH-Prefers-Color-Scheme' | 'Sec-CH-Prefers-Reduced-Motion' | 'Sec-CH-UA' | 'Sec-CH-UA-Arch' | 'Sec-CH-UA-Bitness' | 'Sec-CH-UA-Form-Factor' | 'Sec-CH-UA-Full-Version' | 'Sec-CH-UA-Full-Version-List' | 'Sec-CH-UA-Mobile' | 'Sec-CH-UA-Model' | 'Sec-CH-UA-Platform' | 'Sec-CH-UA-Platform-Version' | 'Sec-CH-UA-WoW64' | 'Sec-Fetch-Dest' | 'Sec-Fetch-Mode' | 'Sec-Fetch-Site' | 'Sec-Fetch-User' | 'Sec-GPC' | 'Server' | 'Server-Timing' | 'Service-Worker-Navigation-Preload' | 'Set-Cookie' | 'Strict-Transport-Security' | 'Timing-Allow-Origin' | 'Trailer' | 'Transfer-Encoding' | 'Upgrade' | 'Vary' | 'WWW-Authenticate' | 'Warning' | 'X-Content-Type-Options' | 'X-DNS-Prefetch-Control' | 'X-Frame-Options' | 'X-Permitted-Cross-Domain-Policies' | 'X-Powered-By' | 'X-Robots-Tag' | 'X-XSS-Protection';
166
+ interface SetHeaders {
167
+ (name: 'Content-Type', value?: BaseMime, options?: SetHeadersOptions): void;
168
+ (name: ResponseHeader, value?: string, options?: SetHeadersOptions): void;
169
+ (name: string, value?: string, options?: SetHeadersOptions): void;
170
+ }
171
+ type ResponseHeadersInit = [string, string][] | Record<'Content-Type', BaseMime> | Record<ResponseHeader, string> | Record<string, string> | Headers;
172
+ interface ResponseInit {
173
+ headers?: ResponseHeadersInit;
174
+ status?: number;
175
+ statusText?: string;
176
+ }
161
177
  export declare const TEXT_PLAIN = "text/plain; charset=UTF-8";
162
178
  export declare class Context<E extends Env = any, P extends string = any, I extends Input = {}> {
163
179
  #private;
@@ -298,9 +314,7 @@ export declare class Context<E extends Env = any, P extends string = any, I exte
298
314
  * })
299
315
  * ```
300
316
  */
301
- header: (name: string, value: string | undefined, options?: {
302
- append?: boolean;
303
- }) => void;
317
+ header: SetHeaders;
304
318
  status: (status: StatusCode) => void;
305
319
  /**
306
320
  * `.set()` can set the value specified by the key.
@@ -3,7 +3,7 @@ import type { Context } from './context';
3
3
  import type { JSX as HonoJSX, IntrinsicElements as IntrinsicElementsDefined } from './intrinsic-elements';
4
4
  export type Props = Record<string, any>;
5
5
  export type FC<P = Props> = {
6
- (props: P): HtmlEscapedString | Promise<HtmlEscapedString>;
6
+ (props: P): HtmlEscapedString | Promise<HtmlEscapedString> | null;
7
7
  defaultProps?: Partial<P> | undefined;
8
8
  displayName?: string | undefined;
9
9
  };
@@ -149,7 +149,7 @@ export declare namespace JSX {
149
149
  contenteditable?: boolean | 'inherit' | undefined;
150
150
  contextmenu?: string | undefined;
151
151
  dir?: string | undefined;
152
- draggable?: 'true' | 'false' | undefined;
152
+ draggable?: 'true' | 'false' | boolean | undefined;
153
153
  enterkeyhint?: 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send' | undefined;
154
154
  hidden?: boolean | undefined;
155
155
  id?: string | undefined;
@@ -17,4 +17,5 @@ export type ServeStaticOptions<E extends Env = Env> = {
17
17
  export declare const serveStatic: <E extends Env = Env>(options: ServeStaticOptions<E> & {
18
18
  getContent: (path: string, c: Context<E, any, {}>) => Promise<Data | Response | null>;
19
19
  pathResolve?: ((path: string) => string) | undefined;
20
+ isDir?: ((path: string) => boolean | undefined | Promise<boolean | undefined>) | undefined;
20
21
  }) => MiddlewareHandler;
@@ -5,4 +5,8 @@
5
5
  export declare const getMimeType: (filename: string, mimes?: Record<string, string>) => string | undefined;
6
6
  export declare const getExtension: (mimeType: string) => string | undefined;
7
7
  export { baseMimes as mimes };
8
- declare const baseMimes: Record<string, string>;
8
+ /**
9
+ * Union types for BaseMime
10
+ */
11
+ export type BaseMime = 'audio/aac' | 'video/x-msvideo' | 'image/avif' | 'video/av1' | 'application/octet-stream' | 'image/bmp' | 'text/css' | 'text/csv' | 'application/vnd.ms-fontobject' | 'application/epub+zip' | 'image/gif' | 'application/gzip' | 'text/html' | 'image/x-icon' | 'text/calendar' | 'image/jpeg' | 'text/javascript' | 'application/json' | 'application/ld+json' | 'audio/x-midi' | 'audio/mpeg' | 'video/mp4' | 'video/mpeg' | 'audio/ogg' | 'video/ogg' | 'application/ogg' | 'audio/opus' | 'font/otf' | 'application/pdf' | 'image/png' | 'application/rtf' | 'image/svg+xml' | 'image/tiff' | 'video/mp2t' | 'font/ttf' | 'text/plain' | 'application/wasm' | 'video/webm' | 'audio/webm' | 'image/webp' | 'font/woff' | 'font/woff2' | 'application/xhtml+xml' | 'application/xml' | 'application/zip' | 'video/3gpp' | 'video/3gpp2' | 'model/gltf+json' | 'model/gltf-binary';
12
+ declare const baseMimes: Record<string, BaseMime>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hono",
3
- "version": "4.5.4",
3
+ "version": "4.5.5",
4
4
  "description": "Web framework built on Web Standards",
5
5
  "main": "dist/cjs/index.js",
6
6
  "type": "module",