hono 4.9.11 → 4.10.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.
@@ -21,20 +21,38 @@ __export(proxy_exports, {
21
21
  proxy: () => proxy
22
22
  });
23
23
  module.exports = __toCommonJS(proxy_exports);
24
+ var import_http_exception = require("../../http-exception");
24
25
  const hopByHopHeaders = [
25
26
  "connection",
26
27
  "keep-alive",
27
28
  "proxy-authenticate",
28
29
  "proxy-authorization",
29
30
  "te",
30
- "trailers",
31
- "transfer-encoding"
31
+ "trailer",
32
+ "transfer-encoding",
33
+ "upgrade"
32
34
  ];
33
- const buildRequestInitFromRequest = (request) => {
35
+ const ALLOWED_TOKEN_PATTERN = /^[!#$%&'*+\-.0-9A-Z^_`a-z|~]+$/;
36
+ const buildRequestInitFromRequest = (request, strictConnectionProcessing) => {
34
37
  if (!request) {
35
38
  return {};
36
39
  }
37
40
  const headers = new Headers(request.headers);
41
+ if (strictConnectionProcessing) {
42
+ const connectionValue = headers.get("connection");
43
+ if (connectionValue) {
44
+ const headerNames = connectionValue.split(",").map((h) => h.trim());
45
+ const invalidHeaders = headerNames.filter((h) => !ALLOWED_TOKEN_PATTERN.test(h));
46
+ if (invalidHeaders.length > 0) {
47
+ throw new import_http_exception.HTTPException(400, {
48
+ message: `Invalid Connection header value: ${invalidHeaders.join(", ")}`
49
+ });
50
+ }
51
+ headerNames.forEach((headerName) => {
52
+ headers.delete(headerName);
53
+ });
54
+ }
55
+ }
38
56
  hopByHopHeaders.forEach((header) => {
39
57
  headers.delete(header);
40
58
  });
@@ -62,9 +80,14 @@ const preprocessRequestInit = (requestInit) => {
62
80
  return requestInit;
63
81
  };
64
82
  const proxy = async (input, proxyInit) => {
65
- const { raw, customFetch, ...requestInit } = proxyInit instanceof Request ? { raw: proxyInit } : proxyInit ?? {};
83
+ const {
84
+ raw,
85
+ customFetch,
86
+ strictConnectionProcessing = false,
87
+ ...requestInit
88
+ } = proxyInit instanceof Request ? { raw: proxyInit } : proxyInit ?? {};
66
89
  const req = new Request(input, {
67
- ...buildRequestInitFromRequest(raw),
90
+ ...buildRequestInitFromRequest(raw, strictConnectionProcessing),
68
91
  ...preprocessRequestInit(requestInit)
69
92
  });
70
93
  req.headers.delete("accept-encoding");
@@ -23,6 +23,7 @@ __export(ssg_exports, {
23
23
  combineAfterResponseHooks: () => combineAfterResponseHooks,
24
24
  combineBeforeRequestHooks: () => combineBeforeRequestHooks,
25
25
  defaultExtensionMap: () => defaultExtensionMap,
26
+ defaultPlugin: () => defaultPlugin,
26
27
  fetchRoutesContent: () => fetchRoutesContent,
27
28
  saveContentToFile: () => saveContentToFile,
28
29
  toSSG: () => toSSG
@@ -213,11 +214,19 @@ const saveContentToFile = async (data, fsModule, outDir, extensionMap) => {
213
214
  }
214
215
  return filePath;
215
216
  };
217
+ const defaultPlugin = {
218
+ afterResponseHook: (res) => {
219
+ if (res.status !== 200) {
220
+ return false;
221
+ }
222
+ return res;
223
+ }
224
+ };
216
225
  const toSSG = async (app, fs, options) => {
217
226
  let result;
218
227
  const getInfoPromises = [];
219
228
  const savePromises = [];
220
- const plugins = options?.plugins || [];
229
+ const plugins = options?.plugins || [defaultPlugin];
221
230
  const beforeRequestHooks = [];
222
231
  const afterResponseHooks = [];
223
232
  const afterGenerateHooks = [];
@@ -310,6 +319,7 @@ const toSSG = async (app, fs, options) => {
310
319
  combineAfterResponseHooks,
311
320
  combineBeforeRequestHooks,
312
321
  defaultExtensionMap,
322
+ defaultPlugin,
313
323
  fetchRoutesContent,
314
324
  saveContentToFile,
315
325
  toSSG
@@ -18,9 +18,11 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var request_exports = {};
20
20
  __export(request_exports, {
21
- HonoRequest: () => HonoRequest
21
+ HonoRequest: () => HonoRequest,
22
+ cloneRawRequest: () => cloneRawRequest
22
23
  });
23
24
  module.exports = __toCommonJS(request_exports);
25
+ var import_http_exception = require("./http-exception");
24
26
  var import_constants = require("./request/constants");
25
27
  var import_body = require("./utils/body");
26
28
  var import_url = require("./utils/url");
@@ -133,7 +135,34 @@ class HonoRequest {
133
135
  return this.#matchResult[0].map(([[, route]]) => route)[this.routeIndex].path;
134
136
  }
135
137
  }
138
+ const cloneRawRequest = async (req) => {
139
+ if (!req.raw.bodyUsed) {
140
+ return req.raw.clone();
141
+ }
142
+ const cacheKey = Object.keys(req.bodyCache)[0];
143
+ if (!cacheKey) {
144
+ throw new import_http_exception.HTTPException(500, {
145
+ message: "Cannot clone request: body was already consumed and not cached. Please use HonoRequest methods (e.g., req.json(), req.text()) instead of consuming req.raw directly."
146
+ });
147
+ }
148
+ const requestInit = {
149
+ body: await req[cacheKey](),
150
+ cache: req.raw.cache,
151
+ credentials: req.raw.credentials,
152
+ headers: req.header(),
153
+ integrity: req.raw.integrity,
154
+ keepalive: req.raw.keepalive,
155
+ method: req.method,
156
+ mode: req.raw.mode,
157
+ redirect: req.raw.redirect,
158
+ referrer: req.raw.referrer,
159
+ referrerPolicy: req.raw.referrerPolicy,
160
+ signal: req.raw.signal
161
+ };
162
+ return new Request(req.url, requestInit);
163
+ };
136
164
  // Annotate the CommonJS export names for ESM import in node:
137
165
  0 && (module.exports = {
138
- HonoRequest
166
+ HonoRequest,
167
+ cloneRawRequest
139
168
  });
@@ -18,16 +18,14 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var matcher_exports = {};
20
20
  __export(matcher_exports, {
21
- buildAllMatchersKey: () => buildAllMatchersKey,
22
21
  emptyParam: () => emptyParam,
23
22
  match: () => match
24
23
  });
25
24
  module.exports = __toCommonJS(matcher_exports);
26
25
  var import_router = require("../../router");
27
26
  const emptyParam = [];
28
- const buildAllMatchersKey = Symbol("buildAllMatchers");
29
27
  function match(method, path) {
30
- const matchers = this[buildAllMatchersKey]();
28
+ const matchers = this.buildAllMatchers();
31
29
  const match2 = (method2, path2) => {
32
30
  const matcher = matchers[method2] || matchers[import_router.METHOD_NAME_ALL];
33
31
  const staticMatch = matcher[2][path2];
@@ -46,7 +44,6 @@ function match(method, path) {
46
44
  }
47
45
  // Annotate the CommonJS export names for ESM import in node:
48
46
  0 && (module.exports = {
49
- buildAllMatchersKey,
50
47
  emptyParam,
51
48
  match
52
49
  });
@@ -34,25 +34,48 @@ class PreparedRegExpRouter {
34
34
  this.#matchers = matchers;
35
35
  this.#relocateMap = relocateMap;
36
36
  }
37
+ #addWildcard(method, handlerData) {
38
+ const matcher = this.#matchers[method];
39
+ matcher[1].forEach((list) => list && list.push(handlerData));
40
+ Object.values(matcher[2]).forEach((list) => list[0].push(handlerData));
41
+ }
42
+ #addPath(method, path, handler, indexes, map) {
43
+ const matcher = this.#matchers[method];
44
+ if (!map) {
45
+ matcher[2][path][0].push([handler, {}]);
46
+ } else {
47
+ indexes.forEach((index) => {
48
+ if (typeof index === "number") {
49
+ matcher[1][index].push([handler, map]);
50
+ } else {
51
+ ;
52
+ matcher[2][index || path][0].push([handler, map]);
53
+ }
54
+ });
55
+ }
56
+ }
37
57
  add(method, path, handler) {
38
- const all = this.#matchers[import_router.METHOD_NAME_ALL];
39
- this.#matchers[method] ||= [
40
- all[0],
41
- all[1].map((list) => Array.isArray(list) ? list.slice() : 0),
42
- Object.keys(all[2]).reduce((obj, key) => {
43
- obj[key] = [all[2][key][0].slice(), import_matcher.emptyParam];
44
- return obj;
45
- }, {})
46
- ];
58
+ if (!this.#matchers[method]) {
59
+ const all = this.#matchers[import_router.METHOD_NAME_ALL];
60
+ const staticMap = {};
61
+ for (const key in all[2]) {
62
+ staticMap[key] = [all[2][key][0].slice(), import_matcher.emptyParam];
63
+ }
64
+ this.#matchers[method] = [
65
+ all[0],
66
+ all[1].map((list) => Array.isArray(list) ? list.slice() : 0),
67
+ staticMap
68
+ ];
69
+ }
47
70
  if (path === "/*" || path === "*") {
48
- const defaultHandlerData = [handler, {}];
49
- (method === import_router.METHOD_NAME_ALL ? Object.keys(this.#matchers) : [method]).forEach((m) => {
50
- const matcher = this.#matchers[m];
51
- matcher[1].forEach((list) => list && list.push(defaultHandlerData));
52
- Object.values(matcher[2]).forEach(
53
- (list) => list[0].push(defaultHandlerData)
54
- );
55
- });
71
+ const handlerData = [handler, {}];
72
+ if (method === import_router.METHOD_NAME_ALL) {
73
+ for (const m in this.#matchers) {
74
+ this.#addWildcard(m, handlerData);
75
+ }
76
+ } else {
77
+ this.#addWildcard(method, handlerData);
78
+ }
56
79
  return;
57
80
  }
58
81
  const data = this.#relocateMap[path];
@@ -60,38 +83,37 @@ class PreparedRegExpRouter {
60
83
  throw new Error(`Path ${path} is not registered`);
61
84
  }
62
85
  for (const [indexes, map] of data) {
63
- ;
64
- (method === import_router.METHOD_NAME_ALL ? Object.keys(this.#matchers) : [method]).forEach((m) => {
65
- const matcher = this.#matchers[m];
66
- if (!map) {
67
- matcher[2][path][0].push([handler, {}]);
68
- } else {
69
- indexes.forEach((index) => {
70
- if (typeof index === "number") {
71
- matcher[1][index].push([handler, map]);
72
- } else {
73
- ;
74
- matcher[2][index || path][0].push([handler, map]);
75
- }
76
- });
86
+ if (method === import_router.METHOD_NAME_ALL) {
87
+ for (const m in this.#matchers) {
88
+ this.#addPath(m, path, handler, indexes, map);
77
89
  }
78
- });
90
+ } else {
91
+ this.#addPath(method, path, handler, indexes, map);
92
+ }
79
93
  }
80
94
  }
81
- [import_matcher.buildAllMatchersKey]() {
95
+ buildAllMatchers() {
82
96
  return this.#matchers;
83
97
  }
84
98
  match = import_matcher.match;
85
99
  }
86
100
  const buildInitParams = ({ paths }) => {
87
- const router = new import_router2.RegExpRouter();
101
+ const RegExpRouterWithMatcherExport = class extends import_router2.RegExpRouter {
102
+ buildAndExportAllMatchers() {
103
+ return this.buildAllMatchers();
104
+ }
105
+ };
106
+ const router = new RegExpRouterWithMatcherExport();
88
107
  for (const path of paths) {
89
108
  router.add(import_router.METHOD_NAME_ALL, path, path);
90
109
  }
91
- const matchers = router[import_matcher.buildAllMatchersKey]();
110
+ const matchers = router.buildAndExportAllMatchers();
92
111
  const all = matchers[import_router.METHOD_NAME_ALL];
93
112
  const relocateMap = {};
94
113
  for (const path of paths) {
114
+ if (path === "/*" || path === "*") {
115
+ continue;
116
+ }
95
117
  all[1].forEach((list, i) => {
96
118
  list.forEach(([p, map]) => {
97
119
  if (p === path) {
@@ -112,7 +134,7 @@ const buildInitParams = ({ paths }) => {
112
134
  for (const path2 in all[2]) {
113
135
  all[2][path2][0].forEach(([p]) => {
114
136
  if (p === path) {
115
- relocateMap[path] ||= [[[], void 0]];
137
+ relocateMap[path] ||= [[[]]];
116
138
  const value = path2 === path ? "" : path2;
117
139
  if (relocateMap[path][0][0].findIndex((v) => v === value) === -1) {
118
140
  relocateMap[path][0][0].push(value);
@@ -130,16 +152,10 @@ const buildInitParams = ({ paths }) => {
130
152
  return [matchers, relocateMap];
131
153
  };
132
154
  const serializeInitParams = ([matchers, relocateMap]) => {
133
- for (const method in matchers) {
134
- const matcher = matchers[method];
135
- matcher[0].toJSON = function() {
136
- return `@${this.toString()}@`;
137
- };
138
- }
139
- const matchersStr = JSON.stringify(matchers).replace(
140
- /"@(.+?)@"/g,
141
- (_, str) => str.replace(/\\\\/g, "\\")
142
- );
155
+ const matchersStr = JSON.stringify(
156
+ matchers,
157
+ (_, value) => value instanceof RegExp ? `##${value.toString()}##` : value
158
+ ).replace(/"##(.+?)##"/g, (_, str) => str.replace(/\\\\/g, "\\"));
143
159
  const relocateMapStr = JSON.stringify(relocateMap);
144
160
  return `[${matchersStr},${relocateMapStr}]`;
145
161
  };
@@ -173,7 +173,7 @@ class RegExpRouter {
173
173
  }
174
174
  }
175
175
  match = import_matcher.match;
176
- [import_matcher.buildAllMatchersKey]() {
176
+ buildAllMatchers() {
177
177
  const matchers = /* @__PURE__ */ Object.create(null);
178
178
  Object.keys(this.#routes).concat(Object.keys(this.#middleware)).forEach((method) => {
179
179
  matchers[method] ||= this.#buildMatcher(method);
@@ -100,7 +100,7 @@ const validator = (target, validationFunc) => {
100
100
  return res;
101
101
  }
102
102
  c.req.addValidatedData(target, res);
103
- await next();
103
+ return await next();
104
104
  };
105
105
  };
106
106
  // Annotate the CommonJS export names for ESM import in node:
@@ -1,18 +1,36 @@
1
1
  // src/helper/proxy/index.ts
2
+ import { HTTPException } from "../../http-exception.js";
2
3
  var hopByHopHeaders = [
3
4
  "connection",
4
5
  "keep-alive",
5
6
  "proxy-authenticate",
6
7
  "proxy-authorization",
7
8
  "te",
8
- "trailers",
9
- "transfer-encoding"
9
+ "trailer",
10
+ "transfer-encoding",
11
+ "upgrade"
10
12
  ];
11
- var buildRequestInitFromRequest = (request) => {
13
+ var ALLOWED_TOKEN_PATTERN = /^[!#$%&'*+\-.0-9A-Z^_`a-z|~]+$/;
14
+ var buildRequestInitFromRequest = (request, strictConnectionProcessing) => {
12
15
  if (!request) {
13
16
  return {};
14
17
  }
15
18
  const headers = new Headers(request.headers);
19
+ if (strictConnectionProcessing) {
20
+ const connectionValue = headers.get("connection");
21
+ if (connectionValue) {
22
+ const headerNames = connectionValue.split(",").map((h) => h.trim());
23
+ const invalidHeaders = headerNames.filter((h) => !ALLOWED_TOKEN_PATTERN.test(h));
24
+ if (invalidHeaders.length > 0) {
25
+ throw new HTTPException(400, {
26
+ message: `Invalid Connection header value: ${invalidHeaders.join(", ")}`
27
+ });
28
+ }
29
+ headerNames.forEach((headerName) => {
30
+ headers.delete(headerName);
31
+ });
32
+ }
33
+ }
16
34
  hopByHopHeaders.forEach((header) => {
17
35
  headers.delete(header);
18
36
  });
@@ -40,9 +58,14 @@ var preprocessRequestInit = (requestInit) => {
40
58
  return requestInit;
41
59
  };
42
60
  var proxy = async (input, proxyInit) => {
43
- const { raw, customFetch, ...requestInit } = proxyInit instanceof Request ? { raw: proxyInit } : proxyInit ?? {};
61
+ const {
62
+ raw,
63
+ customFetch,
64
+ strictConnectionProcessing = false,
65
+ ...requestInit
66
+ } = proxyInit instanceof Request ? { raw: proxyInit } : proxyInit ?? {};
44
67
  const req = new Request(input, {
45
- ...buildRequestInitFromRequest(raw),
68
+ ...buildRequestInitFromRequest(raw, strictConnectionProcessing),
46
69
  ...preprocessRequestInit(requestInit)
47
70
  });
48
71
  req.headers.delete("accept-encoding");
@@ -184,11 +184,19 @@ var saveContentToFile = async (data, fsModule, outDir, extensionMap) => {
184
184
  }
185
185
  return filePath;
186
186
  };
187
+ var defaultPlugin = {
188
+ afterResponseHook: (res) => {
189
+ if (res.status !== 200) {
190
+ return false;
191
+ }
192
+ return res;
193
+ }
194
+ };
187
195
  var toSSG = async (app, fs, options) => {
188
196
  let result;
189
197
  const getInfoPromises = [];
190
198
  const savePromises = [];
191
- const plugins = options?.plugins || [];
199
+ const plugins = options?.plugins || [defaultPlugin];
192
200
  const beforeRequestHooks = [];
193
201
  const afterResponseHooks = [];
194
202
  const afterGenerateHooks = [];
@@ -280,6 +288,7 @@ export {
280
288
  combineAfterResponseHooks,
281
289
  combineBeforeRequestHooks,
282
290
  defaultExtensionMap,
291
+ defaultPlugin,
283
292
  fetchRoutesContent,
284
293
  saveContentToFile,
285
294
  toSSG
package/dist/request.js CHANGED
@@ -1,4 +1,5 @@
1
1
  // src/request.ts
2
+ import { HTTPException } from "./http-exception.js";
2
3
  import { GET_MATCH_RESULT } from "./request/constants.js";
3
4
  import { parseBody } from "./utils/body.js";
4
5
  import { decodeURIComponent_, getQueryParam, getQueryParams, tryDecode } from "./utils/url.js";
@@ -111,6 +112,33 @@ var HonoRequest = class {
111
112
  return this.#matchResult[0].map(([[, route]]) => route)[this.routeIndex].path;
112
113
  }
113
114
  };
115
+ var cloneRawRequest = async (req) => {
116
+ if (!req.raw.bodyUsed) {
117
+ return req.raw.clone();
118
+ }
119
+ const cacheKey = Object.keys(req.bodyCache)[0];
120
+ if (!cacheKey) {
121
+ throw new HTTPException(500, {
122
+ message: "Cannot clone request: body was already consumed and not cached. Please use HonoRequest methods (e.g., req.json(), req.text()) instead of consuming req.raw directly."
123
+ });
124
+ }
125
+ const requestInit = {
126
+ body: await req[cacheKey](),
127
+ cache: req.raw.cache,
128
+ credentials: req.raw.credentials,
129
+ headers: req.header(),
130
+ integrity: req.raw.integrity,
131
+ keepalive: req.raw.keepalive,
132
+ method: req.method,
133
+ mode: req.raw.mode,
134
+ redirect: req.raw.redirect,
135
+ referrer: req.raw.referrer,
136
+ referrerPolicy: req.raw.referrerPolicy,
137
+ signal: req.raw.signal
138
+ };
139
+ return new Request(req.url, requestInit);
140
+ };
114
141
  export {
115
- HonoRequest
142
+ HonoRequest,
143
+ cloneRawRequest
116
144
  };
@@ -1,9 +1,8 @@
1
1
  // src/router/reg-exp-router/matcher.ts
2
2
  import { METHOD_NAME_ALL } from "../../router.js";
3
3
  var emptyParam = [];
4
- var buildAllMatchersKey = Symbol("buildAllMatchers");
5
4
  function match(method, path) {
6
- const matchers = this[buildAllMatchersKey]();
5
+ const matchers = this.buildAllMatchers();
7
6
  const match2 = (method2, path2) => {
8
7
  const matcher = matchers[method2] || matchers[METHOD_NAME_ALL];
9
8
  const staticMatch = matcher[2][path2];
@@ -21,7 +20,6 @@ function match(method, path) {
21
20
  return match2(method, path);
22
21
  }
23
22
  export {
24
- buildAllMatchersKey,
25
23
  emptyParam,
26
24
  match
27
25
  };
@@ -1,6 +1,6 @@
1
1
  // src/router/reg-exp-router/prepared-router.ts
2
2
  import { METHOD_NAME_ALL } from "../../router.js";
3
- import { match, buildAllMatchersKey, emptyParam } from "./matcher.js";
3
+ import { match, emptyParam } from "./matcher.js";
4
4
  import { RegExpRouter } from "./router.js";
5
5
  var PreparedRegExpRouter = class {
6
6
  name = "PreparedRegExpRouter";
@@ -10,25 +10,48 @@ var PreparedRegExpRouter = class {
10
10
  this.#matchers = matchers;
11
11
  this.#relocateMap = relocateMap;
12
12
  }
13
+ #addWildcard(method, handlerData) {
14
+ const matcher = this.#matchers[method];
15
+ matcher[1].forEach((list) => list && list.push(handlerData));
16
+ Object.values(matcher[2]).forEach((list) => list[0].push(handlerData));
17
+ }
18
+ #addPath(method, path, handler, indexes, map) {
19
+ const matcher = this.#matchers[method];
20
+ if (!map) {
21
+ matcher[2][path][0].push([handler, {}]);
22
+ } else {
23
+ indexes.forEach((index) => {
24
+ if (typeof index === "number") {
25
+ matcher[1][index].push([handler, map]);
26
+ } else {
27
+ ;
28
+ matcher[2][index || path][0].push([handler, map]);
29
+ }
30
+ });
31
+ }
32
+ }
13
33
  add(method, path, handler) {
14
- const all = this.#matchers[METHOD_NAME_ALL];
15
- this.#matchers[method] ||= [
16
- all[0],
17
- all[1].map((list) => Array.isArray(list) ? list.slice() : 0),
18
- Object.keys(all[2]).reduce((obj, key) => {
19
- obj[key] = [all[2][key][0].slice(), emptyParam];
20
- return obj;
21
- }, {})
22
- ];
34
+ if (!this.#matchers[method]) {
35
+ const all = this.#matchers[METHOD_NAME_ALL];
36
+ const staticMap = {};
37
+ for (const key in all[2]) {
38
+ staticMap[key] = [all[2][key][0].slice(), emptyParam];
39
+ }
40
+ this.#matchers[method] = [
41
+ all[0],
42
+ all[1].map((list) => Array.isArray(list) ? list.slice() : 0),
43
+ staticMap
44
+ ];
45
+ }
23
46
  if (path === "/*" || path === "*") {
24
- const defaultHandlerData = [handler, {}];
25
- (method === METHOD_NAME_ALL ? Object.keys(this.#matchers) : [method]).forEach((m) => {
26
- const matcher = this.#matchers[m];
27
- matcher[1].forEach((list) => list && list.push(defaultHandlerData));
28
- Object.values(matcher[2]).forEach(
29
- (list) => list[0].push(defaultHandlerData)
30
- );
31
- });
47
+ const handlerData = [handler, {}];
48
+ if (method === METHOD_NAME_ALL) {
49
+ for (const m in this.#matchers) {
50
+ this.#addWildcard(m, handlerData);
51
+ }
52
+ } else {
53
+ this.#addWildcard(method, handlerData);
54
+ }
32
55
  return;
33
56
  }
34
57
  const data = this.#relocateMap[path];
@@ -36,38 +59,37 @@ var PreparedRegExpRouter = class {
36
59
  throw new Error(`Path ${path} is not registered`);
37
60
  }
38
61
  for (const [indexes, map] of data) {
39
- ;
40
- (method === METHOD_NAME_ALL ? Object.keys(this.#matchers) : [method]).forEach((m) => {
41
- const matcher = this.#matchers[m];
42
- if (!map) {
43
- matcher[2][path][0].push([handler, {}]);
44
- } else {
45
- indexes.forEach((index) => {
46
- if (typeof index === "number") {
47
- matcher[1][index].push([handler, map]);
48
- } else {
49
- ;
50
- matcher[2][index || path][0].push([handler, map]);
51
- }
52
- });
62
+ if (method === METHOD_NAME_ALL) {
63
+ for (const m in this.#matchers) {
64
+ this.#addPath(m, path, handler, indexes, map);
53
65
  }
54
- });
66
+ } else {
67
+ this.#addPath(method, path, handler, indexes, map);
68
+ }
55
69
  }
56
70
  }
57
- [buildAllMatchersKey]() {
71
+ buildAllMatchers() {
58
72
  return this.#matchers;
59
73
  }
60
74
  match = match;
61
75
  };
62
76
  var buildInitParams = ({ paths }) => {
63
- const router = new RegExpRouter();
77
+ const RegExpRouterWithMatcherExport = class extends RegExpRouter {
78
+ buildAndExportAllMatchers() {
79
+ return this.buildAllMatchers();
80
+ }
81
+ };
82
+ const router = new RegExpRouterWithMatcherExport();
64
83
  for (const path of paths) {
65
84
  router.add(METHOD_NAME_ALL, path, path);
66
85
  }
67
- const matchers = router[buildAllMatchersKey]();
86
+ const matchers = router.buildAndExportAllMatchers();
68
87
  const all = matchers[METHOD_NAME_ALL];
69
88
  const relocateMap = {};
70
89
  for (const path of paths) {
90
+ if (path === "/*" || path === "*") {
91
+ continue;
92
+ }
71
93
  all[1].forEach((list, i) => {
72
94
  list.forEach(([p, map]) => {
73
95
  if (p === path) {
@@ -88,7 +110,7 @@ var buildInitParams = ({ paths }) => {
88
110
  for (const path2 in all[2]) {
89
111
  all[2][path2][0].forEach(([p]) => {
90
112
  if (p === path) {
91
- relocateMap[path] ||= [[[], void 0]];
113
+ relocateMap[path] ||= [[[]]];
92
114
  const value = path2 === path ? "" : path2;
93
115
  if (relocateMap[path][0][0].findIndex((v) => v === value) === -1) {
94
116
  relocateMap[path][0][0].push(value);
@@ -106,16 +128,10 @@ var buildInitParams = ({ paths }) => {
106
128
  return [matchers, relocateMap];
107
129
  };
108
130
  var serializeInitParams = ([matchers, relocateMap]) => {
109
- for (const method in matchers) {
110
- const matcher = matchers[method];
111
- matcher[0].toJSON = function() {
112
- return `@${this.toString()}@`;
113
- };
114
- }
115
- const matchersStr = JSON.stringify(matchers).replace(
116
- /"@(.+?)@"/g,
117
- (_, str) => str.replace(/\\\\/g, "\\")
118
- );
131
+ const matchersStr = JSON.stringify(
132
+ matchers,
133
+ (_, value) => value instanceof RegExp ? `##${value.toString()}##` : value
134
+ ).replace(/"##(.+?)##"/g, (_, str) => str.replace(/\\\\/g, "\\"));
119
135
  const relocateMapStr = JSON.stringify(relocateMap);
120
136
  return `[${matchersStr},${relocateMapStr}]`;
121
137
  };
@@ -5,7 +5,7 @@ import {
5
5
  UnsupportedPathError
6
6
  } from "../../router.js";
7
7
  import { checkOptionalParameter } from "../../utils/url.js";
8
- import { match, emptyParam, buildAllMatchersKey } from "./matcher.js";
8
+ import { match, emptyParam } from "./matcher.js";
9
9
  import { PATH_ERROR } from "./node.js";
10
10
  import { Trie } from "./trie.js";
11
11
  var nullMatcher = [/^$/, [], /* @__PURE__ */ Object.create(null)];
@@ -155,7 +155,7 @@ var RegExpRouter = class {
155
155
  }
156
156
  }
157
157
  match = match;
158
- [buildAllMatchersKey]() {
158
+ buildAllMatchers() {
159
159
  const matchers = /* @__PURE__ */ Object.create(null);
160
160
  Object.keys(this.#routes).concat(Object.keys(this.#middleware)).forEach((method) => {
161
161
  matchers[method] ||= this.#buildMatcher(method);