hono 4.5.9 → 4.5.10

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.
@@ -22,9 +22,16 @@ __export(compress_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(compress_exports);
24
24
  const ENCODING_TYPES = ["gzip", "deflate"];
25
+ const cacheControlNoTransformRegExp = /(?:^|,)\s*?no-transform\s*?(?:,|$)/i;
26
+ const compressibleContentTypeRegExp = /^\s*(?:text\/[^;\s]+|application\/(?:javascript|json|xml|xml-dtd|ecmascript|dart|postscript|rtf|tar|toml|vnd\.dart|vnd\.ms-fontobject|vnd\.ms-opentype|wasm|x-httpd-php|x-javascript|x-ns-proxy-autoconfig|x-sh|x-tar|x-virtualbox-hdd|x-virtualbox-ova|x-virtualbox-ovf|x-virtualbox-vbox|x-virtualbox-vdi|x-virtualbox-vhd|x-virtualbox-vmdk|x-www-form-urlencoded)|font\/(?:otf|ttf)|image\/(?:bmp|vnd\.adobe\.photoshop|vnd\.microsoft\.icon|vnd\.ms-dds|x-icon|x-ms-bmp)|message\/rfc822|model\/gltf-binary|x-shader\/x-fragment|x-shader\/x-vertex|[^;\s]+?\+(?:json|text|xml|yaml))(?:[;\s]|$)/i;
25
27
  const compress = (options) => {
28
+ const threshold = options?.threshold ?? 1024;
26
29
  return async function compress2(ctx, next) {
27
30
  await next();
31
+ const contentLength = ctx.res.headers.get("Content-Length");
32
+ if (ctx.res.headers.has("Content-Encoding") || ctx.req.method === "HEAD" || contentLength && Number(contentLength) < threshold || !shouldCompress(ctx.res) || !shouldTransform(ctx.res)) {
33
+ return;
34
+ }
28
35
  const accepted = ctx.req.header("Accept-Encoding");
29
36
  const encoding = options?.encoding ?? ENCODING_TYPES.find((encoding2) => accepted?.includes(encoding2));
30
37
  if (!encoding || !ctx.res.body) {
@@ -36,6 +43,14 @@ const compress = (options) => {
36
43
  ctx.res.headers.set("Content-Encoding", encoding);
37
44
  };
38
45
  };
46
+ const shouldCompress = (res) => {
47
+ const type = res.headers.get("Content-Type");
48
+ return type && compressibleContentTypeRegExp.test(type);
49
+ };
50
+ const shouldTransform = (res) => {
51
+ const cacheControl = res.headers.get("Cache-Control");
52
+ return !cacheControl || !cacheControlNoTransformRegExp.test(cacheControl);
53
+ };
39
54
  // Annotate the CommonJS export names for ESM import in node:
40
55
  0 && (module.exports = {
41
56
  compress
@@ -53,7 +53,7 @@ const colorStatus = (status) => {
53
53
  return out[calculateStatus];
54
54
  };
55
55
  function log(fn, prefix, method, path, status = 0, elapsed) {
56
- const out = prefix === "<--" /* Incoming */ ? ` ${prefix} ${method} ${path}` : ` ${prefix} ${method} ${path} ${colorStatus(status)} ${elapsed}`;
56
+ const out = prefix === "<--" /* Incoming */ ? `${prefix} ${method} ${path}` : `${prefix} ${method} ${path} ${colorStatus(status)} ${elapsed}`;
57
57
  fn(out);
58
58
  }
59
59
  const logger = (fn = console.log) => {
@@ -1,8 +1,15 @@
1
1
  // src/middleware/compress/index.ts
2
2
  var ENCODING_TYPES = ["gzip", "deflate"];
3
+ var cacheControlNoTransformRegExp = /(?:^|,)\s*?no-transform\s*?(?:,|$)/i;
4
+ var compressibleContentTypeRegExp = /^\s*(?:text\/[^;\s]+|application\/(?:javascript|json|xml|xml-dtd|ecmascript|dart|postscript|rtf|tar|toml|vnd\.dart|vnd\.ms-fontobject|vnd\.ms-opentype|wasm|x-httpd-php|x-javascript|x-ns-proxy-autoconfig|x-sh|x-tar|x-virtualbox-hdd|x-virtualbox-ova|x-virtualbox-ovf|x-virtualbox-vbox|x-virtualbox-vdi|x-virtualbox-vhd|x-virtualbox-vmdk|x-www-form-urlencoded)|font\/(?:otf|ttf)|image\/(?:bmp|vnd\.adobe\.photoshop|vnd\.microsoft\.icon|vnd\.ms-dds|x-icon|x-ms-bmp)|message\/rfc822|model\/gltf-binary|x-shader\/x-fragment|x-shader\/x-vertex|[^;\s]+?\+(?:json|text|xml|yaml))(?:[;\s]|$)/i;
3
5
  var compress = (options) => {
6
+ const threshold = options?.threshold ?? 1024;
4
7
  return async function compress2(ctx, next) {
5
8
  await next();
9
+ const contentLength = ctx.res.headers.get("Content-Length");
10
+ if (ctx.res.headers.has("Content-Encoding") || ctx.req.method === "HEAD" || contentLength && Number(contentLength) < threshold || !shouldCompress(ctx.res) || !shouldTransform(ctx.res)) {
11
+ return;
12
+ }
6
13
  const accepted = ctx.req.header("Accept-Encoding");
7
14
  const encoding = options?.encoding ?? ENCODING_TYPES.find((encoding2) => accepted?.includes(encoding2));
8
15
  if (!encoding || !ctx.res.body) {
@@ -14,6 +21,14 @@ var compress = (options) => {
14
21
  ctx.res.headers.set("Content-Encoding", encoding);
15
22
  };
16
23
  };
24
+ var shouldCompress = (res) => {
25
+ const type = res.headers.get("Content-Type");
26
+ return type && compressibleContentTypeRegExp.test(type);
27
+ };
28
+ var shouldTransform = (res) => {
29
+ const cacheControl = res.headers.get("Cache-Control");
30
+ return !cacheControl || !cacheControlNoTransformRegExp.test(cacheControl);
31
+ };
17
32
  export {
18
33
  compress
19
34
  };
@@ -25,7 +25,7 @@ var colorStatus = (status) => {
25
25
  return out[calculateStatus];
26
26
  };
27
27
  function log(fn, prefix, method, path, status = 0, elapsed) {
28
- const out = prefix === "<--" /* Incoming */ ? ` ${prefix} ${method} ${path}` : ` ${prefix} ${method} ${path} ${colorStatus(status)} ${elapsed}`;
28
+ const out = prefix === "<--" /* Incoming */ ? `${prefix} ${method} ${path}` : `${prefix} ${method} ${path} ${colorStatus(status)} ${elapsed}`;
29
29
  fn(out);
30
30
  }
31
31
  var logger = (fn = console.log) => {
@@ -166,7 +166,8 @@ export declare namespace JSX {
166
166
  lang?: string | undefined;
167
167
  nonce?: string | undefined;
168
168
  placeholder?: string | undefined;
169
- popover?: string | undefined;
169
+ /** @see https://developer.mozilla.org/en-US/docs/Web/API/Popover_API */
170
+ popover?: boolean | 'auto' | 'manual' | undefined;
170
171
  slot?: string | undefined;
171
172
  spellcheck?: boolean | undefined;
172
173
  style?: CSSProperties | string | undefined;
@@ -207,16 +208,20 @@ export declare namespace JSX {
207
208
  interface BlockquoteHTMLAttributes extends HTMLAttributes {
208
209
  cite?: string | undefined;
209
210
  }
211
+ /** @see https://developer.mozilla.org/en-US/docs/Web/API/Popover_API */
212
+ type HTMLAttributePopoverTargetAction = 'show' | 'hide' | 'toggle';
210
213
  interface ButtonHTMLAttributes extends HTMLAttributes {
211
214
  disabled?: boolean | undefined;
212
215
  form?: string | undefined;
213
- formenctype?: string | undefined;
214
- formmethod?: string | undefined;
216
+ formenctype?: HTMLAttributeFormEnctype | undefined;
217
+ formmethod?: HTMLAttributeFormMethod | undefined;
215
218
  formnovalidate?: boolean | undefined;
216
219
  formtarget?: HTMLAttributeAnchorTarget | undefined;
217
220
  name?: string | undefined;
218
221
  type?: 'submit' | 'reset' | 'button' | undefined;
219
222
  value?: string | ReadonlyArray<string> | number | undefined;
223
+ popovertarget?: string | undefined;
224
+ popovertargetaction?: HTMLAttributePopoverTargetAction | undefined;
220
225
  formAction?: string | Function | undefined;
221
226
  }
222
227
  interface CanvasHTMLAttributes extends HTMLAttributes {
@@ -254,11 +259,17 @@ export declare namespace JSX {
254
259
  form?: string | undefined;
255
260
  name?: string | undefined;
256
261
  }
262
+ /** @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#method */
263
+ type HTMLAttributeFormMethod = 'get' | 'post' | 'dialog';
264
+ /** @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#enctype */
265
+ type HTMLAttributeFormEnctype = 'application/x-www-form-urlencoded' | 'multipart/form-data' | 'text/plain';
266
+ /** @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#autocomplete */
267
+ type HTMLAttributeFormAutocomplete = 'on' | 'off';
257
268
  interface FormHTMLAttributes extends HTMLAttributes {
258
- 'accept-charset'?: string | undefined;
259
- autocomplete?: string | undefined;
260
- enctype?: string | undefined;
261
- method?: string | undefined;
269
+ 'accept-charset'?: StringLiteralUnion<'utf-8'> | undefined;
270
+ autocomplete?: HTMLAttributeFormAutocomplete | undefined;
271
+ enctype?: HTMLAttributeFormEnctype | undefined;
272
+ method?: HTMLAttributeFormMethod | undefined;
262
273
  name?: string | undefined;
263
274
  novalidate?: boolean | undefined;
264
275
  target?: HTMLAttributeAnchorTarget | undefined;
@@ -317,8 +328,8 @@ export declare namespace JSX {
317
328
  checked?: boolean | undefined;
318
329
  disabled?: boolean | undefined;
319
330
  form?: string | undefined;
320
- formenctype?: string | undefined;
321
- formmethod?: string | undefined;
331
+ formenctype?: HTMLAttributeFormEnctype | undefined;
332
+ formmethod?: HTMLAttributeFormMethod | undefined;
322
333
  formnovalidate?: boolean | undefined;
323
334
  formtarget?: HTMLAttributeAnchorTarget | undefined;
324
335
  height?: number | string | undefined;
@@ -339,6 +350,8 @@ export declare namespace JSX {
339
350
  type?: HTMLInputTypeAttribute | undefined;
340
351
  value?: string | ReadonlyArray<string> | number | undefined;
341
352
  width?: number | string | undefined;
353
+ popovertarget?: string | undefined;
354
+ popovertargetaction?: HTMLAttributePopoverTargetAction | undefined;
342
355
  formAction?: string | Function | undefined;
343
356
  }
344
357
  interface KeygenHTMLAttributes extends HTMLAttributes {
@@ -6,6 +6,7 @@ import type { MiddlewareHandler } from '../../types';
6
6
  declare const ENCODING_TYPES: readonly ["gzip", "deflate"];
7
7
  interface CompressionOptions {
8
8
  encoding?: (typeof ENCODING_TYPES)[number];
9
+ threshold?: number;
9
10
  }
10
11
  /**
11
12
  * Compress Middleware for Hono.
@@ -14,6 +15,7 @@ interface CompressionOptions {
14
15
  *
15
16
  * @param {CompressionOptions} [options] - The options for the compress middleware.
16
17
  * @param {'gzip' | 'deflate'} [options.encoding] - The compression scheme to allow for response compression. Either 'gzip' or 'deflate'. If not defined, both are allowed and will be used based on the Accept-Encoding header. 'gzip' is prioritized if this option is not provided and the client provides both in the Accept-Encoding header.
18
+ * @param {number} [options.threshold=1024] - The minimum size in bytes to compress. Defaults to 1024 bytes.
17
19
  * @returns {MiddlewareHandler} The middleware handler function.
18
20
  *
19
21
  * @example
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hono",
3
- "version": "4.5.9",
3
+ "version": "4.5.10",
4
4
  "description": "Web framework built on Web Standards",
5
5
  "main": "dist/cjs/index.js",
6
6
  "type": "module",
@@ -617,7 +617,7 @@
617
617
  "@types/jsdom": "^21.1.4",
618
618
  "@types/node": "20.11.4",
619
619
  "@types/supertest": "^2.0.12",
620
- "@vitest/coverage-v8": "^1.1.0",
620
+ "@vitest/coverage-v8": "^2.0.5",
621
621
  "arg": "^5.0.2",
622
622
  "crypto-js": "^4.1.1",
623
623
  "esbuild": "^0.15.12",
@@ -631,7 +631,7 @@
631
631
  "supertest": "^6.3.3",
632
632
  "typescript": "^5.3.3",
633
633
  "vite-plugin-fastly-js-compute": "^0.4.2",
634
- "vitest": "^1.2.2",
634
+ "vitest": "^2.0.5",
635
635
  "wrangler": "^3.58.0",
636
636
  "ws": "^8.17.0",
637
637
  "zod": "^3.20.2"