hono 4.5.2 → 4.5.4

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(
@@ -167,7 +167,13 @@ const hc = (baseUrl, options) => createProxy(function proxyCallback(opts) {
167
167
  }
168
168
  });
169
169
  }
170
- return new WebSocket(targetUrl.toString());
170
+ const establishWebSocket = (...args) => {
171
+ if (options?.webSocket !== void 0 && typeof options.webSocket === "function") {
172
+ return options.webSocket(...args);
173
+ }
174
+ return new WebSocket(...args);
175
+ };
176
+ return establishWebSocket(targetUrl.toString());
171
177
  }
172
178
  const req = new ClientRequestImpl(url, method);
173
179
  if (method) {
@@ -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 = ({
@@ -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) => {
@@ -151,7 +151,13 @@ var hc = (baseUrl, options) => createProxy(function proxyCallback(opts) {
151
151
  }
152
152
  });
153
153
  }
154
- return new WebSocket(targetUrl.toString());
154
+ const establishWebSocket = (...args) => {
155
+ if (options?.webSocket !== void 0 && typeof options.webSocket === "function") {
156
+ return options.webSocket(...args);
157
+ }
158
+ return new WebSocket(...args);
159
+ };
160
+ return establishWebSocket(targetUrl.toString());
155
161
  }
156
162
  const req = new ClientRequestImpl(url, method);
157
163
  if (method) {
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 = ({
@@ -5,6 +5,7 @@ import type { HasRequiredKeys } from '../utils/types';
5
5
  type HonoRequest = (typeof Hono.prototype)['request'];
6
6
  export type ClientRequestOptions<T = unknown> = {
7
7
  fetch?: typeof fetch | HonoRequest;
8
+ webSocket?: (...args: ConstructorParameters<typeof WebSocket>) => WebSocket;
8
9
  /**
9
10
  * Standard `RequestInit`, caution that this take highest priority
10
11
  * and could be used to overwrite things that Hono sets for you, like `body | method | headers`.
@@ -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 {
@@ -6,7 +6,9 @@
6
6
  */
7
7
  export declare namespace JSX {
8
8
  export type CrossOrigin = 'anonymous' | 'use-credentials' | '' | undefined;
9
- export type CSSProperties = {};
9
+ export interface CSSProperties {
10
+ [propertyKey: string]: unknown;
11
+ }
10
12
  type AnyAttributes = {
11
13
  [attributeName: string]: any;
12
14
  };
@@ -147,7 +149,7 @@ export declare namespace JSX {
147
149
  contenteditable?: boolean | 'inherit' | undefined;
148
150
  contextmenu?: string | undefined;
149
151
  dir?: string | undefined;
150
- draggable?: boolean | undefined;
152
+ draggable?: 'true' | 'false' | undefined;
151
153
  enterkeyhint?: 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send' | undefined;
152
154
  hidden?: boolean | undefined;
153
155
  id?: string | undefined;
@@ -165,7 +167,7 @@ export declare namespace JSX {
165
167
  popover?: string | undefined;
166
168
  slot?: string | undefined;
167
169
  spellcheck?: boolean | undefined;
168
- style?: CSSProperties | undefined;
170
+ style?: CSSProperties | string | undefined;
169
171
  tabindex?: number | undefined;
170
172
  title?: string | undefined;
171
173
  translate?: 'yes' | 'no' | undefined;
@@ -458,7 +458,7 @@ type ChangePathOfSchema<S extends Schema, Path extends string> = keyof S extends
458
458
  [K in keyof S as Path]: S[K];
459
459
  };
460
460
  export type Endpoint = {
461
- input: Partial<ValidationTargets>;
461
+ input: any;
462
462
  output: any;
463
463
  outputFormat: ResponseFormat;
464
464
  status: StatusCode;
@@ -514,11 +514,11 @@ export type TypedResponse<T = unknown, U extends StatusCode = StatusCode, F exte
514
514
  type MergeTypedResponse<T> = T extends Promise<infer T2> ? T2 extends TypedResponse ? T2 : TypedResponse : T extends TypedResponse ? T : TypedResponse;
515
515
  export type FormValue = string | Blob;
516
516
  export type ParsedFormValue = string | File;
517
- export type ValidationTargets<T extends FormValue = ParsedFormValue> = {
517
+ export type ValidationTargets<T extends FormValue = ParsedFormValue, P extends string = string> = {
518
518
  json: any;
519
519
  form: Record<string, T | T[]>;
520
520
  query: Record<string, string | string[]>;
521
- param: Record<string, string> | Record<string, string | undefined>;
521
+ param: Record<P, P extends `${infer _}?` ? string | undefined : string>;
522
522
  header: Record<string, string>;
523
523
  cookie: Record<string, string>;
524
524
  };
@@ -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.2",
3
+ "version": "4.5.4",
4
4
  "description": "Web framework built on Web Standards",
5
5
  "main": "dist/cjs/index.js",
6
6
  "type": "module",