hono 4.6.5 → 4.6.7

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.
Files changed (38) hide show
  1. package/dist/adapter/bun/websocket.js +23 -26
  2. package/dist/adapter/cloudflare-workers/websocket.js +40 -39
  3. package/dist/adapter/deno/serve-static.js +4 -2
  4. package/dist/adapter/deno/websocket.js +7 -8
  5. package/dist/adapter/vercel/handler.js +2 -2
  6. package/dist/cjs/adapter/bun/websocket.js +24 -26
  7. package/dist/cjs/adapter/cloudflare-workers/websocket.js +40 -39
  8. package/dist/cjs/adapter/deno/serve-static.js +4 -2
  9. package/dist/cjs/adapter/deno/websocket.js +7 -8
  10. package/dist/cjs/adapter/vercel/handler.js +2 -2
  11. package/dist/cjs/client/client.js +10 -16
  12. package/dist/cjs/client/utils.js +18 -0
  13. package/dist/cjs/helper/websocket/index.js +43 -2
  14. package/dist/cjs/middleware/secure-headers/secure-headers.js +6 -5
  15. package/dist/cjs/router/linear-router/router.js +75 -77
  16. package/dist/cjs/router/pattern-router/router.js +3 -2
  17. package/dist/cjs/router/smart-router/router.js +3 -3
  18. package/dist/cjs/router/trie-router/node.js +9 -12
  19. package/dist/cjs/router/trie-router/router.js +2 -2
  20. package/dist/cjs/utils/jwt/jws.js +4 -2
  21. package/dist/client/client.js +11 -16
  22. package/dist/client/utils.js +17 -0
  23. package/dist/helper/websocket/index.js +40 -1
  24. package/dist/middleware/secure-headers/secure-headers.js +6 -5
  25. package/dist/router/linear-router/router.js +75 -77
  26. package/dist/router/pattern-router/router.js +3 -2
  27. package/dist/router/smart-router/router.js +3 -3
  28. package/dist/router/trie-router/node.js +9 -12
  29. package/dist/router/trie-router/router.js +2 -2
  30. package/dist/types/adapter/bun/websocket.d.ts +9 -1
  31. package/dist/types/adapter/vercel/handler.d.ts +1 -2
  32. package/dist/types/client/types.d.ts +9 -0
  33. package/dist/types/client/utils.d.ts +1 -0
  34. package/dist/types/helper/websocket/index.d.ts +35 -6
  35. package/dist/types/middleware/powered-by/index.d.ts +19 -0
  36. package/dist/types/router/trie-router/node.d.ts +0 -2
  37. package/dist/utils/jwt/jws.js +4 -2
  38. package/package.json +1 -1
