@depup/hono 4.13.7-depup.0 → 4.13.9-depup.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -13,8 +13,8 @@ npm install @depup/hono
13
13
 
14
14
  | Field | Value |
15
15
  |-------|-------|
16
- | Original | [hono](https://www.npmjs.com/package/hono) @ 4.13.7 |
17
- | Processed | 2026-09-05 |
16
+ | Original | [hono](https://www.npmjs.com/package/hono) @ 4.13.9 |
17
+ | Processed | 2026-09-24 |
18
18
  | Smoke test | passed |
19
19
  | Deps updated | 0 |
20
20
 
package/changes.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "bumped": {},
3
- "timestamp": "2026-09-05T00:31:16.725Z",
3
+ "timestamp": "2026-09-24T08:12:48.055Z",
4
4
  "totalUpdated": 0
5
5
  }
@@ -1,4 +1,5 @@
1
1
  // src/adapter/aws-lambda/handler.ts
2
+ import { pipeline } from "node:stream/promises";
2
3
  import { decodeBase64, encodeBase64 } from "../../utils/encode.js";
3
4
  function sanitizeHeaderValue(value) {
4
5
  const hasNonAscii = /[^\x00-\x7F]/.test(value);
@@ -10,14 +11,14 @@ function sanitizeHeaderValue(value) {
10
11
  var getRequestContext = (event) => {
11
12
  return event.requestContext;
12
13
  };
13
- var streamToNodeStream = async (reader, writer) => {
14
+ async function* readWebStream(reader) {
14
15
  let readResult = await reader.read();
15
16
  while (!readResult.done) {
16
- writer.write(readResult.value);
17
+ yield readResult.value;
17
18
  readResult = await reader.read();
18
19
  }
19
- writer.end();
20
- };
20
+ }
21
+ var streamToNodeStream = (reader, writer) => pipeline(readWebStream(reader), writer);
21
22
  var streamHandle = (app) => {
22
23
  return awslambda.streamifyResponse(
23
24
  async (event, responseStream, context) => {
@@ -201,7 +202,7 @@ var EventV1Processor = class extends EventProcessor {
201
202
  ([key, values]) => values.map((value) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join("&")
202
203
  ).join("&");
203
204
  } else {
204
- return Object.entries(event.queryStringParameters || {}).filter(([, value]) => value).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value || "")}`).join("&");
205
+ return Object.entries(event.queryStringParameters || {}).filter(([, value]) => value !== void 0).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value || "")}`).join("&");
205
206
  }
206
207
  }
207
208
  getCookies(_event, _headers) {
@@ -261,7 +262,7 @@ var ALBProcessor = class extends EventProcessor {
261
262
  if (event.multiValueQueryStringParameters) {
262
263
  return Object.entries(event.multiValueQueryStringParameters || {}).filter(([, value]) => value).map(([key, value]) => `${key}=${value.join(`&${key}=`)}`).join("&");
263
264
  } else {
264
- return Object.entries(event.queryStringParameters || {}).filter(([, value]) => value).map(([key, value]) => `${key}=${value}`).join("&");
265
+ return Object.entries(event.queryStringParameters || {}).filter(([, value]) => value !== void 0).map(([key, value]) => `${key}=${value}`).join("&");
265
266
  }
266
267
  }
267
268
  getCookies(event, headers) {
@@ -343,7 +344,10 @@ var isLatticeEventV2 = (event) => {
343
344
  return false;
344
345
  };
345
346
  var defaultIsContentTypeBinary = (contentType) => {
346
- return !/^text\/(?:plain|html|css|javascript|csv)|(?:\/|\+)(?:json|xml)\s*(?:;|$)/.test(
347
+ if (/^application\/vnd\.(?:apple\.installer|mozilla\.xul)\+xml\s*(?:;|$)/i.test(contentType)) {
348
+ return true;
349
+ }
350
+ return !/^text\/(?:plain|html|css|javascript|csv)|(?:\/|\+)(?:json|xml)\s*(?:;|$)/i.test(
347
351
  contentType
348
352
  );
349
353
  };
@@ -17,7 +17,8 @@ var handle = (app) => {
17
17
  const [context, callback] = args;
18
18
  let callbackError = null;
19
19
  let callbackResult;
20
- const res = await app.fetch(createRequest(event), {
20
+ const cf = getCloudFrontRecord(event);
21
+ const res = await app.fetch(createRequest(cf), {
21
22
  event,
22
23
  context,
23
24
  callback: (err, result) => {
@@ -27,9 +28,9 @@ var handle = (app) => {
27
28
  }
28
29
  callback?.(err, result);
29
30
  },
30
- config: event.Records[0].cf.config,
31
- request: event.Records[0].cf.request,
32
- response: event.Records[0].cf.response
31
+ config: cf.config,
32
+ request: cf.request,
33
+ response: cf.response
33
34
  });
34
35
  if (callbackError) {
35
36
  throw callbackError;
@@ -48,17 +49,27 @@ var createResult = async (res) => {
48
49
  ...isBase64Encoded && { bodyEncoding: "base64" }
49
50
  };
50
51
  };
51
- var createRequest = (event) => {
52
- const queryString = event.Records[0].cf.request.querystring;
53
- const host = event.Records[0].cf.request.headers?.host?.[0]?.value || event.Records[0].cf.config.distributionDomainName;
54
- const urlPath = `https://${host}${event.Records[0].cf.request.uri}`;
52
+ var getCloudFrontRecord = (event) => {
53
+ const cf = event?.Records?.[0]?.cf;
54
+ if (!cf?.request) {
55
+ throw new TypeError(
56
+ "Unable to map the CloudFront event to a Request: expected `Records[0].cf.request` in the Lambda@Edge event."
57
+ );
58
+ }
59
+ return cf;
60
+ };
61
+ var createRequest = (cf) => {
62
+ const request = cf.request;
63
+ const queryString = request.querystring;
64
+ const host = request.headers?.host?.[0]?.value || cf.config?.distributionDomainName;
65
+ const urlPath = `https://${host}${request.uri}`;
55
66
  const url = queryString ? `${urlPath}?${queryString}` : urlPath;
56
67
  const headers = new Headers();
57
- Object.entries(event.Records[0].cf.request.headers).forEach(([k, v]) => {
68
+ Object.entries(request.headers ?? {}).forEach(([k, v]) => {
58
69
  v.forEach((header) => headers.append(k, header.value));
59
70
  });
60
- const requestBody = event.Records[0].cf.request.body;
61
- const method = event.Records[0].cf.request.method;
71
+ const requestBody = request.body;
72
+ const method = request.method;
62
73
  const rawBody = createBody(method, requestBody);
63
74
  let body = rawBody;
64
75
  if (rawBody !== void 0) {
@@ -85,7 +96,10 @@ var createBody = (method, requestBody) => {
85
96
  return requestBody.data;
86
97
  };
87
98
  var isContentTypeBinary = (contentType) => {
88
- return !/^(text\/(plain|html|css|javascript|csv).*|application\/(.*json|.*xml).*|image\/svg\+xml.*)$/.test(
99
+ if (/^application\/vnd\.(?:apple\.installer|mozilla\.xul)\+xml\s*(?:;|$)/i.test(contentType)) {
100
+ return true;
101
+ }
102
+ return !/^text\/(?:plain|html|css|javascript|csv)|(?:\/|\+)(?:json|xml)\s*(?:;|$)/i.test(
89
103
  contentType
90
104
  );
91
105
  };
@@ -29,6 +29,7 @@ __export(handler_exports, {
29
29
  streamHandle: () => streamHandle
30
30
  });
31
31
  module.exports = __toCommonJS(handler_exports);
32
+ var import_promises = require("node:stream/promises");
32
33
  var import_encode = require("../../utils/encode");
33
34
  function sanitizeHeaderValue(value) {
34
35
  const hasNonAscii = /[^\x00-\x7F]/.test(value);
@@ -40,14 +41,14 @@ function sanitizeHeaderValue(value) {
40
41
  const getRequestContext = (event) => {
41
42
  return event.requestContext;
42
43
  };
43
- const streamToNodeStream = async (reader, writer) => {
44
+ async function* readWebStream(reader) {
44
45
  let readResult = await reader.read();
45
46
  while (!readResult.done) {
46
- writer.write(readResult.value);
47
+ yield readResult.value;
47
48
  readResult = await reader.read();
48
49
  }
49
- writer.end();
50
- };
50
+ }
51
+ const streamToNodeStream = (reader, writer) => (0, import_promises.pipeline)(readWebStream(reader), writer);
51
52
  const streamHandle = (app) => {
52
53
  return awslambda.streamifyResponse(
53
54
  async (event, responseStream, context) => {
@@ -231,7 +232,7 @@ class EventV1Processor extends EventProcessor {
231
232
  ([key, values]) => values.map((value) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join("&")
232
233
  ).join("&");
233
234
  } else {
234
- return Object.entries(event.queryStringParameters || {}).filter(([, value]) => value).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value || "")}`).join("&");
235
+ return Object.entries(event.queryStringParameters || {}).filter(([, value]) => value !== void 0).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value || "")}`).join("&");
235
236
  }
236
237
  }
237
238
  getCookies(_event, _headers) {
@@ -291,7 +292,7 @@ class ALBProcessor extends EventProcessor {
291
292
  if (event.multiValueQueryStringParameters) {
292
293
  return Object.entries(event.multiValueQueryStringParameters || {}).filter(([, value]) => value).map(([key, value]) => `${key}=${value.join(`&${key}=`)}`).join("&");
293
294
  } else {
294
- return Object.entries(event.queryStringParameters || {}).filter(([, value]) => value).map(([key, value]) => `${key}=${value}`).join("&");
295
+ return Object.entries(event.queryStringParameters || {}).filter(([, value]) => value !== void 0).map(([key, value]) => `${key}=${value}`).join("&");
295
296
  }
296
297
  }
297
298
  getCookies(event, headers) {
@@ -373,7 +374,10 @@ const isLatticeEventV2 = (event) => {
373
374
  return false;
374
375
  };
375
376
  const defaultIsContentTypeBinary = (contentType) => {
376
- return !/^text\/(?:plain|html|css|javascript|csv)|(?:\/|\+)(?:json|xml)\s*(?:;|$)/.test(
377
+ if (/^application\/vnd\.(?:apple\.installer|mozilla\.xul)\+xml\s*(?:;|$)/i.test(contentType)) {
378
+ return true;
379
+ }
380
+ return !/^text\/(?:plain|html|css|javascript|csv)|(?:\/|\+)(?:json|xml)\s*(?:;|$)/i.test(
377
381
  contentType
378
382
  );
379
383
  };
@@ -50,7 +50,8 @@ const handle = (app) => {
50
50
  const [context, callback] = args;
51
51
  let callbackError = null;
52
52
  let callbackResult;
53
- const res = await app.fetch(createRequest(event), {
53
+ const cf = getCloudFrontRecord(event);
54
+ const res = await app.fetch(createRequest(cf), {
54
55
  event,
55
56
  context,
56
57
  callback: (err, result) => {
@@ -60,9 +61,9 @@ const handle = (app) => {
60
61
  }
61
62
  callback?.(err, result);
62
63
  },
63
- config: event.Records[0].cf.config,
64
- request: event.Records[0].cf.request,
65
- response: event.Records[0].cf.response
64
+ config: cf.config,
65
+ request: cf.request,
66
+ response: cf.response
66
67
  });
67
68
  if (callbackError) {
68
69
  throw callbackError;
@@ -81,17 +82,27 @@ const createResult = async (res) => {
81
82
  ...isBase64Encoded && { bodyEncoding: "base64" }
82
83
  };
83
84
  };
84
- const createRequest = (event) => {
85
- const queryString = event.Records[0].cf.request.querystring;
86
- const host = event.Records[0].cf.request.headers?.host?.[0]?.value || event.Records[0].cf.config.distributionDomainName;
87
- const urlPath = `https://${host}${event.Records[0].cf.request.uri}`;
85
+ const getCloudFrontRecord = (event) => {
86
+ const cf = event?.Records?.[0]?.cf;
87
+ if (!cf?.request) {
88
+ throw new TypeError(
89
+ "Unable to map the CloudFront event to a Request: expected `Records[0].cf.request` in the Lambda@Edge event."
90
+ );
91
+ }
92
+ return cf;
93
+ };
94
+ const createRequest = (cf) => {
95
+ const request = cf.request;
96
+ const queryString = request.querystring;
97
+ const host = request.headers?.host?.[0]?.value || cf.config?.distributionDomainName;
98
+ const urlPath = `https://${host}${request.uri}`;
88
99
  const url = queryString ? `${urlPath}?${queryString}` : urlPath;
89
100
  const headers = new Headers();
90
- Object.entries(event.Records[0].cf.request.headers).forEach(([k, v]) => {
101
+ Object.entries(request.headers ?? {}).forEach(([k, v]) => {
91
102
  v.forEach((header) => headers.append(k, header.value));
92
103
  });
93
- const requestBody = event.Records[0].cf.request.body;
94
- const method = event.Records[0].cf.request.method;
104
+ const requestBody = request.body;
105
+ const method = request.method;
95
106
  const rawBody = createBody(method, requestBody);
96
107
  let body = rawBody;
97
108
  if (rawBody !== void 0) {
@@ -118,7 +129,10 @@ const createBody = (method, requestBody) => {
118
129
  return requestBody.data;
119
130
  };
120
131
  const isContentTypeBinary = (contentType) => {
121
- return !/^(text\/(plain|html|css|javascript|csv).*|application\/(.*json|.*xml).*|image\/svg\+xml.*)$/.test(
132
+ if (/^application\/vnd\.(?:apple\.installer|mozilla\.xul)\+xml\s*(?:;|$)/i.test(contentType)) {
133
+ return true;
134
+ }
135
+ return !/^text\/(?:plain|html|css|javascript|csv)|(?:\/|\+)(?:json|xml)\s*(?:;|$)/i.test(
122
136
  contentType
123
137
  );
124
138
  };
@@ -424,7 +424,7 @@ class Context {
424
424
  const locationString = String(location);
425
425
  this.header(
426
426
  "Location",
427
- // Multibyes should be encoded
427
+ // Multibytes should be encoded
428
428
  // eslint-disable-next-line no-control-regex
429
429
  !/[^\x00-\xFF]/.test(locationString) ? locationString : encodeURI(locationString)
430
430
  );
@@ -23,15 +23,17 @@ __export(accepts_exports, {
23
23
  module.exports = __toCommonJS(accepts_exports);
24
24
  var import_accept = require("../../utils/accept");
25
25
  const matchType = (acceptType, supportedType) => {
26
- if (acceptType === supportedType) {
26
+ const accept = acceptType.toLowerCase();
27
+ const supported = supportedType.toLowerCase();
28
+ if (accept === supported) {
27
29
  return true;
28
30
  }
29
- if (acceptType === "*/*" || acceptType === "*") {
31
+ if (accept === "*/*" || accept === "*") {
30
32
  return false;
31
33
  }
32
- if (acceptType.endsWith("/*")) {
33
- const [acceptMain] = acceptType.split("/");
34
- const [supportedMain] = supportedType.split("/");
34
+ if (accept.endsWith("/*")) {
35
+ const [acceptMain] = accept.split("/");
36
+ const [supportedMain] = supported.split("/");
35
37
  return acceptMain === supportedMain;
36
38
  }
37
39
  return false;
@@ -47,7 +49,7 @@ const getSpecificity = (type) => {
47
49
  };
48
50
  const defaultMatch = (accepts2, config) => {
49
51
  const { supports, default: defaultSupport } = config;
50
- const sortedAccepts = accepts2.slice().sort((a, b) => {
52
+ const sortedAccepts = accepts2.filter((accept) => accept.q > 0).sort((a, b) => {
51
53
  if (b.q !== a.q) {
52
54
  return b.q - a.q;
53
55
  }
@@ -110,7 +110,7 @@ const ErrorBoundary = async ({ children, fallback, fallbackRender, onError }) =>
110
110
  if (resArray.some((res) => res instanceof Promise)) {
111
111
  getResume();
112
112
  const index = errorBoundaryCounter++;
113
- const replaceRe = RegExp(`(<template id="E:${index}"></template>.*?)(.*?)(<!--E:${index}-->)`);
113
+ const replaceRe = RegExp(`(<template id="E:${index}"></template>)(.*?)(<!--E:${index}-->)`, "s");
114
114
  let caught = false;
115
115
  const catchCallback = async ({ error: error2, buffer }) => {
116
116
  if (caught) {
@@ -355,6 +355,17 @@ const applyNodeObject = (node, container, isNew) => {
355
355
  }
356
356
  };
357
357
  const isSameContext = (oldContexts, newContexts) => !!(oldContexts && oldContexts.length === newContexts.length && oldContexts.every((ctx, i) => ctx[1] === newContexts[i][1]));
358
+ const indexChildrenByKey = (children) => {
359
+ const index = /* @__PURE__ */ new Map();
360
+ for (const child of children) {
361
+ const key = child.key;
362
+ if (index.has(key)) {
363
+ return;
364
+ }
365
+ index.set(key, child);
366
+ }
367
+ return index;
368
+ };
358
369
  const fallbackUpdateFnArrayMap = /* @__PURE__ */ new WeakMap();
359
370
  const build = (context, node, children) => {
360
371
  const buildWithPreviousChildren = !children && node.pC;
@@ -368,9 +379,11 @@ const build = (context, node, children) => {
368
379
  foundErrorHandler = children[0][import_constants.DOM_ERROR_HANDLER];
369
380
  context[5].push([context, foundErrorHandler, node]);
370
381
  }
371
- const oldVChildren = buildWithPreviousChildren ? [...node.pC] : node.vC ? [...node.vC] : void 0;
382
+ let oldVChildren = buildWithPreviousChildren ? [...node.pC] : node.vC ? [...node.vC] : void 0;
372
383
  const vChildren = [];
373
384
  let prevNode;
385
+ let scanBudget = (oldVChildren?.length || 0) * 2;
386
+ let oldChildrenByKey;
374
387
  for (let i = 0; i < children.length; i++) {
375
388
  if (Array.isArray(children[i])) {
376
389
  children.splice(i, 1, ...children[i].flat(Infinity));
@@ -389,13 +402,35 @@ const build = (context, node, children) => {
389
402
  }
390
403
  }
391
404
  let oldChild;
392
- if (oldVChildren && oldVChildren.length) {
393
- const i2 = oldVChildren.findIndex(
394
- isNodeString(child) ? (c) => isNodeString(c) : child.key !== void 0 ? (c) => c.key === child.key && c.tag === child.tag : (c) => c.tag === child.tag
395
- );
396
- if (i2 !== -1) {
397
- oldChild = oldVChildren[i2];
398
- oldVChildren.splice(i2, 1);
405
+ if (oldChildrenByKey && child.key === void 0 && !isNodeString(child)) {
406
+ oldVChildren = [...oldChildrenByKey.values()];
407
+ oldChildrenByKey = void 0;
408
+ }
409
+ if (oldChildrenByKey) {
410
+ const key = child.key;
411
+ const candidate = oldChildrenByKey.get(key);
412
+ if (candidate && (isNodeString(child) ? isNodeString(candidate) : candidate.tag === child.tag && candidate.key === key)) {
413
+ oldChild = candidate;
414
+ oldChildrenByKey.delete(key);
415
+ }
416
+ } else if (oldVChildren && oldVChildren.length) {
417
+ const first = oldVChildren[0];
418
+ const isMatchFirst = isNodeString(child) ? isNodeString(first) : !isNodeString(first) && (child.key !== void 0 ? first.key === child.key && first.tag === child.tag : first.tag === child.tag);
419
+ if (isMatchFirst) {
420
+ oldChild = oldVChildren.shift();
421
+ } else {
422
+ const i2 = oldVChildren.findIndex(
423
+ isNodeString(child) ? (c) => isNodeString(c) : child.key !== void 0 ? (c) => c.key === child.key && c.tag === child.tag : (c) => c.tag === child.tag
424
+ );
425
+ scanBudget -= i2 === -1 ? oldVChildren.length : i2;
426
+ if (i2 !== -1) {
427
+ oldChild = oldVChildren[i2];
428
+ oldVChildren.splice(i2, 1);
429
+ }
430
+ if (scanBudget < 0) {
431
+ scanBudget = Infinity;
432
+ oldChildrenByKey = indexChildrenByKey(oldVChildren);
433
+ }
399
434
  }
400
435
  }
401
436
  if (oldChild) {
@@ -441,6 +476,7 @@ const build = (context, node, children) => {
441
476
  prevNode = child;
442
477
  }
443
478
  }
479
+ oldVChildren = oldChildrenByKey ? [...oldChildrenByKey.values()] : oldVChildren;
444
480
  node.vR = buildWithPreviousChildren ? [...node.vC, ...oldVChildren || []] : oldVChildren || [];
445
481
  node.vC = vChildren;
446
482
  if (buildWithPreviousChildren) {
@@ -82,7 +82,7 @@ const Suspense = async ({
82
82
  const content = htmlArray.join("");
83
83
  if (buffer) {
84
84
  buffer[0] = buffer[0].replace(
85
- new RegExp(`<template id="H:${index}"></template>.*?<!--/\\$-->`),
85
+ new RegExp(`<template id="H:${index}"></template>.*?<!--/\\$-->`, "s"),
86
86
  () => content
87
87
  );
88
88
  }
@@ -101,7 +101,10 @@ function detectFromHeader(c, options) {
101
101
  return void 0;
102
102
  }
103
103
  const languages = parseAcceptLanguage(acceptLanguage);
104
- for (const { lang } of languages) {
104
+ for (const { lang, q } of languages) {
105
+ if (q === 0) {
106
+ continue;
107
+ }
105
108
  const normalizedLang = normalizeLanguage(lang, options);
106
109
  if (normalizedLang) {
107
110
  return normalizedLang;
@@ -28,8 +28,14 @@ const prettyJSON = (options) => {
28
28
  await next();
29
29
  const contentType = c.res.headers.get("Content-Type");
30
30
  if (pretty && contentType && jsonContentTypeRegex.test(contentType)) {
31
- const obj = await c.res.json();
31
+ let obj;
32
+ try {
33
+ obj = await c.res.clone().json();
34
+ } catch {
35
+ return;
36
+ }
32
37
  c.res = new Response(JSON.stringify(obj, null, options?.space ?? 2), c.res);
38
+ c.res.headers.delete("Content-Length");
33
39
  }
34
40
  };
35
41
  };
@@ -116,7 +116,10 @@ class HonoRequest {
116
116
  if (anyCachedKey === "json") {
117
117
  body = JSON.stringify(body);
118
118
  }
119
- return new Response(body)[key]();
119
+ const contentType = anyCachedKey === "formData" ? void 0 : raw.headers.get("content-type");
120
+ return new Response(body, {
121
+ headers: contentType ? { "Content-Type": contentType } : void 0
122
+ })[key]();
120
123
  });
121
124
  }
122
125
  return bodyCache[key] = raw[key]();
@@ -108,11 +108,11 @@ class LinearRouter {
108
108
  } else {
109
109
  let endValuePos = path.indexOf("/", pos + 1);
110
110
  if (endValuePos === -1) {
111
- if (pos + 1 === path.length) {
112
- continue ROUTES_LOOP;
113
- }
114
111
  endValuePos = path.length;
115
112
  }
113
+ if (endValuePos === pos + 1) {
114
+ continue ROUTES_LOOP;
115
+ }
116
116
  value = path.slice(pos + 1, endValuePos);
117
117
  pos = endValuePos;
118
118
  }
@@ -201,7 +201,7 @@ const parseAccept = (acceptHeader) => {
201
201
  ;
202
202
  [i, accept] = getNextAcceptValue(acceptHeader, i);
203
203
  if (accept) {
204
- accept.q = parseQuality(accept.params.q);
204
+ accept.q = parseQuality(accept.params.q ?? accept.params.Q);
205
205
  values.push(accept);
206
206
  if (lastAccept && lastAccept.q < accept.q) {
207
207
  requiresSort = true;
@@ -225,16 +225,13 @@ const parseQuality = (qVal) => {
225
225
  return 0;
226
226
  }
227
227
  const num = Number(qVal);
228
- if (num === Infinity) {
228
+ if (Number.isNaN(num)) {
229
229
  return 1;
230
230
  }
231
- if (num === -Infinity) {
231
+ if (num < 0) {
232
232
  return 0;
233
233
  }
234
- if (Number.isNaN(num)) {
235
- return 1;
236
- }
237
- if (num < 0 || num > 1) {
234
+ if (num > 1) {
238
235
  return 1;
239
236
  }
240
237
  return num;
@@ -120,12 +120,13 @@ const verify = async (token, publicKey, algOrOptions) => {
120
120
  }
121
121
  }
122
122
  const headerPayload = token.substring(0, token.lastIndexOf("."));
123
- const verified = await (0, import_jws.verifying)(
124
- publicKey,
125
- alg,
126
- (0, import_encode.decodeBase64Url)(tokenParts[2]),
127
- import_utf8.utf8Encoder.encode(headerPayload)
128
- );
123
+ let signature;
124
+ try {
125
+ signature = (0, import_encode.decodeBase64Url)(tokenParts[2]);
126
+ } catch {
127
+ throw new import_types.JwtTokenInvalid(token);
128
+ }
129
+ const verified = await (0, import_jws.verifying)(publicKey, alg, signature, import_utf8.utf8Encoder.encode(headerPayload));
129
130
  if (!verified) {
130
131
  throw new import_types.JwtTokenSignatureMismatched(token);
131
132
  }
package/dist/context.js CHANGED
@@ -402,7 +402,7 @@ var Context = class {
402
402
  const locationString = String(location);
403
403
  this.header(
404
404
  "Location",
405
- // Multibyes should be encoded
405
+ // Multibytes should be encoded
406
406
  // eslint-disable-next-line no-control-regex
407
407
  !/[^\x00-\xFF]/.test(locationString) ? locationString : encodeURI(locationString)
408
408
  );
@@ -1,15 +1,17 @@
1
1
  // src/helper/accepts/accepts.ts
2
2
  import { parseAccept } from "../../utils/accept.js";
3
3
  var matchType = (acceptType, supportedType) => {
4
- if (acceptType === supportedType) {
4
+ const accept = acceptType.toLowerCase();
5
+ const supported = supportedType.toLowerCase();
6
+ if (accept === supported) {
5
7
  return true;
6
8
  }
7
- if (acceptType === "*/*" || acceptType === "*") {
9
+ if (accept === "*/*" || accept === "*") {
8
10
  return false;
9
11
  }
10
- if (acceptType.endsWith("/*")) {
11
- const [acceptMain] = acceptType.split("/");
12
- const [supportedMain] = supportedType.split("/");
12
+ if (accept.endsWith("/*")) {
13
+ const [acceptMain] = accept.split("/");
14
+ const [supportedMain] = supported.split("/");
13
15
  return acceptMain === supportedMain;
14
16
  }
15
17
  return false;
@@ -25,7 +27,7 @@ var getSpecificity = (type) => {
25
27
  };
26
28
  var defaultMatch = (accepts2, config) => {
27
29
  const { supports, default: defaultSupport } = config;
28
- const sortedAccepts = accepts2.slice().sort((a, b) => {
30
+ const sortedAccepts = accepts2.filter((accept) => accept.q > 0).sort((a, b) => {
29
31
  if (b.q !== a.q) {
30
32
  return b.q - a.q;
31
33
  }
@@ -88,7 +88,7 @@ var ErrorBoundary = async ({ children, fallback, fallbackRender, onError }) => {
88
88
  if (resArray.some((res) => res instanceof Promise)) {
89
89
  getResume();
90
90
  const index = errorBoundaryCounter++;
91
- const replaceRe = RegExp(`(<template id="E:${index}"></template>.*?)(.*?)(<!--E:${index}-->)`);
91
+ const replaceRe = RegExp(`(<template id="E:${index}"></template>)(.*?)(<!--E:${index}-->)`, "s");
92
92
  let caught = false;
93
93
  const catchCallback = async ({ error: error2, buffer }) => {
94
94
  if (caught) {
@@ -332,6 +332,17 @@ var applyNodeObject = (node, container, isNew) => {
332
332
  }
333
333
  };
334
334
  var isSameContext = (oldContexts, newContexts) => !!(oldContexts && oldContexts.length === newContexts.length && oldContexts.every((ctx, i) => ctx[1] === newContexts[i][1]));
335
+ var indexChildrenByKey = (children) => {
336
+ const index = /* @__PURE__ */ new Map();
337
+ for (const child of children) {
338
+ const key = child.key;
339
+ if (index.has(key)) {
340
+ return;
341
+ }
342
+ index.set(key, child);
343
+ }
344
+ return index;
345
+ };
335
346
  var fallbackUpdateFnArrayMap = /* @__PURE__ */ new WeakMap();
336
347
  var build = (context, node, children) => {
337
348
  const buildWithPreviousChildren = !children && node.pC;
@@ -345,9 +356,11 @@ var build = (context, node, children) => {
345
356
  foundErrorHandler = children[0][DOM_ERROR_HANDLER];
346
357
  context[5].push([context, foundErrorHandler, node]);
347
358
  }
348
- const oldVChildren = buildWithPreviousChildren ? [...node.pC] : node.vC ? [...node.vC] : void 0;
359
+ let oldVChildren = buildWithPreviousChildren ? [...node.pC] : node.vC ? [...node.vC] : void 0;
349
360
  const vChildren = [];
350
361
  let prevNode;
362
+ let scanBudget = (oldVChildren?.length || 0) * 2;
363
+ let oldChildrenByKey;
351
364
  for (let i = 0; i < children.length; i++) {
352
365
  if (Array.isArray(children[i])) {
353
366
  children.splice(i, 1, ...children[i].flat(Infinity));
@@ -366,13 +379,35 @@ var build = (context, node, children) => {
366
379
  }
367
380
  }
368
381
  let oldChild;
369
- if (oldVChildren && oldVChildren.length) {
370
- const i2 = oldVChildren.findIndex(
371
- isNodeString(child) ? (c) => isNodeString(c) : child.key !== void 0 ? (c) => c.key === child.key && c.tag === child.tag : (c) => c.tag === child.tag
372
- );
373
- if (i2 !== -1) {
374
- oldChild = oldVChildren[i2];
375
- oldVChildren.splice(i2, 1);
382
+ if (oldChildrenByKey && child.key === void 0 && !isNodeString(child)) {
383
+ oldVChildren = [...oldChildrenByKey.values()];
384
+ oldChildrenByKey = void 0;
385
+ }
386
+ if (oldChildrenByKey) {
387
+ const key = child.key;
388
+ const candidate = oldChildrenByKey.get(key);
389
+ if (candidate && (isNodeString(child) ? isNodeString(candidate) : candidate.tag === child.tag && candidate.key === key)) {
390
+ oldChild = candidate;
391
+ oldChildrenByKey.delete(key);
392
+ }
393
+ } else if (oldVChildren && oldVChildren.length) {
394
+ const first = oldVChildren[0];
395
+ const isMatchFirst = isNodeString(child) ? isNodeString(first) : !isNodeString(first) && (child.key !== void 0 ? first.key === child.key && first.tag === child.tag : first.tag === child.tag);
396
+ if (isMatchFirst) {
397
+ oldChild = oldVChildren.shift();
398
+ } else {
399
+ const i2 = oldVChildren.findIndex(
400
+ isNodeString(child) ? (c) => isNodeString(c) : child.key !== void 0 ? (c) => c.key === child.key && c.tag === child.tag : (c) => c.tag === child.tag
401
+ );
402
+ scanBudget -= i2 === -1 ? oldVChildren.length : i2;
403
+ if (i2 !== -1) {
404
+ oldChild = oldVChildren[i2];
405
+ oldVChildren.splice(i2, 1);
406
+ }
407
+ if (scanBudget < 0) {
408
+ scanBudget = Infinity;
409
+ oldChildrenByKey = indexChildrenByKey(oldVChildren);
410
+ }
376
411
  }
377
412
  }
378
413
  if (oldChild) {
@@ -418,6 +453,7 @@ var build = (context, node, children) => {
418
453
  prevNode = child;
419
454
  }
420
455
  }
456
+ oldVChildren = oldChildrenByKey ? [...oldChildrenByKey.values()] : oldVChildren;
421
457
  node.vR = buildWithPreviousChildren ? [...node.vC, ...oldVChildren || []] : oldVChildren || [];
422
458
  node.vC = vChildren;
423
459
  if (buildWithPreviousChildren) {
@@ -59,7 +59,7 @@ var Suspense = async ({
59
59
  const content = htmlArray.join("");
60
60
  if (buffer) {
61
61
  buffer[0] = buffer[0].replace(
62
- new RegExp(`<template id="H:${index}"></template>.*?<!--/\\$-->`),
62
+ new RegExp(`<template id="H:${index}"></template>.*?<!--/\\$-->`, "s"),
63
63
  () => content
64
64
  );
65
65
  }
@@ -71,7 +71,10 @@ function detectFromHeader(c, options) {
71
71
  return void 0;
72
72
  }
73
73
  const languages = parseAcceptLanguage(acceptLanguage);
74
- for (const { lang } of languages) {
74
+ for (const { lang, q } of languages) {
75
+ if (q === 0) {
76
+ continue;
77
+ }
75
78
  const normalizedLang = normalizeLanguage(lang, options);
76
79
  if (normalizedLang) {
77
80
  return normalizedLang;
@@ -7,8 +7,14 @@ var prettyJSON = (options) => {
7
7
  await next();
8
8
  const contentType = c.res.headers.get("Content-Type");
9
9
  if (pretty && contentType && jsonContentTypeRegex.test(contentType)) {
10
- const obj = await c.res.json();
10
+ let obj;
11
+ try {
12
+ obj = await c.res.clone().json();
13
+ } catch {
14
+ return;
15
+ }
11
16
  c.res = new Response(JSON.stringify(obj, null, options?.space ?? 2), c.res);
17
+ c.res.headers.delete("Content-Length");
12
18
  }
13
19
  };
14
20
  };
package/dist/request.js CHANGED
@@ -94,7 +94,10 @@ var HonoRequest = class {
94
94
  if (anyCachedKey === "json") {
95
95
  body = JSON.stringify(body);
96
96
  }
97
- return new Response(body)[key]();
97
+ const contentType = anyCachedKey === "formData" ? void 0 : raw.headers.get("content-type");
98
+ return new Response(body, {
99
+ headers: contentType ? { "Content-Type": contentType } : void 0
100
+ })[key]();
98
101
  });
99
102
  }
100
103
  return bodyCache[key] = raw[key]();
@@ -87,11 +87,11 @@ var LinearRouter = class {
87
87
  } else {
88
88
  let endValuePos = path.indexOf("/", pos + 1);
89
89
  if (endValuePos === -1) {
90
- if (pos + 1 === path.length) {
91
- continue ROUTES_LOOP;
92
- }
93
90
  endValuePos = path.length;
94
91
  }
92
+ if (endValuePos === pos + 1) {
93
+ continue ROUTES_LOOP;
94
+ }
95
95
  value = path.slice(pos + 1, endValuePos);
96
96
  pos = endValuePos;
97
97
  }
@@ -27,7 +27,7 @@ interface ProxyFetch {
27
27
  * Fetch API wrapper for proxy.
28
28
  * The parameters and return value are the same as for `fetch` (except for the proxy-specific options).
29
29
  *
30
- * The “Accept-Encoding” header is replaced with an encoding that the current runtime can handle.
30
+ * The "Accept-Encoding" header is replaced with an encoding that the current runtime can handle.
31
31
  * Unnecessary response headers are deleted and a Response object is returned that can be returned
32
32
  * as is as a response from the handler.
33
33
  *
@@ -31,7 +31,7 @@ export declare const matchedRoutes: (c: Context) => RouterRoute[];
31
31
  * Get the route path registered within the handler
32
32
  *
33
33
  * @param {Context} c - The context object
34
- * @param {number} index - The index of the root from which to retrieve the path, similar to Array.prototype.at(), where a negative number is the index counted from the end of the matching root. Defaults to the current root index.
34
+ * @param {number} index - The index of the route from which to retrieve the path, similar to Array.prototype.at(), where a negative number is the index counted from the end of the matching route. Defaults to the current route index.
35
35
  * @returns The route path registered within the handler
36
36
  *
37
37
  * @example
@@ -54,7 +54,7 @@ export declare const routePath: (c: Context, index?: number) => string;
54
54
  * Get the basePath of the as-is route specified by routing.
55
55
  *
56
56
  * @param {Context} c - The context object
57
- * @param {number} index - The index of the root from which to retrieve the path, similar to Array.prototype.at(), where a negative number is the index counted from the end of the matching root. Defaults to the current root index.
57
+ * @param {number} index - The index of the route from which to retrieve the path, similar to Array.prototype.at(), where a negative number is the index counted from the end of the matching route. Defaults to the current route index.
58
58
  * @returns The basePath of the as-is route specified by routing.
59
59
  *
60
60
  * @example
@@ -66,7 +66,9 @@ export declare const every: (...middleware: (MiddlewareHandler | Condition)[]) =
66
66
  * If there are multiple targets to match any of them, they can be passed as an array.
67
67
  * If a string is passed, it will be treated as a path pattern to match.
68
68
  * If a Condition function is passed, it will be evaluated against the request context.
69
- * @param middleware - A composed middleware
69
+ * @param middleware - Middleware to run when the condition is not met.
70
+ * Multiple middleware can be passed, and they are applied in the order they are passed.
71
+ * @returns A composed middleware.
70
72
  *
71
73
  * @example
72
74
  * ```ts
@@ -32,7 +32,7 @@ export type JSONValue = JSONObject | JSONArray | JSONPrimitive;
32
32
  * `JSON.stringify()` throws a `TypeError` when it encounters a `bigint` value,
33
33
  * unless a custom `replacer` function or `.toJSON()` method is provided.
34
34
  *
35
- * This behaviour can be controlled by the `TError` generic type parameter,
35
+ * This behavior can be controlled by the `TError` generic type parameter,
36
36
  * which defaults to `bigint | ReadonlyArray<bigint>`.
37
37
  * You can set it to `never` to disable this check.
38
38
  */
@@ -180,7 +180,7 @@ var parseAccept = (acceptHeader) => {
180
180
  ;
181
181
  [i, accept] = getNextAcceptValue(acceptHeader, i);
182
182
  if (accept) {
183
- accept.q = parseQuality(accept.params.q);
183
+ accept.q = parseQuality(accept.params.q ?? accept.params.Q);
184
184
  values.push(accept);
185
185
  if (lastAccept && lastAccept.q < accept.q) {
186
186
  requiresSort = true;
@@ -204,16 +204,13 @@ var parseQuality = (qVal) => {
204
204
  return 0;
205
205
  }
206
206
  const num = Number(qVal);
207
- if (num === Infinity) {
207
+ if (Number.isNaN(num)) {
208
208
  return 1;
209
209
  }
210
- if (num === -Infinity) {
210
+ if (num < 0) {
211
211
  return 0;
212
212
  }
213
- if (Number.isNaN(num)) {
214
- return 1;
215
- }
216
- if (num < 0 || num > 1) {
213
+ if (num > 1) {
217
214
  return 1;
218
215
  }
219
216
  return num;
@@ -109,12 +109,13 @@ var verify = async (token, publicKey, algOrOptions) => {
109
109
  }
110
110
  }
111
111
  const headerPayload = token.substring(0, token.lastIndexOf("."));
112
- const verified = await verifying(
113
- publicKey,
114
- alg,
115
- decodeBase64Url(tokenParts[2]),
116
- utf8Encoder.encode(headerPayload)
117
- );
112
+ let signature;
113
+ try {
114
+ signature = decodeBase64Url(tokenParts[2]);
115
+ } catch {
116
+ throw new JwtTokenInvalid(token);
117
+ }
118
+ const verified = await verifying(publicKey, alg, signature, utf8Encoder.encode(headerPayload));
118
119
  if (!verified) {
119
120
  throw new JwtTokenSignatureMismatched(token);
120
121
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@depup/hono",
3
- "version": "4.13.7-depup.0",
3
+ "version": "4.13.9-depup.0",
4
4
  "description": "Web framework built on Web Standards (with updated dependencies)",
5
5
  "main": "dist/cjs/index.js",
6
6
  "type": "module",
@@ -711,8 +711,8 @@
711
711
  "changes": {},
712
712
  "depsUpdated": 0,
713
713
  "originalPackage": "hono",
714
- "originalVersion": "4.13.7",
715
- "processedAt": "2026-09-05T00:31:41.567Z",
714
+ "originalVersion": "4.13.9",
715
+ "processedAt": "2026-09-24T08:13:10.881Z",
716
716
  "smokeTest": "passed"
717
717
  }
718
718
  }