hono 4.5.1 → 4.5.3

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,6 +1,6 @@
1
1
  // src/adapter/service-worker/handler.ts
2
2
  var handle = (app, opts = {
3
- fetch
3
+ fetch: globalThis.self !== void 0 ? globalThis.self.fetch : fetch
4
4
  }) => {
5
5
  return (evt) => {
6
6
  evt.respondWith(
@@ -22,7 +22,7 @@ __export(handler_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(handler_exports);
24
24
  const handle = (app, opts = {
25
- fetch
25
+ fetch: globalThis.self !== void 0 ? globalThis.self.fetch : fetch
26
26
  }) => {
27
27
  return (evt) => {
28
28
  evt.respondWith(
@@ -28,6 +28,7 @@ __export(base_exports, {
28
28
  JSXFragmentNode: () => JSXFragmentNode,
29
29
  JSXNode: () => JSXNode,
30
30
  cloneElement: () => cloneElement,
31
+ getNameSpaceContext: () => getNameSpaceContext,
31
32
  isValidElement: () => isValidElement,
32
33
  jsx: () => jsx,
33
34
  jsxFn: () => jsxFn,
@@ -42,6 +43,11 @@ var import_constants = require("./constants");
42
43
  var import_utils = require("./utils");
43
44
  var intrinsicElementTags = __toESM(require("./intrinsic-element/components"), 1);
44
45
  var import_common = require("./intrinsic-element/common");
46
+ let nameSpaceContext = void 0;
47
+ const getNameSpaceContext = () => nameSpaceContext;
48
+ const toSVGAttributeName = (key) => /[A-Z]/.test(key) && key.match(
49
+ /^(?:al|basel|clip(?:Path|Rule)$|co|do|fill|fl|fo|gl|let|lig|i|marker[EMS]|o|pai|pointe|sh|st[or]|text[^L]|tr|u|ve|w)/
50
+ ) ? key.replace(/([A-Z])/g, "-$1").toLowerCase() : key;
45
51
  const emptyTags = [
46
52
  "area",
47
53
  "base",
@@ -143,8 +149,9 @@ class JSXNode {
143
149
  const props = this.props;
144
150
  let { children } = this;
145
151
  buffer[0] += `<${tag}`;
152
+ const normalizeKey = nameSpaceContext && (0, import_context.useContext)(nameSpaceContext) === "svg" ? (key) => toSVGAttributeName((0, import_utils.normalizeIntrinsicElementKey)(key)) : (key) => (0, import_utils.normalizeIntrinsicElementKey)(key);
146
153
  for (let [key, v] of Object.entries(props)) {
147
- key = (0, import_utils.normalizeIntrinsicElementKey)(key);
154
+ key = normalizeKey(key);
148
155
  if (key === "children") {
149
156
  } else if (key === "style" && typeof v === "object") {
150
157
  let styleStr = "";
@@ -262,6 +269,17 @@ const jsxFn = (tag, props, children) => {
262
269
  props,
263
270
  children
264
271
  );
272
+ } else if (tag === "svg") {
273
+ nameSpaceContext ||= (0, import_context.createContext)("");
274
+ return new JSXNode(tag, props, [
275
+ new JSXFunctionNode(
276
+ nameSpaceContext,
277
+ {
278
+ value: tag
279
+ },
280
+ children
281
+ )
282
+ ]);
265
283
  } else {
266
284
  return new JSXNode(tag, props, children);
267
285
  }
@@ -323,6 +341,7 @@ const reactAPICompatVersion = "19.0.0-hono-jsx";
323
341
  JSXFragmentNode,
324
342
  JSXNode,
325
343
  cloneElement,
344
+ getNameSpaceContext,
326
345
  isValidElement,
327
346
  jsx,
328
347
  jsxFn,
@@ -187,22 +187,7 @@ const getNextChildren = (node, container, nextChildren, childrenToRemove, callba
187
187
  });
188
188
  };
189
189
  const findInsertBefore = (node) => {
190
- if (!node) {
191
- return null;
192
- } else if (node.tag === HONO_PORTAL_ELEMENT) {
193
- return findInsertBefore(node.nN);
194
- } else if (node.e) {
195
- return node.e;
196
- }
197
- if (node.vC) {
198
- for (let i = 0, len = node.vC.length; i < len; i++) {
199
- const e = findInsertBefore(node.vC[i]);
200
- if (e) {
201
- return e;
202
- }
203
- }
204
- }
205
- return findInsertBefore(node.nN);
190
+ return !node ? null : node.tag === HONO_PORTAL_ELEMENT ? findInsertBefore(node.nN) : node.e || node.vC && node.pP && findInsertBefore(node.vC[0]) || findInsertBefore(node.nN);
206
191
  };
207
192
  const removeNode = (node) => {
208
193
  if (!isNodeString(node)) {
@@ -29,6 +29,7 @@ __export(components_exports, {
29
29
  });
30
30
  module.exports = __toCommonJS(components_exports);
31
31
  var import_base = require("../base");
32
+ var import_context = require("../context");
32
33
  var import_html = require("../../helper/html");
33
34
  var import_common = require("./common");
34
35
  var import_constants = require("../constants");
@@ -105,6 +106,10 @@ const documentMetadataTag = (tag, children, props, sort) => {
105
106
  }
106
107
  };
107
108
  const title = ({ children, ...props }) => {
109
+ const nameSpaceContext = (0, import_base.getNameSpaceContext)();
110
+ if (nameSpaceContext && (0, import_context.useContext)(nameSpaceContext) === "svg") {
111
+ new import_base.JSXNode("title", props, (0, import_children.toArray)(children ?? []));
112
+ }
108
113
  return documentMetadataTag("title", children, props, false);
109
114
  };
110
115
  const script = ({
@@ -42,7 +42,7 @@ const csrf = (options) => {
42
42
  }
43
43
  return handler(origin, c);
44
44
  };
45
- return async function cors(c, next) {
45
+ return async function csrf2(c, next) {
46
46
  if (!isSafeMethodRe.test(c.req.method) && isRequestedByFormElementRe.test(c.req.header("content-type") || "") && !isAllowedOrigin(c.req.header("origin"), c)) {
47
47
  const res = new Response("Forbidden", {
48
48
  status: 403
@@ -49,7 +49,8 @@ const DEFAULT_OPTIONS = {
49
49
  xDownloadOptions: true,
50
50
  xFrameOptions: true,
51
51
  xPermittedCrossDomainPolicies: true,
52
- xXssProtection: true
52
+ xXssProtection: true,
53
+ removePoweredBy: true
53
54
  };
54
55
  const generateNonce = () => {
55
56
  const buffer = new Uint8Array(16);
@@ -85,7 +86,9 @@ const secureHeaders = (customOptions) => {
85
86
  const headersToSetForReq = callbacks.length === 0 ? headersToSet : callbacks.reduce((acc, cb) => cb(ctx, acc), headersToSet);
86
87
  await next();
87
88
  setHeaders(ctx, headersToSetForReq);
88
- ctx.res.headers.delete("X-Powered-By");
89
+ if (options?.removePoweredBy) {
90
+ ctx.res.headers.delete("X-Powered-By");
91
+ }
89
92
  };
90
93
  };
91
94
  function getFilteredHeaders(options) {
@@ -24,8 +24,8 @@ module.exports = __toCommonJS(validator_exports);
24
24
  var import_cookie = require("../helper/cookie");
25
25
  var import_http_exception = require("../http-exception");
26
26
  var import_buffer = require("../utils/buffer");
27
- const jsonRegex = /^application\/([a-z-\.]+\+)?json$/;
28
- const multipartRegex = /^multipart\/form-data(; boundary=[A-Za-z0-9'()+_,\-./:=?]+)?$/;
27
+ const jsonRegex = /^application\/([a-z-\.]+\+)?json(;\s*[a-zA-Z0-9\-]+\=([^;]+))*$/;
28
+ const multipartRegex = /^multipart\/form-data(; boundary=[a-zA-Z0-9'"()+_,\-./:=?]+)?$/;
29
29
  const urlencodedRegex = /^application\/x-www-form-urlencoded$/;
30
30
  const validator = (target, validationFunc) => {
31
31
  return async (c, next) => {
package/dist/jsx/base.js CHANGED
@@ -1,11 +1,16 @@
1
1
  // src/jsx/base.ts
2
2
  import { raw } from "../helper/html/index.js";
3
3
  import { escapeToBuffer, resolveCallbackSync, stringBufferToString } from "../utils/html.js";
4
- import { globalContexts } from "./context.js";
4
+ import { createContext, globalContexts, useContext } from "./context.js";
5
5
  import { DOM_RENDERER } from "./constants.js";
6
6
  import { normalizeIntrinsicElementKey, styleObjectForEach } from "./utils.js";
7
7
  import * as intrinsicElementTags from "./intrinsic-element/components.js";
8
8
  import { domRenderers } from "./intrinsic-element/common.js";
9
+ var nameSpaceContext = void 0;
10
+ var getNameSpaceContext = () => nameSpaceContext;
11
+ var toSVGAttributeName = (key) => /[A-Z]/.test(key) && key.match(
12
+ /^(?:al|basel|clip(?:Path|Rule)$|co|do|fill|fl|fo|gl|let|lig|i|marker[EMS]|o|pai|pointe|sh|st[or]|text[^L]|tr|u|ve|w)/
13
+ ) ? key.replace(/([A-Z])/g, "-$1").toLowerCase() : key;
9
14
  var emptyTags = [
10
15
  "area",
11
16
  "base",
@@ -107,8 +112,9 @@ var JSXNode = class {
107
112
  const props = this.props;
108
113
  let { children } = this;
109
114
  buffer[0] += `<${tag}`;
115
+ const normalizeKey = nameSpaceContext && useContext(nameSpaceContext) === "svg" ? (key) => toSVGAttributeName(normalizeIntrinsicElementKey(key)) : (key) => normalizeIntrinsicElementKey(key);
110
116
  for (let [key, v] of Object.entries(props)) {
111
- key = normalizeIntrinsicElementKey(key);
117
+ key = normalizeKey(key);
112
118
  if (key === "children") {
113
119
  } else if (key === "style" && typeof v === "object") {
114
120
  let styleStr = "";
@@ -226,6 +232,17 @@ var jsxFn = (tag, props, children) => {
226
232
  props,
227
233
  children
228
234
  );
235
+ } else if (tag === "svg") {
236
+ nameSpaceContext ||= createContext("");
237
+ return new JSXNode(tag, props, [
238
+ new JSXFunctionNode(
239
+ nameSpaceContext,
240
+ {
241
+ value: tag
242
+ },
243
+ children
244
+ )
245
+ ]);
229
246
  } else {
230
247
  return new JSXNode(tag, props, children);
231
248
  }
@@ -286,6 +303,7 @@ export {
286
303
  JSXFragmentNode,
287
304
  JSXNode,
288
305
  cloneElement,
306
+ getNameSpaceContext,
289
307
  isValidElement,
290
308
  jsx,
291
309
  jsxFn,
@@ -157,22 +157,7 @@ var getNextChildren = (node, container, nextChildren, childrenToRemove, callback
157
157
  });
158
158
  };
159
159
  var findInsertBefore = (node) => {
160
- if (!node) {
161
- return null;
162
- } else if (node.tag === HONO_PORTAL_ELEMENT) {
163
- return findInsertBefore(node.nN);
164
- } else if (node.e) {
165
- return node.e;
166
- }
167
- if (node.vC) {
168
- for (let i = 0, len = node.vC.length; i < len; i++) {
169
- const e = findInsertBefore(node.vC[i]);
170
- if (e) {
171
- return e;
172
- }
173
- }
174
- }
175
- return findInsertBefore(node.nN);
160
+ return !node ? null : node.tag === HONO_PORTAL_ELEMENT ? findInsertBefore(node.nN) : node.e || node.vC && node.pP && findInsertBefore(node.vC[0]) || findInsertBefore(node.nN);
176
161
  };
177
162
  var removeNode = (node) => {
178
163
  if (!isNodeString(node)) {
@@ -1,5 +1,6 @@
1
1
  // src/jsx/intrinsic-element/components.ts
2
- import { JSXNode } from "../base.js";
2
+ import { JSXNode, getNameSpaceContext } from "../base.js";
3
+ import { useContext } from "../context.js";
3
4
  import { raw } from "../../helper/html/index.js";
4
5
  import { dataPrecedenceAttr, deDupeKeyMap } from "./common.js";
5
6
  import { PERMALINK } from "../constants.js";
@@ -76,6 +77,10 @@ var documentMetadataTag = (tag, children, props, sort) => {
76
77
  }
77
78
  };
78
79
  var title = ({ children, ...props }) => {
80
+ const nameSpaceContext = getNameSpaceContext();
81
+ if (nameSpaceContext && useContext(nameSpaceContext) === "svg") {
82
+ new JSXNode("title", props, toArray(children ?? []));
83
+ }
79
84
  return documentMetadataTag("title", children, props, false);
80
85
  };
81
86
  var script = ({
@@ -20,7 +20,7 @@ var csrf = (options) => {
20
20
  }
21
21
  return handler(origin, c);
22
22
  };
23
- return async function cors(c, next) {
23
+ return async function csrf2(c, next) {
24
24
  if (!isSafeMethodRe.test(c.req.method) && isRequestedByFormElementRe.test(c.req.header("content-type") || "") && !isAllowedOrigin(c.req.header("origin"), c)) {
25
25
  const res = new Response("Forbidden", {
26
26
  status: 403
@@ -26,7 +26,8 @@ var DEFAULT_OPTIONS = {
26
26
  xDownloadOptions: true,
27
27
  xFrameOptions: true,
28
28
  xPermittedCrossDomainPolicies: true,
29
- xXssProtection: true
29
+ xXssProtection: true,
30
+ removePoweredBy: true
30
31
  };
31
32
  var generateNonce = () => {
32
33
  const buffer = new Uint8Array(16);
@@ -62,7 +63,9 @@ var secureHeaders = (customOptions) => {
62
63
  const headersToSetForReq = callbacks.length === 0 ? headersToSet : callbacks.reduce((acc, cb) => cb(ctx, acc), headersToSet);
63
64
  await next();
64
65
  setHeaders(ctx, headersToSetForReq);
65
- ctx.res.headers.delete("X-Powered-By");
66
+ if (options?.removePoweredBy) {
67
+ ctx.res.headers.delete("X-Powered-By");
68
+ }
66
69
  };
67
70
  };
68
71
  function getFilteredHeaders(options) {
@@ -122,7 +122,7 @@ interface JSONRespond {
122
122
  *
123
123
  * @returns {Response & TypedResponse<SimplifyDeepArray<T> extends JSONValue ? (JSONValue extends SimplifyDeepArray<T> ? never : JSONParsed<T>) : never, U, 'json'>} - The response after rendering the JSON object, typed with the provided object and status code types.
124
124
  */
125
- type JSONRespondReturn<T extends JSONValue | SimplifyDeepArray<unknown> | InvalidJSONValue, U extends StatusCode> = Response & TypedResponse<SimplifyDeepArray<T> extends JSONValue ? JSONValue extends SimplifyDeepArray<T> ? never : JSONParsed<T> : JSONParsed<T>, U, 'json'>;
125
+ type JSONRespondReturn<T extends JSONValue | SimplifyDeepArray<unknown> | InvalidJSONValue, U extends StatusCode> = Response & TypedResponse<SimplifyDeepArray<T> extends JSONValue ? JSONValue extends SimplifyDeepArray<T> ? never : JSONParsed<T> : never, U, 'json'>;
126
126
  /**
127
127
  * Interface representing a function that responds with HTML content.
128
128
  *
@@ -17,6 +17,7 @@ export declare namespace JSX {
17
17
  [tagName: string]: Props;
18
18
  }
19
19
  }
20
+ export declare const getNameSpaceContext: () => Context<string> | undefined;
20
21
  type LocalContexts = [Context<unknown>, unknown][];
21
22
  export type Child = string | Promise<string> | number | JSXNode | null | undefined | boolean | Child[];
22
23
  export declare class JSXNode implements HtmlEscaped {
@@ -62,6 +62,7 @@ interface SecureHeadersOptions {
62
62
  xFrameOptions?: overridableHeader;
63
63
  xPermittedCrossDomainPolicies?: overridableHeader;
64
64
  xXssProtection?: overridableHeader;
65
+ removePoweredBy?: boolean;
65
66
  }
66
67
  export declare const NONCE: ContentSecurityPolicyOptionHandler;
67
68
  /**
@@ -85,6 +86,7 @@ export declare const NONCE: ContentSecurityPolicyOptionHandler;
85
86
  * @param {overridableHeader} [customOptions.xFrameOptions=true] - Settings for the X-Frame-Options header.
86
87
  * @param {overridableHeader} [customOptions.xPermittedCrossDomainPolicies=true] - Settings for the X-Permitted-Cross-Domain-Policies header.
87
88
  * @param {overridableHeader} [customOptions.xXssProtection=true] - Settings for the X-XSS-Protection header.
89
+ * @param {boolean} [customOptions.removePoweredBy=true] - Settings for remove X-Powered-By header.
88
90
  * @returns {MiddlewareHandler} The middleware handler function.
89
91
  *
90
92
  * @example
@@ -11,7 +11,7 @@ export type IfAnyThenEmptyObject<T> = 0 extends 1 & T ? {} : T;
11
11
  export type JSONPrimitive = string | boolean | number | null;
12
12
  export type JSONArray = (JSONPrimitive | JSONObject | JSONArray)[];
13
13
  export type JSONObject = {
14
- [key: string]: JSONPrimitive | JSONArray | JSONObject | object;
14
+ [key: string]: JSONPrimitive | JSONArray | JSONObject | object | InvalidJSONValue;
15
15
  };
16
16
  export type InvalidJSONValue = undefined | symbol | ((...args: unknown[]) => unknown);
17
17
  type InvalidToNull<T> = T extends InvalidJSONValue ? null : T;
@@ -27,7 +27,7 @@ export type JSONParsed<T> = T extends {
27
27
  toJSON(): infer J;
28
28
  } ? (() => J) extends () => JSONPrimitive ? J : (() => J) extends () => {
29
29
  toJSON(): unknown;
30
- } ? {} : JSONParsed<J> : T extends JSONPrimitive ? T : T extends InvalidJSONValue ? never : T extends [] ? [] : T extends readonly [infer R, ...infer U] ? [JSONParsed<InvalidToNull<R>>, ...JSONParsed<U>] : T extends Array<infer U> ? Array<JSONParsed<InvalidToNull<U>>> : T extends Set<unknown> | Map<unknown, unknown> ? {} : T extends object ? {
30
+ } ? {} : JSONParsed<J> : T extends JSONPrimitive ? T : T extends InvalidJSONValue ? never : T extends [] ? [] : T extends readonly [infer R, ...infer U] ? [JSONParsed<InvalidToNull<R>>, ...JSONParsed<U>] : T extends Array<infer U> ? Array<JSONParsed<InvalidToNull<U>>> : T extends ReadonlyArray<infer U> ? ReadonlyArray<JSONParsed<InvalidToNull<U>>> : T extends Set<unknown> | Map<unknown, unknown> ? {} : T extends object ? {
31
31
  [K in keyof OmitSymbolKeys<T> as IsInvalid<T[K]> extends true ? never : K]: boolean extends IsInvalid<T[K]> ? JSONParsed<T[K]> | undefined : JSONParsed<T[K]>;
32
32
  } : never;
33
33
  /**
@@ -2,8 +2,8 @@
2
2
  import { getCookie } from "../helper/cookie/index.js";
3
3
  import { HTTPException } from "../http-exception.js";
4
4
  import { bufferToFormData } from "../utils/buffer.js";
5
- var jsonRegex = /^application\/([a-z-\.]+\+)?json$/;
6
- var multipartRegex = /^multipart\/form-data(; boundary=[A-Za-z0-9'()+_,\-./:=?]+)?$/;
5
+ var jsonRegex = /^application\/([a-z-\.]+\+)?json(;\s*[a-zA-Z0-9\-]+\=([^;]+))*$/;
6
+ var multipartRegex = /^multipart\/form-data(; boundary=[a-zA-Z0-9'"()+_,\-./:=?]+)?$/;
7
7
  var urlencodedRegex = /^application\/x-www-form-urlencoded$/;
8
8
  var validator = (target, validationFunc) => {
9
9
  return async (c, next) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hono",
3
- "version": "4.5.1",
3
+ "version": "4.5.3",
4
4
  "description": "Web framework built on Web Standards",
5
5
  "main": "dist/cjs/index.js",
6
6
  "type": "module",