@@ -30,104 +30,102 @@ class LinearRouter {
30
30
  name = "LinearRouter";
31
31
  routes = [];
32
32
  add(method, path, handler) {
33
- ;
34
- ((0, import_url.checkOptionalParameter)(path) || [path]).forEach((p) => {
35
- this.routes.push([method, p, handler]);
36
- });
33
+ for (let i = 0, paths = (0, import_url.checkOptionalParameter)(path) || [path], len = paths.length; i < len; i++) {
34
+ this.routes.push([method, paths[i], handler]);
35
+ }
37
36
  }
38
37
  match(method, path) {
39
38
  const handlers = [];
40
39
  ROUTES_LOOP:
41
40
  for (let i = 0, len = this.routes.length; i < len; i++) {
42
41
  const [routeMethod, routePath, handler] = this.routes[i];
43
- if (routeMethod !== method && routeMethod !== import_router.METHOD_NAME_ALL) {
44
- continue;
45
- }
46
- if (routePath === "*" || routePath === "/*") {
47
- handlers.push([handler, emptyParams]);
48
- continue;
49
- }
50
- const hasStar = routePath.indexOf("*") !== -1;
51
- const hasLabel = routePath.indexOf(":") !== -1;
52
- if (!hasStar && !hasLabel) {
53
- if (routePath === path || routePath + "/" === path) {
42
+ if (routeMethod === method || routeMethod === import_router.METHOD_NAME_ALL) {
43
+ if (routePath === "*" || routePath === "/*") {
54
44
  handlers.push([handler, emptyParams]);
45
+ continue;
55
46
  }
56
- } else if (hasStar && !hasLabel) {
57
- const endsWithStar = routePath.charCodeAt(routePath.length - 1) === 42;
58
- const parts = (endsWithStar ? routePath.slice(0, -2) : routePath).split(splitByStarRe);
59
- const lastIndex = parts.length - 1;
60
- for (let j = 0, pos = 0, len2 = parts.length; j < len2; j++) {
61
- const part = parts[j];
62
- const index = path.indexOf(part, pos);
63
- if (index !== pos) {
64
- continue ROUTES_LOOP;
47
+ const hasStar = routePath.indexOf("*") !== -1;
48
+ const hasLabel = routePath.indexOf(":") !== -1;
49
+ if (!hasStar && !hasLabel) {
50
+ if (routePath === path || routePath + "/" === path) {
51
+ handlers.push([handler, emptyParams]);
65
52
  }
66
- pos += part.length;
67
- if (j === lastIndex) {
68
- if (!endsWithStar && pos !== path.length && !(pos === path.length - 1 && path.charCodeAt(pos) === 47)) {
69
- continue ROUTES_LOOP;
70
- }
71
- } else {
72
- const index2 = path.indexOf("/", pos);
73
- if (index2 === -1) {
53
+ } else if (hasStar && !hasLabel) {
54
+ const endsWithStar = routePath.charCodeAt(routePath.length - 1) === 42;
55
+ const parts = (endsWithStar ? routePath.slice(0, -2) : routePath).split(splitByStarRe);
56
+ const lastIndex = parts.length - 1;
57
+ for (let j = 0, pos = 0, len2 = parts.length; j < len2; j++) {
58
+ const part = parts[j];
59
+ const index = path.indexOf(part, pos);
60
+ if (index !== pos) {
74
61
  continue ROUTES_LOOP;
75
62
  }
76
- pos = index2;
77
- }
78
- }
79
- handlers.push([handler, emptyParams]);
80
- } else if (hasLabel && !hasStar) {
81
- const params = /* @__PURE__ */ Object.create(null);
82
- const parts = routePath.match(splitPathRe);
83
- const lastIndex = parts.length - 1;
84
- for (let j = 0, pos = 0, len2 = parts.length; j < len2; j++) {
85
- if (pos === -1 || pos >= path.length) {
86
- continue ROUTES_LOOP;
87
- }
88
- const part = parts[j];
89
- if (part.charCodeAt(1) === 58) {
90
- let name = part.slice(2);
91
- let value;
92
- if (name.charCodeAt(name.length - 1) === 125) {
93
- const openBracePos = name.indexOf("{");
94
- const pattern = name.slice(openBracePos + 1, -1);
95
- const restPath = path.slice(pos + 1);
96
- const match = new RegExp(pattern, "d").exec(restPath);
97
- if (!match || match.indices[0][0] !== 0 || match.indices[0][1] === 0) {
63
+ pos += part.length;
64
+ if (j === lastIndex) {
65
+ if (!endsWithStar && pos !== path.length && !(pos === path.length - 1 && path.charCodeAt(pos) === 47)) {
98
66
  continue ROUTES_LOOP;
99
67
  }
100
- name = name.slice(0, openBracePos);
101
- value = restPath.slice(...match.indices[0]);
102
- pos += match.indices[0][1] + 1;
103
68
  } else {
104
- let endValuePos = path.indexOf("/", pos + 1);
105
- if (endValuePos === -1) {
106
- if (pos + 1 === path.length) {
107
- continue ROUTES_LOOP;
108
- }
109
- endValuePos = path.length;
69
+ const index2 = path.indexOf("/", pos);
70
+ if (index2 === -1) {
71
+ continue ROUTES_LOOP;
110
72
  }
111
- value = path.slice(pos + 1, endValuePos);
112
- pos = endValuePos;
113
- }
114
- params[name] ||= value;
115
- } else {
116
- const index = path.indexOf(part, pos);
117
- if (index !== pos) {
118
- continue ROUTES_LOOP;
73
+ pos = index2;
119
74
  }
120
- pos += part.length;
121
75
  }
122
- if (j === lastIndex) {
123
- if (pos !== path.length && !(pos === path.length - 1 && path.charCodeAt(pos) === 47)) {
76
+ handlers.push([handler, emptyParams]);
77
+ } else if (hasLabel && !hasStar) {
78
+ const params = /* @__PURE__ */ Object.create(null);
79
+ const parts = routePath.match(splitPathRe);
80
+ const lastIndex = parts.length - 1;
81
+ for (let j = 0, pos = 0, len2 = parts.length; j < len2; j++) {
82
+ if (pos === -1 || pos >= path.length) {
124
83
  continue ROUTES_LOOP;
125
84
  }
85
+ const part = parts[j];
86
+ if (part.charCodeAt(1) === 58) {
87
+ let name = part.slice(2);
88
+ let value;
89
+ if (name.charCodeAt(name.length - 1) === 125) {
90
+ const openBracePos = name.indexOf("{");
91
+ const pattern = name.slice(openBracePos + 1, -1);
92
+ const restPath = path.slice(pos + 1);
93
+ const match = new RegExp(pattern, "d").exec(restPath);
94
+ if (!match || match.indices[0][0] !== 0 || match.indices[0][1] === 0) {
95
+ continue ROUTES_LOOP;
96
+ }
97
+ name = name.slice(0, openBracePos);
98
+ value = restPath.slice(...match.indices[0]);
99
+ pos += match.indices[0][1] + 1;
100
+ } else {
101
+ let endValuePos = path.indexOf("/", pos + 1);
102
+ if (endValuePos === -1) {
103
+ if (pos + 1 === path.length) {
104
+ continue ROUTES_LOOP;
105
+ }
106
+ endValuePos = path.length;
107
+ }
108
+ value = path.slice(pos + 1, endValuePos);
109
+ pos = endValuePos;
110
+ }
111
+ params[name] ||= value;
112
+ } else {
113
+ const index = path.indexOf(part, pos);
114
+ if (index !== pos) {
115
+ continue ROUTES_LOOP;
116
+ }
117
+ pos += part.length;
118
+ }
119
+ if (j === lastIndex) {
120
+ if (pos !== path.length && !(pos === path.length - 1 && path.charCodeAt(pos) === 47)) {
121
+ continue ROUTES_LOOP;
122
+ }
123
+ }
126
124
  }
125
+ handlers.push([handler, params]);
126
+ } else if (hasLabel && hasStar) {
127
+ throw new import_router.UnsupportedPathError();
127
128
  }
128
- handlers.push([handler, params]);
129
- } else if (hasLabel && hasStar) {
130
- throw new import_router.UnsupportedPathError();
131
129
  }
132
130
  }
133
131
  return [handlers];
@@ -50,8 +50,9 @@ class PatternRouter {
50
50
  }
51
51
  match(method, path) {
52
52
  const handlers = [];
53
- for (const [pattern, routeMethod, handler] of this.routes) {
54
- if (routeMethod === import_router.METHOD_NAME_ALL || routeMethod === method) {
53
+ for (let i = 0, len = this.routes.length; i < len; i++) {
54
+ const [pattern, routeMethod, handler] = this.routes[i];
55
+ if (routeMethod === method || routeMethod === import_router.METHOD_NAME_ALL) {
55
56
  const match = pattern.exec(path);
56
57
  if (match) {
57
58
  handlers.push([handler, match.groups || /* @__PURE__ */ Object.create(null)]);
@@ -46,9 +46,9 @@ class SmartRouter {
46
46
  for (; i < len; i++) {
47
47
  const router = routers[i];
48
48
  try {
49
- routes.forEach((args) => {
50
- router.add(...args);
51
- });
49
+ for (let i2 = 0, len2 = routes.length; i2 < len2; i2++) {
50
+ router.add(...routes[i2]);
51
+ }
52
52
  res = router.match(method, path);
53
53
  } catch (e) {
54
54
  if (e instanceof import_router.UnsupportedPathError) {
@@ -28,21 +28,18 @@ class Node {
28
28
  children;
29
29
  patterns;
30
30
  order = 0;
31
- name;
32
31
  params = /* @__PURE__ */ Object.create(null);
33
32
  constructor(method, handler, children) {
34
33
  this.children = children || /* @__PURE__ */ Object.create(null);
35
34
  this.methods = [];
36
- this.name = "";
37
35
  if (method && handler) {
38
36
  const m = /* @__PURE__ */ Object.create(null);
39
- m[method] = { handler, possibleKeys: [], score: 0, name: this.name };
37
+ m[method] = { handler, possibleKeys: [], score: 0 };
40
38
  this.methods = [m];
41
39
  }
42
40
  this.patterns = [];
43
41
  }
44
42
  insert(method, path, handler) {
45
- this.name = `${method} ${path}`;
46
43
  this.order = ++this.order;
47
44
  let curNode = this;
48
45
  const parts = (0, import_url.splitRoutingPath)(path);
@@ -72,7 +69,6 @@ class Node {
72
69
  const handlerSet = {
73
70
  handler,
74
71
  possibleKeys: possibleKeys.filter((v, i, a) => a.indexOf(v) === i),
75
- name: this.name,
76
72
  score: this.order
77
73
  };
78
74
  m[method] = handlerSet;
@@ -87,11 +83,12 @@ class Node {
87
83
  const processedSet = /* @__PURE__ */ Object.create(null);
88
84
  if (handlerSet !== void 0) {
89
85
  handlerSet.params = /* @__PURE__ */ Object.create(null);
90
- handlerSet.possibleKeys.forEach((key) => {
91
- const processed = processedSet[handlerSet.name];
86
+ for (let i2 = 0, len2 = handlerSet.possibleKeys.length; i2 < len2; i2++) {
87
+ const key = handlerSet.possibleKeys[i2];
88
+ const processed = processedSet[handlerSet.score];
92
89
  handlerSet.params[key] = params[key] && !processed ? params[key] : nodeParams[key] ?? params[key];
93
- processedSet[handlerSet.name] = true;
94
- });
90
+ processedSet[handlerSet.score] = true;
91
+ }
95
92
  handlerSets.push(handlerSet);
96
93
  }
97
94
  }
@@ -112,7 +109,7 @@ class Node {
112
109
  const nextNode = node.children[part];
113
110
  if (nextNode) {
114
111
  nextNode.params = node.params;
115
- if (isLast === true) {
112
+ if (isLast) {
116
113
  if (nextNode.children["*"]) {
117
114
  handlerSets.push(
118
115
  ...this.gHSets(nextNode.children["*"], method, node.params, /* @__PURE__ */ Object.create(null))
@@ -145,10 +142,10 @@ class Node {
145
142
  handlerSets.push(...this.gHSets(child, method, node.params, params));
146
143
  continue;
147
144
  }
148
- if (matcher === true || matcher instanceof RegExp && matcher.test(part)) {
145
+ if (matcher === true || matcher.test(part)) {
149
146
  if (typeof key === "string") {
150
147
  params[name] = part;
151
- if (isLast === true) {
148
+ if (isLast) {
152
149
  handlerSets.push(...this.gHSets(child, method, params, node.params));
153
150
  if (child.children["*"]) {
154
151
  handlerSets.push(...this.gHSets(child.children["*"], method, params, node.params));
@@ -32,8 +32,8 @@ class TrieRouter {
32
32
  add(method, path, handler) {
33
33
  const results = (0, import_url.checkOptionalParameter)(path);
34
34
  if (results) {
35
- for (const p of results) {
36
- this.node.insert(method, p, handler);
35
+ for (let i = 0, len = results.length; i < len; i++) {
36
+ this.node.insert(method, results[i], handler);
37
37
  }
38
38
  return;
39
39
  }
@@ -44,8 +44,10 @@ async function importPrivateKey(key, alg) {
44
44
  throw new Error("`crypto.subtle.importKey` is undefined. JWT auth middleware requires it.");
45
45
  }
46
46
  if (isCryptoKey(key)) {
47
- if (key.type !== "private") {
48
- throw new Error(`unexpected non private key: CryptoKey.type is ${key.type}`);
47
+ if (key.type !== "private" && key.type !== "secret") {
48
+ throw new Error(
49
+ `unexpected key type: CryptoKey.type is ${key.type}, expected private or secret`
50
+ );
49
51
  }
50
52
  return key;
51
53
  }
@@ -1,6 +1,7 @@
1
1
  // src/client/client.ts
2
2
  import { serialize } from "../utils/cookie.js";
3
3
  import {
4
+ buildSearchParams,
4
5
  deepMerge,
5
6
  mergePath,
6
7
  removeIndexString,
@@ -39,19 +40,7 @@ var ClientRequestImpl = class {
39
40
  fetch = async (args, opt) => {
40
41
  if (args) {
41
42
  if (args.query) {
42
- for (const [k, v] of Object.entries(args.query)) {
43
- if (v === void 0) {
44
- continue;
45
- }
46
- this.queryParams ||= new URLSearchParams();
47
- if (Array.isArray(v)) {
48
- for (const v2 of v) {
49
- this.queryParams.append(k, v2);
50
- }
51
- } else {
52
- this.queryParams.set(k, v);
53
- }
54
- }
43
+ this.queryParams = buildSearchParams(args.query);
55
44
  }
56
45
  if (args.form) {
57
46
  const form = new FormData();
@@ -130,10 +119,16 @@ var hc = (baseUrl, options) => createProxy(function proxyCallback(opts) {
130
119
  const path = parts.join("/");
131
120
  const url = mergePath(baseUrl, path);
132
121
  if (method === "url") {
133
- if (opts.args[0] && opts.args[0].param) {
134
- return new URL(replaceUrlParam(url, opts.args[0].param));
122
+ let result = url;
123
+ if (opts.args[0]) {
124
+ if (opts.args[0].param) {
125
+ result = replaceUrlParam(url, opts.args[0].param);
126
+ }
127
+ if (opts.args[0].query) {
128
+ result = result + "?" + buildSearchParams(opts.args[0].query).toString();
129
+ }
135
130
  }
136
- return new URL(url);
131
+ return new URL(result);
137
132
  }
138
133
  if (method === "ws") {
139
134
  const webSocketUrl = replaceUrlProtocol(
@@ -12,6 +12,22 @@ var replaceUrlParam = (urlString, params) => {
12
12
  }
13
13
  return urlString;
14
14
  };
15
+ var buildSearchParams = (query) => {
16
+ const searchParams = new URLSearchParams();
17
+ for (const [k, v] of Object.entries(query)) {
18
+ if (v === void 0) {
19
+ continue;
20
+ }
21
+ if (Array.isArray(v)) {
22
+ for (const v2 of v) {
23
+ searchParams.append(k, v2);
24
+ }
25
+ } else {
26
+ searchParams.set(k, v);
27
+ }
28
+ }
29
+ return searchParams;
30
+ };
15
31
  var replaceUrlProtocol = (urlString, protocol) => {
16
32
  switch (protocol) {
17
33
  case "ws":
@@ -45,6 +61,7 @@ function deepMerge(target, source) {
45
61
  return merged;
46
62
  }
47
63
  export {
64
+ buildSearchParams,
48
65
  deepMerge,
49
66
  mergePath,
50
67
  removeIndexString,
@@ -1,9 +1,48 @@
1
1
  // src/helper/websocket/index.ts
2
+ var WSContext = class {
3
+ #init;
4
+ constructor(init) {
5
+ this.#init = init;
6
+ this.raw = init.raw;
7
+ this.url = init.url ? new URL(init.url) : null;
8
+ this.protocol = init.protocol ?? null;
9
+ }
10
+ send(source, options) {
11
+ this.#init.send(
12
+ typeof source === "string" ? source : source instanceof Uint8Array ? source.buffer : source,
13
+ options ?? {}
14
+ );
15
+ }
16
+ raw;
17
+ binaryType = "arraybuffer";
18
+ get readyState() {
19
+ return this.#init.readyState;
20
+ }
21
+ url;
22
+ protocol;
23
+ close(code, reason) {
24
+ this.#init.close(code, reason);
25
+ }
26
+ };
2
27
  var createWSMessageEvent = (source) => {
3
28
  return new MessageEvent("message", {
4
29
  data: source
5
30
  });
6
31
  };
32
+ var defineWebSocketHelper = (handler) => {
33
+ return (createEvents, options) => {
34
+ return async function UpgradeWebSocket(c, next) {
35
+ const events = await createEvents(c);
36
+ const result = await handler(c, events, options);
37
+ if (result) {
38
+ return result;
39
+ }
40
+ await next();
41
+ };
42
+ };
43
+ };
7
44
  export {
8
- createWSMessageEvent
45
+ WSContext,
46
+ createWSMessageEvent,
47
+ defineWebSocketHelper
9
48
  };
@@ -36,11 +36,12 @@ var generateNonce = () => {
36
36
  return encodeBase64(buffer);
37
37
  };
38
38
  var NONCE = (ctx) => {
39
- const nonce = ctx.get("secureHeadersNonce") || (() => {
40
- const newNonce = generateNonce();
41
- ctx.set("secureHeadersNonce", newNonce);
42
- return newNonce;
43
- })();
39
+ const key = "secureHeadersNonce";
40
+ const init = ctx.get(key);
41
+ const nonce = init || generateNonce();
42
+ if (init == null) {
43
+ ctx.set(key, nonce);
44
+ }
44
45
  return `'nonce-${nonce}'`;
45
46
  };
46
47
  var secureHeaders = (customOptions) => {
@@ -8,104 +8,102 @@ var LinearRouter = class {
8
8
  name = "LinearRouter";
9
9
  routes = [];
10
10
  add(method, path, handler) {
11
- ;
12
- (checkOptionalParameter(path) || [path]).forEach((p) => {
13
- this.routes.push([method, p, handler]);
14
- });
11
+ for (let i = 0, paths = checkOptionalParameter(path) || [path], len = paths.length; i < len; i++) {
12
+ this.routes.push([method, paths[i], handler]);
13
+ }
15
14
  }
16
15
  match(method, path) {
17
16
  const handlers = [];
18
17
  ROUTES_LOOP:
19
18
  for (let i = 0, len = this.routes.length; i < len; i++) {
20
19
  const [routeMethod, routePath, handler] = this.routes[i];
21
- if (routeMethod !== method && routeMethod !== METHOD_NAME_ALL) {
22
- continue;
23
- }
24
- if (routePath === "*" || routePath === "/*") {
25
- handlers.push([handler, emptyParams]);
26
- continue;
27
- }
28
- const hasStar = routePath.indexOf("*") !== -1;
29
- const hasLabel = routePath.indexOf(":") !== -1;
30
- if (!hasStar && !hasLabel) {
31
- if (routePath === path || routePath + "/" === path) {
20
+ if (routeMethod === method || routeMethod === METHOD_NAME_ALL) {
21
+ if (routePath === "*" || routePath === "/*") {
32
22
  handlers.push([handler, emptyParams]);
23
+ continue;
33
24
  }
34
- } else if (hasStar && !hasLabel) {
35
- const endsWithStar = routePath.charCodeAt(routePath.length - 1) === 42;
36
- const parts = (endsWithStar ? routePath.slice(0, -2) : routePath).split(splitByStarRe);
37
- const lastIndex = parts.length - 1;
38
- for (let j = 0, pos = 0, len2 = parts.length; j < len2; j++) {
39
- const part = parts[j];
40
- const index = path.indexOf(part, pos);
41
- if (index !== pos) {
42
- continue ROUTES_LOOP;
25
+ const hasStar = routePath.indexOf("*") !== -1;
26
+ const hasLabel = routePath.indexOf(":") !== -1;
27
+ if (!hasStar && !hasLabel) {
28
+ if (routePath === path || routePath + "/" === path) {
29
+ handlers.push([handler, emptyParams]);
43
30
  }
44
- pos += part.length;
45
- if (j === lastIndex) {
46
- if (!endsWithStar && pos !== path.length && !(pos === path.length - 1 && path.charCodeAt(pos) === 47)) {
47
- continue ROUTES_LOOP;
48
- }
49
- } else {
50
- const index2 = path.indexOf("/", pos);
51
- if (index2 === -1) {
31
+ } else if (hasStar && !hasLabel) {
32
+ const endsWithStar = routePath.charCodeAt(routePath.length - 1) === 42;
33
+ const parts = (endsWithStar ? routePath.slice(0, -2) : routePath).split(splitByStarRe);
34
+ const lastIndex = parts.length - 1;
35
+ for (let j = 0, pos = 0, len2 = parts.length; j < len2; j++) {
36
+ const part = parts[j];
37
+ const index = path.indexOf(part, pos);
38
+ if (index !== pos) {
52
39
  continue ROUTES_LOOP;
53
40
  }
54
- pos = index2;
55
- }
56
- }
57
- handlers.push([handler, emptyParams]);
58
- } else if (hasLabel && !hasStar) {
59
- const params = /* @__PURE__ */ Object.create(null);
60
- const parts = routePath.match(splitPathRe);
61
- const lastIndex = parts.length - 1;
62
- for (let j = 0, pos = 0, len2 = parts.length; j < len2; j++) {
63
- if (pos === -1 || pos >= path.length) {
64
- continue ROUTES_LOOP;
65
- }
66
- const part = parts[j];
67
- if (part.charCodeAt(1) === 58) {
68
- let name = part.slice(2);
69
- let value;
70
- if (name.charCodeAt(name.length - 1) === 125) {
71
- const openBracePos = name.indexOf("{");
72
- const pattern = name.slice(openBracePos + 1, -1);
73
- const restPath = path.slice(pos + 1);
74
- const match = new RegExp(pattern, "d").exec(restPath);
75
- if (!match || match.indices[0][0] !== 0 || match.indices[0][1] === 0) {
41
+ pos += part.length;
42
+ if (j === lastIndex) {
43
+ if (!endsWithStar && pos !== path.length && !(pos === path.length - 1 && path.charCodeAt(pos) === 47)) {
76
44
  continue ROUTES_LOOP;
77
45
  }
78
- name = name.slice(0, openBracePos);
79
- value = restPath.slice(...match.indices[0]);
80
- pos += match.indices[0][1] + 1;
81
46
  } else {
82
- let endValuePos = path.indexOf("/", pos + 1);
83
- if (endValuePos === -1) {
84
- if (pos + 1 === path.length) {
85
- continue ROUTES_LOOP;
86
- }
87
- endValuePos = path.length;
47
+ const index2 = path.indexOf("/", pos);
48
+ if (index2 === -1) {
49
+ continue ROUTES_LOOP;
88
50
  }
89
- value = path.slice(pos + 1, endValuePos);
90
- pos = endValuePos;
91
- }
92
- params[name] ||= value;
93
- } else {
94
- const index = path.indexOf(part, pos);
95
- if (index !== pos) {
96
- continue ROUTES_LOOP;
51
+ pos = index2;
97
52
  }
98
- pos += part.length;
99
53
  }
100
- if (j === lastIndex) {
101
- if (pos !== path.length && !(pos === path.length - 1 && path.charCodeAt(pos) === 47)) {
54
+ handlers.push([handler, emptyParams]);
55
+ } else if (hasLabel && !hasStar) {
56
+ const params = /* @__PURE__ */ Object.create(null);
57
+ const parts = routePath.match(splitPathRe);
58
+ const lastIndex = parts.length - 1;
59
+ for (let j = 0, pos = 0, len2 = parts.length; j < len2; j++) {
60
+ if (pos === -1 || pos >= path.length) {
102
61
  continue ROUTES_LOOP;
103
62
  }
63
+ const part = parts[j];
64
+ if (part.charCodeAt(1) === 58) {
65
+ let name = part.slice(2);
66
+ let value;
67
+ if (name.charCodeAt(name.length - 1) === 125) {
68
+ const openBracePos = name.indexOf("{");
69
+ const pattern = name.slice(openBracePos + 1, -1);
70
+ const restPath = path.slice(pos + 1);
71
+ const match = new RegExp(pattern, "d").exec(restPath);
72
+ if (!match || match.indices[0][0] !== 0 || match.indices[0][1] === 0) {
73
+ continue ROUTES_LOOP;
74
+ }
75
+ name = name.slice(0, openBracePos);
76
+ value = restPath.slice(...match.indices[0]);
77
+ pos += match.indices[0][1] + 1;
78
+ } else {
79
+ let endValuePos = path.indexOf("/", pos + 1);
80
+ if (endValuePos === -1) {
81
+ if (pos + 1 === path.length) {
82
+ continue ROUTES_LOOP;
83
+ }
84
+ endValuePos = path.length;
85
+ }
86
+ value = path.slice(pos + 1, endValuePos);
87
+ pos = endValuePos;
88
+ }
89
+ params[name] ||= value;
90
+ } else {
91
+ const index = path.indexOf(part, pos);
92
+ if (index !== pos) {
93
+ continue ROUTES_LOOP;
94
+ }
95
+ pos += part.length;
96
+ }
97
+ if (j === lastIndex) {
98
+ if (pos !== path.length && !(pos === path.length - 1 && path.charCodeAt(pos) === 47)) {
99
+ continue ROUTES_LOOP;
100
+ }
101
+ }
104
102
  }
103
+ handlers.push([handler, params]);
104
+ } else if (hasLabel && hasStar) {
105
+ throw new UnsupportedPathError();
105
106
  }
106
- handlers.push([handler, params]);
107
- } else if (hasLabel && hasStar) {
108
- throw new UnsupportedPathError();
109
107
  }
110
108
  }
111
109
  return [handlers];
@@ -28,8 +28,9 @@ var PatternRouter = class {
28
28
  }
29
29
  match(method, path) {
30
30
  const handlers = [];
31
- for (const [pattern, routeMethod, handler] of this.routes) {
32
- if (routeMethod === METHOD_NAME_ALL || routeMethod === method) {
31
+ for (let i = 0, len = this.routes.length; i < len; i++) {
32
+ const [pattern, routeMethod, handler] = this.routes[i];
33
+ if (routeMethod === method || routeMethod === METHOD_NAME_ALL) {
33
34
  const match = pattern.exec(path);
34
35
  if (match) {
35
36
  handlers.push([handler, match.groups || /* @__PURE__ */ Object.create(null)]);
@@ -24,9 +24,9 @@ var SmartRouter = class {
24
24
  for (; i < len; i++) {
25
25
  const router = routers[i];
26
26
  try {
27
- routes.forEach((args) => {
28
- router.add(...args);
29
- });
27
+ for (let i2 = 0, len2 = routes.length; i2 < len2; i2++) {
28
+ router.add(...routes[i2]);
29
+ }
30
30
  res = router.match(method, path);
31
31
  } catch (e) {
32
32
  if (e instanceof UnsupportedPathError) {