summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDivy Srivastava <dj.srivastava23@gmail.com>2022-08-19 15:54:54 +0530
committerGitHub <noreply@github.com>2022-08-19 15:54:54 +0530
commit25a109d9ea27ad3a76fdce14bba283e953af9bce (patch)
tree68f0280065c9df4be8fa325ba82693879b4b46cd
parent9e576dff7c39cfd510c60ba92aa0d1c15fd24a6b (diff)
chore(bench): add flash router benchmarks (#15495)
-rw-r--r--.dprint.json1
-rw-r--r--cli/bench/http/bun_hono_router.js13
-rw-r--r--cli/bench/http/deno_flash_hono_router.js10
-rw-r--r--cli/bench/testdata/npm/hono/LICENSE21
-rw-r--r--cli/bench/testdata/npm/hono/README.md88
-rw-r--r--cli/bench/testdata/npm/hono/dist/compose.d.ts2
-rw-r--r--cli/bench/testdata/npm/hono/dist/compose.js49
-rw-r--r--cli/bench/testdata/npm/hono/dist/context.d.ts69
-rw-r--r--cli/bench/testdata/npm/hono/dist/context.js112
-rw-r--r--cli/bench/testdata/npm/hono/dist/hono.d.ts56
-rw-r--r--cli/bench/testdata/npm/hono/dist/hono.js128
-rw-r--r--cli/bench/testdata/npm/hono/dist/index.d.ts10
-rw-r--r--cli/bench/testdata/npm/hono/dist/index.js13
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/basic-auth/index.d.ts11
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/basic-auth/index.js48
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/bearer-auth/index.d.ts8
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/bearer-auth/index.js61
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/cache/index.d.ts7
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/cache/index.js32
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/compress/index.d.ts8
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/compress/index.js19
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/cors/index.d.ts12
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/cors/index.js61
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/etag/index.d.ts7
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/etag/index.js27
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/html/index.d.ts3
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/html/index.js36
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/jsx/index.d.ts26
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/jsx/index.js193
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/jsx/jsx-dev-runtime.d.ts2
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/jsx/jsx-dev-runtime.js10
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/jsx/jsx-runtime.d.ts2
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/jsx/jsx-runtime.js7
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/jwt/index.d.ts7
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/jwt/index.js63
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/logger/index.d.ts5
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/logger/index.js49
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/powered-by/index.d.ts3
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/powered-by/index.js10
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/pretty-json/index.d.ts7
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/pretty-json/index.js11
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/serve-static/bun.d.ts7
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/serve-static/bun.js38
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/serve-static/index.d.ts1
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/serve-static/index.js5
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/serve-static/module.d.mts5
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/serve-static/module.mjs13
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/serve-static/serve-static.d.ts9
-rw-r--r--cli/bench/testdata/npm/hono/dist/middleware/serve-static/serve-static.js40
-rw-r--r--cli/bench/testdata/npm/hono/dist/request.d.ts32
-rw-r--r--cli/bench/testdata/npm/hono/dist/request.js78
-rw-r--r--cli/bench/testdata/npm/hono/dist/router.d.ts10
-rw-r--r--cli/bench/testdata/npm/hono/dist/router.js5
-rw-r--r--cli/bench/testdata/npm/hono/dist/router/reg-exp-router/index.d.ts1
-rw-r--r--cli/bench/testdata/npm/hono/dist/router/reg-exp-router/index.js5
-rw-r--r--cli/bench/testdata/npm/hono/dist/router/reg-exp-router/node.d.ts14
-rw-r--r--cli/bench/testdata/npm/hono/dist/router/reg-exp-router/node.js100
-rw-r--r--cli/bench/testdata/npm/hono/dist/router/reg-exp-router/router.d.ts34
-rw-r--r--cli/bench/testdata/npm/hono/dist/router/reg-exp-router/router.js360
-rw-r--r--cli/bench/testdata/npm/hono/dist/router/reg-exp-router/trie.d.ts14
-rw-r--r--cli/bench/testdata/npm/hono/dist/router/reg-exp-router/trie.js42
-rw-r--r--cli/bench/testdata/npm/hono/dist/router/trie-router/index.d.ts1
-rw-r--r--cli/bench/testdata/npm/hono/dist/router/trie-router/index.js5
-rw-r--r--cli/bench/testdata/npm/hono/dist/router/trie-router/node.d.ts20
-rw-r--r--cli/bench/testdata/npm/hono/dist/router/trie-router/node.js168
-rw-r--r--cli/bench/testdata/npm/hono/dist/router/trie-router/router.d.ts8
-rw-r--r--cli/bench/testdata/npm/hono/dist/router/trie-router/router.js16
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/body.d.ts2
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/body.js31
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/buffer.d.ts3
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/buffer.js39
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/cloudflare.d.ts6
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/cloudflare.js39
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/cookie.d.ts13
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/cookie.js40
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/crypto.d.ts10
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/crypto.js53
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/encode.d.ts7
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/encode.js80
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/filepath.d.ts7
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/filepath.js25
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/html.d.ts6
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/html.js38
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/http-status.d.ts2
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/http-status.js50
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/jwt/index.d.ts1
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/jwt/index.js27
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/jwt/jwt.d.ts7
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/jwt/jwt.js101
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/jwt/types.d.ts25
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/jwt/types.js49
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/mime.d.ts1
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/mime.js92
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/url.d.ts6
-rw-r--r--cli/bench/testdata/npm/hono/dist/utils/url.js83
-rw-r--r--cli/bench/testdata/npm/hono/package.json168
-rwxr-xr-xtools/lint.js1
97 files changed, 3350 insertions, 0 deletions
diff --git a/.dprint.json b/.dprint.json
index 65ecc8b5e..62f77f096 100644
--- a/.dprint.json
+++ b/.dprint.json
@@ -20,6 +20,7 @@
".cargo_home",
".git",
"cli/bench/testdata/express-router.js",
+ "cli/bench/testdata/npm/*",
"cli/dts/lib.d.ts",
"cli/dts/lib.dom*",
"cli/dts/lib.es*",
diff --git a/cli/bench/http/bun_hono_router.js b/cli/bench/http/bun_hono_router.js
new file mode 100644
index 000000000..a0bba67d5
--- /dev/null
+++ b/cli/bench/http/bun_hono_router.js
@@ -0,0 +1,13 @@
+// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
+const port = Bun.argv[2] || "4545";
+const { Hono } = require("../testdata/npm/hono/dist/index.js");
+
+const app = new Hono();
+app.get("/", (c) => c.text("Hello, World!"));
+
+Bun.serve({
+ fetch(r) {
+ return app.fetch(r);
+ },
+ port: Number(port),
+});
diff --git a/cli/bench/http/deno_flash_hono_router.js b/cli/bench/http/deno_flash_hono_router.js
new file mode 100644
index 000000000..af6adc9ba
--- /dev/null
+++ b/cli/bench/http/deno_flash_hono_router.js
@@ -0,0 +1,10 @@
+// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
+import { Hono } from "https://deno.land/x/hono@v2.0.9/mod.ts";
+
+const addr = Deno.args[0] || "127.0.0.1:4500";
+const [hostname, port] = addr.split(":");
+
+const app = new Hono();
+app.get("/", (c) => c.text("Hello, World!"));
+
+Deno.serve(app.fetch, { port: Number(port), hostname });
diff --git a/cli/bench/testdata/npm/hono/LICENSE b/cli/bench/testdata/npm/hono/LICENSE
new file mode 100644
index 000000000..c9e631261
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 Yusuke Wada
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/cli/bench/testdata/npm/hono/README.md b/cli/bench/testdata/npm/hono/README.md
new file mode 100644
index 000000000..763e3898a
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/README.md
@@ -0,0 +1,88 @@
+<div align="center">
+ <a href="https://honojs.dev">
+ <img src="https://raw.githubusercontent.com/honojs/hono/main/docs/images/hono-title.png" width="500" height="auto" alt="Hono"/>
+ </a>
+</div>
+
+<hr />
+
+<p align="center">
+<a href="https://honojs.dev"><b>Documentation :point_right: honojs.dev</b></a><br />
+<i>v2.x has been released!</i> <a href="docs/MIGRATION.md">Migration guide</b>
+</p>
+
+<hr />
+
+[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/honojs/hono/ci)](https://github.com/honojs/hono/actions)
+[![GitHub](https://img.shields.io/github/license/honojs/hono)](https://github.com/honojs/hono/blob/main/LICENSE)
+[![npm](https://img.shields.io/npm/v/hono)](https://www.npmjs.com/package/hono)
+[![npm](https://img.shields.io/npm/dm/hono)](https://www.npmjs.com/package/hono)
+[![npm type definitions](https://img.shields.io/npm/types/hono)](https://www.npmjs.com/package/hono)
+[![GitHub commit activity](https://img.shields.io/github/commit-activity/m/honojs/hono)](https://github.com/honojs/hono/pulse)
+[![GitHub last commit](https://img.shields.io/github/last-commit/honojs/hono)](https://github.com/honojs/hono/commits/main)
+[![Deno badge](https://img.shields.io/endpoint?url=https%3A%2F%2Fdeno-visualizer.danopia.net%2Fshields%2Flatest-version%2Fx%2Fhono%2Fmod.ts)](https://doc.deno.land/https/deno.land/x/hono/mod.ts)
+
+Hono - _**[炎] means flame🔥 in Japanese**_ - is a small, simple, and ultrafast web framework for Cloudflare Workers, Deno, Bun, and others.
+
+```ts
+import { Hono } from 'hono'
+const app = new Hono()
+
+app.get('/', (c) => c.text('Hono!!'))
+
+export default app
+```
+
+## Features
+
+- **Ultrafast** - the router does not use linear loops.
+- **Zero-dependencies** - using only Service Worker and Web Standard API.
+- **Middleware** - built-in middleware, custom middleware, and third-party middleware.
+- **TypeScript** - first-class TypeScript support.
+- **Multi-platform** - works on Cloudflare Workers, Fastly Compute@Edge, Deno, or Bun.
+
+## Benchmarks
+
+**Hono is fastest**, compared to other routers for Cloudflare Workers.
+
+```plain
+hono - trie-router(default) x 424,449 ops/sec ±4.98% (77 runs sampled)
+hono - regexp-router x 516,228 ops/sec ±4.79% (81 runs sampled)
+itty-router x 206,641 ops/sec ±3.59% (87 runs sampled)
+sunder x 319,500 ops/sec ±1.33% (93 runs sampled)
+worktop x 187,280 ops/sec ±3.09% (87 runs sampled)
+Fastest is hono - regexp-router
+✨ Done in 38.32s.
+```
+
+## Documentation
+
+The documentation is available on [honojs.dev](https://honojs.dev).
+
+## Migration
+
+Migration guide is available on [docs/MIGRATION.md](docs/MIGRATION.md).
+
+## Contributing
+
+Contributions Welcome! You can contribute in the following ways.
+
+- Create an Issue - Propose a new feature. Report a bug.
+- Pull Request - Fix a bug and typo. Refactor the code.
+- Create third-party middleware - Instruct below.
+- Share - Share your thoughts on the Blog, Twitter, and others.
+- Make your application - Please try to use Hono.
+
+For more details, see [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md).
+
+## Contributors
+
+Thanks to [all contributors](https://github.com/honojs/hono/graphs/contributors)! Especially, [@metrue](https://github.com/metrue) and [@usualoma](https://github.com/usualoma)!
+
+## Author
+
+Yusuke Wada <https://github.com/yusukebe>
+
+## License
+
+Distributed under the MIT License. See [LICENSE](LICENSE) for more information.
diff --git a/cli/bench/testdata/npm/hono/dist/compose.d.ts b/cli/bench/testdata/npm/hono/dist/compose.d.ts
new file mode 100644
index 000000000..495b9bda5
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/compose.d.ts
@@ -0,0 +1,2 @@
+import type { ErrorHandler, NotFoundHandler } from './hono';
+export declare const compose: <C>(middleware: Function[], onError?: ErrorHandler, onNotFound?: NotFoundHandler) => (context: C, next?: Function) => Promise<C>;
diff --git a/cli/bench/testdata/npm/hono/dist/compose.js b/cli/bench/testdata/npm/hono/dist/compose.js
new file mode 100644
index 000000000..3c7e57722
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/compose.js
@@ -0,0 +1,49 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.compose = void 0;
+const context_1 = require("./context");
+// Based on the code in the MIT licensed `koa-compose` package.
+const compose = (middleware, onError, onNotFound) => {
+ const middlewareLength = middleware.length;
+ return (context, next) => {
+ let index = -1;
+ return dispatch(0);
+ async function dispatch(i) {
+ if (i <= index) {
+ throw new Error('next() called multiple times');
+ }
+ let handler = middleware[i];
+ index = i;
+ if (i === middlewareLength && next)
+ handler = next;
+ if (!handler) {
+ if (context instanceof context_1.HonoContext && context.finalized === false && onNotFound) {
+ context.res = await onNotFound(context);
+ }
+ return context;
+ }
+ let res;
+ let isError = false;
+ try {
+ const tmp = handler(context, () => dispatch(i + 1));
+ res = tmp instanceof Promise ? await tmp : tmp;
+ }
+ catch (err) {
+ if (context instanceof context_1.HonoContext && onError) {
+ if (err instanceof Error) {
+ isError = true;
+ res = onError(err, context);
+ }
+ }
+ if (!res) {
+ throw err;
+ }
+ }
+ if (res && context instanceof context_1.HonoContext && (!context.finalized || isError)) {
+ context.res = res;
+ }
+ return context;
+ }
+ };
+};
+exports.compose = compose;
diff --git a/cli/bench/testdata/npm/hono/dist/context.d.ts b/cli/bench/testdata/npm/hono/dist/context.d.ts
new file mode 100644
index 000000000..1f67f6206
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/context.d.ts
@@ -0,0 +1,69 @@
+/// <reference types="@cloudflare/workers-types" />
+import type { ContextVariableMap, NotFoundHandler } from './hono';
+import type { CookieOptions } from './utils/cookie';
+import type { StatusCode } from './utils/http-status';
+declare type Headers = Record<string, string>;
+export declare type Data = string | ArrayBuffer | ReadableStream;
+declare type Env = Record<string, any>;
+export interface Context<RequestParamKeyType extends string = string, E = Env> {
+ req: Request<RequestParamKeyType>;
+ env: E;
+ event: FetchEvent;
+ executionCtx: ExecutionContext;
+ finalized: boolean;
+ get res(): Response;
+ set res(_res: Response);
+ header: (name: string, value: string) => void;
+ status: (status: StatusCode) => void;
+ set: {
+ <Key extends keyof ContextVariableMap>(key: Key, value: ContextVariableMap[Key]): void;
+ (key: string, value: any): void;
+ };
+ get: {
+ <Key extends keyof ContextVariableMap>(key: Key): ContextVariableMap[Key];
+ <T = any>(key: string): T;
+ };
+ pretty: (prettyJSON: boolean, space?: number) => void;
+ newResponse: (data: Data | null, status: StatusCode, headers: Headers) => Response;
+ body: (data: Data | null, status?: StatusCode, headers?: Headers) => Response;
+ text: (text: string, status?: StatusCode, headers?: Headers) => Response;
+ json: <T>(object: T, status?: StatusCode, headers?: Headers) => Response;
+ html: (html: string, status?: StatusCode, headers?: Headers) => Response;
+ redirect: (location: string, status?: StatusCode) => Response;
+ cookie: (name: string, value: string, options?: CookieOptions) => void;
+ notFound: () => Response | Promise<Response>;
+}
+export declare class HonoContext<RequestParamKeyType extends string = string, E = Env> implements Context<RequestParamKeyType, E> {
+ req: Request<RequestParamKeyType>;
+ env: E;
+ finalized: boolean;
+ _status: StatusCode;
+ private _executionCtx;
+ private _pretty;
+ private _prettySpace;
+ private _map;
+ private _headers;
+ private _res;
+ private notFoundHandler;
+ constructor(req: Request, env?: E | undefined, executionCtx?: FetchEvent | ExecutionContext | undefined, notFoundHandler?: NotFoundHandler);
+ get event(): FetchEvent;
+ get executionCtx(): ExecutionContext;
+ get res(): Response;
+ set res(_res: Response);
+ header(name: string, value: string): void;
+ status(status: StatusCode): void;
+ set<Key extends keyof ContextVariableMap>(key: Key, value: ContextVariableMap[Key]): void;
+ set(key: string, value: any): void;
+ get<Key extends keyof ContextVariableMap>(key: Key): ContextVariableMap[Key];
+ get<T = any>(key: string): T;
+ pretty(prettyJSON: boolean, space?: number): void;
+ newResponse(data: Data | null, status: StatusCode, headers?: Headers): Response;
+ body(data: Data | null, status?: StatusCode, headers?: Headers): Response;
+ text(text: string, status?: StatusCode, headers?: Headers): Response;
+ json<T>(object: T, status?: StatusCode, headers?: Headers): Response;
+ html(html: string, status?: StatusCode, headers?: Headers): Response;
+ redirect(location: string, status?: StatusCode): Response;
+ cookie(name: string, value: string, opt?: CookieOptions): void;
+ notFound(): Response | Promise<Response>;
+}
+export {};
diff --git a/cli/bench/testdata/npm/hono/dist/context.js b/cli/bench/testdata/npm/hono/dist/context.js
new file mode 100644
index 000000000..bfbeb4200
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/context.js
@@ -0,0 +1,112 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.HonoContext = void 0;
+const cookie_1 = require("./utils/cookie");
+const url_1 = require("./utils/url");
+class HonoContext {
+ constructor(req, env = undefined, executionCtx = undefined, notFoundHandler = () => new Response()) {
+ this._status = 200;
+ this._pretty = false;
+ this._prettySpace = 2;
+ this._executionCtx = executionCtx;
+ this.req = req;
+ this.env = env ? env : {};
+ this.notFoundHandler = notFoundHandler;
+ this.finalized = false;
+ }
+ get event() {
+ if (this._executionCtx instanceof FetchEvent) {
+ return this._executionCtx;
+ }
+ else {
+ throw Error('This context has no FetchEvent');
+ }
+ }
+ get executionCtx() {
+ if (this._executionCtx) {
+ return this._executionCtx;
+ }
+ else {
+ throw Error('This context has no ExecutionContext');
+ }
+ }
+ get res() {
+ return (this._res || (this._res = new Response()));
+ }
+ set res(_res) {
+ this._res = _res;
+ this.finalized = true;
+ }
+ header(name, value) {
+ this._headers || (this._headers = {});
+ this._headers[name.toLowerCase()] = value;
+ if (this.finalized) {
+ this.res.headers.set(name, value);
+ }
+ }
+ status(status) {
+ this._status = status;
+ }
+ set(key, value) {
+ this._map || (this._map = {});
+ this._map[key] = value;
+ }
+ get(key) {
+ if (!this._map) {
+ return undefined;
+ }
+ return this._map[key];
+ }
+ pretty(prettyJSON, space = 2) {
+ this._pretty = prettyJSON;
+ this._prettySpace = space;
+ }
+ newResponse(data, status, headers = {}) {
+ const _headers = { ...this._headers };
+ if (this._res) {
+ this._res.headers.forEach((v, k) => {
+ _headers[k] = v;
+ });
+ }
+ return new Response(data, {
+ status: status || this._status || 200,
+ headers: { ..._headers, ...headers },
+ });
+ }
+ body(data, status = this._status, headers = {}) {
+ return this.newResponse(data, status, headers);
+ }
+ text(text, status = this._status, headers = {}) {
+ headers['content-type'] = 'text/plain; charset=UTF-8';
+ return this.body(text, status, headers);
+ }
+ json(object, status = this._status, headers = {}) {
+ const body = this._pretty
+ ? JSON.stringify(object, null, this._prettySpace)
+ : JSON.stringify(object);
+ headers['content-type'] = 'application/json; charset=UTF-8';
+ return this.body(body, status, headers);
+ }
+ html(html, status = this._status, headers = {}) {
+ headers['content-type'] = 'text/html; charset=UTF-8';
+ return this.body(html, status, headers);
+ }
+ redirect(location, status = 302) {
+ if (!(0, url_1.isAbsoluteURL)(location)) {
+ const url = new URL(this.req.url);
+ url.pathname = location;
+ location = url.toString();
+ }
+ return this.newResponse(null, status, {
+ Location: location,
+ });
+ }
+ cookie(name, value, opt) {
+ const cookie = (0, cookie_1.serialize)(name, value, opt);
+ this.header('set-cookie', cookie);
+ }
+ notFound() {
+ return this.notFoundHandler(this);
+ }
+}
+exports.HonoContext = HonoContext;
diff --git a/cli/bench/testdata/npm/hono/dist/hono.d.ts b/cli/bench/testdata/npm/hono/dist/hono.d.ts
new file mode 100644
index 000000000..f234d1675
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/hono.d.ts
@@ -0,0 +1,56 @@
+/// <reference types="@cloudflare/workers-types" />
+import type { Context } from './context';
+import type { Router } from './router';
+export interface ContextVariableMap {
+}
+declare type Env = Record<string, any>;
+export declare type Handler<RequestParamKeyType extends string = string, E = Env> = (c: Context<RequestParamKeyType, E>, next: Next) => Response | Promise<Response> | Promise<void> | Promise<Response | undefined>;
+export declare type NotFoundHandler<E = Env> = (c: Context<string, E>) => Response | Promise<Response>;
+export declare type ErrorHandler<E = Env> = (err: Error, c: Context<string, E>) => Response;
+export declare type Next = () => Promise<void>;
+declare type ParamKeyName<NameWithPattern> = NameWithPattern extends `${infer Name}{${infer _Pattern}` ? Name : NameWithPattern;
+declare type ParamKey<Component> = Component extends `:${infer NameWithPattern}` ? ParamKeyName<NameWithPattern> : never;
+declare type ParamKeys<Path> = Path extends `${infer Component}/${infer Rest}` ? ParamKey<Component> | ParamKeys<Rest> : ParamKey<Path>;
+interface HandlerInterface<T extends string, E extends Env = Env, U = Hono<E, T>> {
+ <Path extends string>(path: Path, ...handlers: Handler<ParamKeys<Path> extends never ? string : ParamKeys<Path>, E>[]): U;
+ (path: string, ...handlers: Handler<string, E>[]): U;
+ <Path extends string>(...handlers: Handler<ParamKeys<Path> extends never ? string : ParamKeys<Path>, E>[]): U;
+ (...handlers: Handler<string, E>[]): U;
+}
+interface Route<E extends Env> {
+ path: string;
+ method: string;
+ handler: Handler<string, E>;
+}
+declare const Hono_base: new <E_1 extends Env, T extends string, U>() => {
+ all: HandlerInterface<T, E_1, U>;
+ get: HandlerInterface<T, E_1, U>;
+ post: HandlerInterface<T, E_1, U>;
+ put: HandlerInterface<T, E_1, U>;
+ delete: HandlerInterface<T, E_1, U>;
+ head: HandlerInterface<T, E_1, U>;
+ options: HandlerInterface<T, E_1, U>;
+ patch: HandlerInterface<T, E_1, U>;
+};
+export declare class Hono<E extends Env = Env, P extends string = '/'> extends Hono_base<E, P, Hono<E, P>> {
+ readonly router: Router<Handler<string, E>>;
+ readonly strict: boolean;
+ private _tempPath;
+ private path;
+ routes: Route<E>[];
+ constructor(init?: Partial<Pick<Hono, 'router' | 'strict'>>);
+ private notFoundHandler;
+ private errorHandler;
+ route(path: string, app?: Hono<any>): Hono<E, P>;
+ use(path: string, ...middleware: Handler<string, E>[]): Hono<E, P>;
+ use(...middleware: Handler<string, E>[]): Hono<E, P>;
+ onError(handler: ErrorHandler<E>): Hono<E, P>;
+ notFound(handler: NotFoundHandler<E>): Hono<E, P>;
+ private addRoute;
+ private matchRoute;
+ private dispatch;
+ handleEvent(event: FetchEvent): Promise<Response>;
+ fetch: (request: Request, env?: E, executionCtx?: ExecutionContext) => Promise<Response>;
+ request(input: RequestInfo, requestInit?: RequestInit): Promise<Response>;
+}
+export {};
diff --git a/cli/bench/testdata/npm/hono/dist/hono.js b/cli/bench/testdata/npm/hono/dist/hono.js
new file mode 100644
index 000000000..0b6e67b7f
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/hono.js
@@ -0,0 +1,128 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.Hono = void 0;
+const compose_1 = require("./compose");
+const context_1 = require("./context");
+const request_1 = require("./request");
+const router_1 = require("./router");
+const trie_router_1 = require("./router/trie-router"); // Default Router
+const url_1 = require("./utils/url");
+const methods = ['get', 'post', 'put', 'delete', 'head', 'options', 'patch'];
+function defineDynamicClass() {
+ return class {
+ };
+}
+class Hono extends defineDynamicClass() {
+ constructor(init = {}) {
+ super();
+ this.router = new trie_router_1.TrieRouter();
+ this.strict = true; // strict routing - default is true
+ this._tempPath = '';
+ this.path = '/';
+ this.routes = [];
+ this.notFoundHandler = (c) => {
+ const message = '404 Not Found';
+ return c.text(message, 404);
+ };
+ this.errorHandler = (err, c) => {
+ console.error(`${err.stack || err.message}`);
+ const message = 'Internal Server Error';
+ return c.text(message, 500);
+ };
+ this.fetch = (request, env, executionCtx) => {
+ return this.dispatch(request, executionCtx, env);
+ };
+ (0, request_1.extendRequestPrototype)();
+ const allMethods = [...methods, router_1.METHOD_NAME_ALL_LOWERCASE];
+ allMethods.map((method) => {
+ this[method] = (args1, ...args) => {
+ if (typeof args1 === 'string') {
+ this.path = args1;
+ }
+ else {
+ this.addRoute(method, this.path, args1);
+ }
+ args.map((handler) => {
+ if (typeof handler !== 'string') {
+ this.addRoute(method, this.path, handler);
+ }
+ });
+ return this;
+ };
+ });
+ Object.assign(this, init);
+ }
+ route(path, app) {
+ this._tempPath = path;
+ if (app) {
+ app.routes.map((r) => {
+ this.addRoute(r.method, r.path, r.handler);
+ });
+ this._tempPath = '';
+ }
+ return this;
+ }
+ use(arg1, ...handlers) {
+ if (typeof arg1 === 'string') {
+ this.path = arg1;
+ }
+ else {
+ handlers.unshift(arg1);
+ }
+ handlers.map((handler) => {
+ this.addRoute(router_1.METHOD_NAME_ALL, this.path, handler);
+ });
+ return this;
+ }
+ onError(handler) {
+ this.errorHandler = handler;
+ return this;
+ }
+ notFound(handler) {
+ this.notFoundHandler = handler;
+ return this;
+ }
+ addRoute(method, path, handler) {
+ method = method.toUpperCase();
+ if (this._tempPath) {
+ path = (0, url_1.mergePath)(this._tempPath, path);
+ }
+ this.router.add(method, path, handler);
+ const r = { path: path, method: method, handler: handler };
+ this.routes.push(r);
+ }
+ matchRoute(method, path) {
+ return this.router.match(method, path);
+ }
+ async dispatch(request, eventOrExecutionCtx, env) {
+ const path = (0, url_1.getPathFromURL)(request.url, this.strict);
+ const method = request.method;
+ const result = this.matchRoute(method, path);
+ request.paramData = result?.params;
+ const handlers = result ? result.handlers : [this.notFoundHandler];
+ const c = new context_1.HonoContext(request, env, eventOrExecutionCtx, this.notFoundHandler);
+ const composed = (0, compose_1.compose)(handlers, this.errorHandler, this.notFoundHandler);
+ let context;
+ try {
+ context = await composed(c);
+ if (!context.finalized) {
+ throw new Error('Context is not finalized. You may forget returning Response object or `await next()`');
+ }
+ }
+ catch (err) {
+ if (err instanceof Error) {
+ return this.errorHandler(err, c);
+ }
+ throw err;
+ }
+ return context.res;
+ }
+ handleEvent(event) {
+ return this.dispatch(event.request, event);
+ }
+ request(input, requestInit) {
+ const req = input instanceof Request ? input : new Request(input, requestInit);
+ return this.dispatch(req);
+ }
+}
+exports.Hono = Hono;
diff --git a/cli/bench/testdata/npm/hono/dist/index.d.ts b/cli/bench/testdata/npm/hono/dist/index.d.ts
new file mode 100644
index 000000000..92c9f1881
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/index.d.ts
@@ -0,0 +1,10 @@
+/// <reference path="request.d.ts" />
+import { Hono } from './hono';
+export type { Handler, Next } from './hono';
+export type { Context } from './context';
+declare module './hono' {
+ interface Hono {
+ fire(): void;
+ }
+}
+export { Hono };
diff --git a/cli/bench/testdata/npm/hono/dist/index.js b/cli/bench/testdata/npm/hono/dist/index.js
new file mode 100644
index 000000000..a11e3395f
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/index.js
@@ -0,0 +1,13 @@
+"use strict";
+// @denoify-ignore
+// eslint-disable-next-line @typescript-eslint/triple-slash-reference
+/// <reference path="./request.ts" /> Import "declare global" for the Request interface.
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.Hono = void 0;
+const hono_1 = require("./hono");
+Object.defineProperty(exports, "Hono", { enumerable: true, get: function () { return hono_1.Hono; } });
+hono_1.Hono.prototype.fire = function () {
+ addEventListener('fetch', (event) => {
+ void event.respondWith(this.handleEvent(event));
+ });
+};
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/basic-auth/index.d.ts b/cli/bench/testdata/npm/hono/dist/middleware/basic-auth/index.d.ts
new file mode 100644
index 000000000..072df608f
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/basic-auth/index.d.ts
@@ -0,0 +1,11 @@
+import type { Context } from '../../context';
+import type { Next } from '../../hono';
+export declare const basicAuth: (options: {
+ username: string;
+ password: string;
+ realm?: string;
+ hashFunction?: Function;
+}, ...users: {
+ username: string;
+ password: string;
+}[]) => (ctx: Context, next: Next) => Promise<void>;
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/basic-auth/index.js b/cli/bench/testdata/npm/hono/dist/middleware/basic-auth/index.js
new file mode 100644
index 000000000..c58244a3c
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/basic-auth/index.js
@@ -0,0 +1,48 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.basicAuth = void 0;
+const buffer_1 = require("../../utils/buffer");
+const encode_1 = require("../../utils/encode");
+const CREDENTIALS_REGEXP = /^ *(?:[Bb][Aa][Ss][Ii][Cc]) +([A-Za-z0-9._~+/-]+=*) *$/;
+const USER_PASS_REGEXP = /^([^:]*):(.*)$/;
+const auth = (req) => {
+ const match = CREDENTIALS_REGEXP.exec(req.headers.get('Authorization') || '');
+ if (!match) {
+ return undefined;
+ }
+ const userPass = USER_PASS_REGEXP.exec((0, encode_1.decodeBase64)(match[1]));
+ if (!userPass) {
+ return undefined;
+ }
+ return { username: userPass[1], password: userPass[2] };
+};
+const basicAuth = (options, ...users) => {
+ if (!options) {
+ throw new Error('basic auth middleware requires options for "username and password"');
+ }
+ if (!options.realm) {
+ options.realm = 'Secure Area';
+ }
+ users.unshift({ username: options.username, password: options.password });
+ return async (ctx, next) => {
+ const requestUser = auth(ctx.req);
+ if (requestUser) {
+ for (const user of users) {
+ const usernameEqual = await (0, buffer_1.timingSafeEqual)(user.username, requestUser.username, options.hashFunction);
+ const passwordEqual = await (0, buffer_1.timingSafeEqual)(user.password, requestUser.password, options.hashFunction);
+ if (usernameEqual && passwordEqual) {
+ // Authorized OK
+ await next();
+ return;
+ }
+ }
+ }
+ ctx.res = new Response('Unauthorized', {
+ status: 401,
+ headers: {
+ 'WWW-Authenticate': 'Basic realm="' + options.realm?.replace(/"/g, '\\"') + '"',
+ },
+ });
+ };
+};
+exports.basicAuth = basicAuth;
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/bearer-auth/index.d.ts b/cli/bench/testdata/npm/hono/dist/middleware/bearer-auth/index.d.ts
new file mode 100644
index 000000000..972177fc7
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/bearer-auth/index.d.ts
@@ -0,0 +1,8 @@
+import type { Context } from '../../context';
+import type { Next } from '../../hono';
+export declare const bearerAuth: (options: {
+ token: string;
+ realm?: string;
+ prefix?: string;
+ hashFunction?: Function;
+}) => (c: Context, next: Next) => Promise<void>;
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/bearer-auth/index.js b/cli/bench/testdata/npm/hono/dist/middleware/bearer-auth/index.js
new file mode 100644
index 000000000..da5a78921
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/bearer-auth/index.js
@@ -0,0 +1,61 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.bearerAuth = void 0;
+const buffer_1 = require("../../utils/buffer");
+const TOKEN_STRINGS = '[A-Za-z0-9._~+/-]+=*';
+const PREFIX = 'Bearer';
+const bearerAuth = (options) => {
+ if (!options.token) {
+ throw new Error('bearer auth middleware requires options for "token"');
+ }
+ if (!options.realm) {
+ options.realm = '';
+ }
+ if (!options.prefix) {
+ options.prefix = PREFIX;
+ }
+ const realm = options.realm?.replace(/"/g, '\\"');
+ return async (c, next) => {
+ const headerToken = c.req.headers.get('Authorization');
+ if (!headerToken) {
+ // No Authorization header
+ c.res = new Response('Unauthorized', {
+ status: 401,
+ headers: {
+ 'WWW-Authenticate': `${options.prefix} realm="` + realm + '"',
+ },
+ });
+ }
+ else {
+ const regexp = new RegExp('^' + options.prefix + ' +(' + TOKEN_STRINGS + ') *$');
+ const match = regexp.exec(headerToken);
+ if (!match) {
+ // Invalid Request
+ c.res = new Response('Bad Request', {
+ status: 400,
+ headers: {
+ 'WWW-Authenticate': `${options.prefix} error="invalid_request"`,
+ },
+ });
+ }
+ else {
+ const equal = await (0, buffer_1.timingSafeEqual)(options.token, match[1], options.hashFunction);
+ if (!equal) {
+ // Invalid Token
+ c.res = new Response('Unauthorized', {
+ status: 401,
+ headers: {
+ 'WWW-Authenticate': `${options.prefix} error="invalid_token"`,
+ },
+ });
+ }
+ else {
+ // Authorize OK
+ await next();
+ return;
+ }
+ }
+ }
+ };
+};
+exports.bearerAuth = bearerAuth;
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/cache/index.d.ts b/cli/bench/testdata/npm/hono/dist/middleware/cache/index.d.ts
new file mode 100644
index 000000000..c0390c41e
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/cache/index.d.ts
@@ -0,0 +1,7 @@
+import type { Context } from '../../context';
+import type { Next } from '../../hono';
+export declare const cache: (options: {
+ cacheName: string;
+ wait?: boolean;
+ cacheControl?: string;
+}) => (c: Context, next: Next) => Promise<Response | undefined>;
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/cache/index.js b/cli/bench/testdata/npm/hono/dist/middleware/cache/index.js
new file mode 100644
index 000000000..890058af9
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/cache/index.js
@@ -0,0 +1,32 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.cache = void 0;
+const cache = (options) => {
+ if (options.wait === undefined) {
+ options.wait = false;
+ }
+ const addHeader = (response) => {
+ if (options.cacheControl)
+ response.headers.append('Cache-Control', options.cacheControl);
+ };
+ return async (c, next) => {
+ const key = c.req;
+ const cache = await caches.open(options.cacheName);
+ const response = await cache.match(key);
+ if (!response) {
+ await next();
+ addHeader(c.res);
+ const response = c.res.clone();
+ if (options.wait) {
+ await cache.put(key, response);
+ }
+ else {
+ c.executionCtx.waitUntil(cache.put(key, response));
+ }
+ }
+ else {
+ return response;
+ }
+ };
+};
+exports.cache = cache;
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/compress/index.d.ts b/cli/bench/testdata/npm/hono/dist/middleware/compress/index.d.ts
new file mode 100644
index 000000000..53f39ad86
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/compress/index.d.ts
@@ -0,0 +1,8 @@
+import type { Context } from '../../context';
+import type { Next } from '../../hono';
+declare type EncodingType = 'gzip' | 'deflate';
+interface CompressionOptions {
+ encoding?: EncodingType;
+}
+export declare const compress: (options?: CompressionOptions) => (ctx: Context, next: Next) => Promise<void>;
+export {};
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/compress/index.js b/cli/bench/testdata/npm/hono/dist/middleware/compress/index.js
new file mode 100644
index 000000000..fd605cf71
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/compress/index.js
@@ -0,0 +1,19 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.compress = void 0;
+const compress = (options) => {
+ return async (ctx, next) => {
+ await next();
+ const accepted = ctx.req.headers.get('Accept-Encoding');
+ const pattern = options?.encoding ?? /gzip|deflate/;
+ const match = accepted?.match(pattern);
+ if (!accepted || !match || !ctx.res.body) {
+ return;
+ }
+ const encoding = match[0];
+ const stream = new CompressionStream(encoding);
+ ctx.res = new Response(ctx.res.body.pipeThrough(stream), ctx.res.clone());
+ ctx.res.headers.set('Content-Encoding', encoding);
+ };
+};
+exports.compress = compress;
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/cors/index.d.ts b/cli/bench/testdata/npm/hono/dist/middleware/cors/index.d.ts
new file mode 100644
index 000000000..f353df808
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/cors/index.d.ts
@@ -0,0 +1,12 @@
+import type { Context } from '../../context';
+import type { Next } from '../../hono';
+declare type CORSOptions = {
+ origin: string;
+ allowMethods?: string[];
+ allowHeaders?: string[];
+ maxAge?: number;
+ credentials?: boolean;
+ exposeHeaders?: string[];
+};
+export declare const cors: (options?: CORSOptions) => (c: Context, next: Next) => Promise<void>;
+export {};
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/cors/index.js b/cli/bench/testdata/npm/hono/dist/middleware/cors/index.js
new file mode 100644
index 000000000..441de0928
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/cors/index.js
@@ -0,0 +1,61 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.cors = void 0;
+const cors = (options) => {
+ const defaults = {
+ origin: '*',
+ allowMethods: ['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH'],
+ allowHeaders: [],
+ exposeHeaders: [],
+ };
+ const opts = {
+ ...defaults,
+ ...options,
+ };
+ return async (c, next) => {
+ await next();
+ function set(key, value) {
+ c.res.headers.append(key, value);
+ }
+ set('Access-Control-Allow-Origin', opts.origin);
+ // Suppose the server sends a response with an Access-Control-Allow-Origin value with an explicit origin (rather than the "*" wildcard).
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
+ if (opts.origin !== '*') {
+ set('Vary', 'Origin');
+ }
+ if (opts.credentials) {
+ set('Access-Control-Allow-Credentials', 'true');
+ }
+ if (opts.exposeHeaders?.length) {
+ set('Access-Control-Expose-Headers', opts.exposeHeaders.join(','));
+ }
+ if (c.req.method === 'OPTIONS') {
+ // Preflight
+ if (opts.maxAge != null) {
+ set('Access-Control-Max-Age', opts.maxAge.toString());
+ }
+ if (opts.allowMethods?.length) {
+ set('Access-Control-Allow-Methods', opts.allowMethods.join(','));
+ }
+ let headers = opts.allowHeaders;
+ if (!headers?.length) {
+ const requestHeaders = c.req.headers.get('Access-Control-Request-Headers');
+ if (requestHeaders) {
+ headers = requestHeaders.split(/\s*,\s*/);
+ }
+ }
+ if (headers?.length) {
+ set('Access-Control-Allow-Headers', headers.join(','));
+ set('Vary', 'Access-Control-Request-Headers');
+ }
+ c.res.headers.delete('Content-Length');
+ c.res.headers.delete('Content-Type');
+ c.res = new Response(null, {
+ headers: c.res.headers,
+ status: 204,
+ statusText: c.res.statusText,
+ });
+ }
+ };
+};
+exports.cors = cors;
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/etag/index.d.ts b/cli/bench/testdata/npm/hono/dist/middleware/etag/index.d.ts
new file mode 100644
index 000000000..8cb945e14
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/etag/index.d.ts
@@ -0,0 +1,7 @@
+import type { Context } from '../../context';
+import type { Next } from '../../hono';
+declare type ETagOptions = {
+ weak: boolean;
+};
+export declare const etag: (options?: ETagOptions) => (c: Context, next: Next) => Promise<void>;
+export {};
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/etag/index.js b/cli/bench/testdata/npm/hono/dist/middleware/etag/index.js
new file mode 100644
index 000000000..60800edf1
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/etag/index.js
@@ -0,0 +1,27 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.etag = void 0;
+const crypto_1 = require("../../utils/crypto");
+const etag = (options = { weak: false }) => {
+ return async (c, next) => {
+ const ifNoneMatch = c.req.header('If-None-Match') || c.req.header('if-none-match');
+ await next();
+ const res = c.res;
+ const clone = res.clone();
+ const hash = await (0, crypto_1.sha1)(res.body || '');
+ const etag = options.weak ? `W/"${hash}"` : `"${hash}"`;
+ if (ifNoneMatch && ifNoneMatch === etag) {
+ await clone.blob(); // Force using body
+ c.res = new Response(null, {
+ status: 304,
+ statusText: 'Not Modified',
+ });
+ c.res.headers.delete('Content-Length');
+ }
+ else {
+ c.res = new Response(clone.body, clone);
+ c.res.headers.append('ETag', etag);
+ }
+ };
+};
+exports.etag = etag;
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/html/index.d.ts b/cli/bench/testdata/npm/hono/dist/middleware/html/index.d.ts
new file mode 100644
index 000000000..976a7d1db
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/html/index.d.ts
@@ -0,0 +1,3 @@
+import type { HtmlEscapedString } from '../../utils/html';
+export declare const raw: (value: any) => HtmlEscapedString;
+export declare const html: (strings: TemplateStringsArray, ...values: any[]) => HtmlEscapedString;
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/html/index.js b/cli/bench/testdata/npm/hono/dist/middleware/html/index.js
new file mode 100644
index 000000000..598621bf0
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/html/index.js
@@ -0,0 +1,36 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.html = exports.raw = void 0;
+const html_1 = require("../../utils/html");
+const raw = (value) => {
+ const escapedString = new String(value);
+ escapedString.isEscaped = true;
+ return escapedString;
+};
+exports.raw = raw;
+const html = (strings, ...values) => {
+ const buffer = [''];
+ for (let i = 0, len = strings.length - 1; i < len; i++) {
+ buffer[0] += strings[i];
+ const children = values[i] instanceof Array ? values[i].flat(Infinity) : [values[i]];
+ for (let i = 0, len = children.length; i < len; i++) {
+ const child = children[i];
+ if (typeof child === 'string') {
+ (0, html_1.escapeToBuffer)(child, buffer);
+ }
+ else if (typeof child === 'boolean' || child === null || child === undefined) {
+ continue;
+ }
+ else if ((typeof child === 'object' && child.isEscaped) ||
+ typeof child === 'number') {
+ buffer[0] += child;
+ }
+ else {
+ (0, html_1.escapeToBuffer)(child.toString(), buffer);
+ }
+ }
+ }
+ buffer[0] += strings[strings.length - 1];
+ return (0, exports.raw)(buffer[0]);
+};
+exports.html = html;
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/jsx/index.d.ts b/cli/bench/testdata/npm/hono/dist/middleware/jsx/index.d.ts
new file mode 100644
index 000000000..3222b2b36
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/jsx/index.d.ts
@@ -0,0 +1,26 @@
+import type { StringBuffer, HtmlEscaped, HtmlEscapedString } from '../../utils/html';
+declare global {
+ namespace jsx.JSX {
+ interface IntrinsicElements {
+ [tagName: string]: Record<string, any>;
+ }
+ }
+}
+declare type Child = string | number | JSXNode | Child[];
+export declare class JSXNode implements HtmlEscaped {
+ tag: string | Function;
+ props: Record<string, any>;
+ children: Child[];
+ isEscaped: true;
+ constructor(tag: string | Function, props: Record<string, any>, children: Child[]);
+ toString(): string;
+ toStringToBuffer(buffer: StringBuffer): void;
+}
+export { jsxFn as jsx };
+declare const jsxFn: (tag: string | Function, props: Record<string, any>, ...children: (string | HtmlEscapedString)[]) => JSXNode;
+declare type FC<T = Record<string, any>> = (props: T) => HtmlEscapedString;
+export declare const memo: <T>(component: FC<T>, propsAreEqual?: (prevProps: Readonly<T>, nextProps: Readonly<T>) => boolean) => FC<T>;
+export declare const Fragment: (props: {
+ key?: string;
+ children?: any;
+}) => JSXNode;
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/jsx/index.js b/cli/bench/testdata/npm/hono/dist/middleware/jsx/index.js
new file mode 100644
index 000000000..f72a7ecb9
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/jsx/index.js
@@ -0,0 +1,193 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.Fragment = exports.memo = exports.jsx = exports.JSXNode = void 0;
+const html_1 = require("../../utils/html");
+const emptyTags = [
+ 'area',
+ 'base',
+ 'br',
+ 'col',
+ 'embed',
+ 'hr',
+ 'img',
+ 'input',
+ 'keygen',
+ 'link',
+ 'meta',
+ 'param',
+ 'source',
+ 'track',
+ 'wbr',
+];
+const booleanAttributes = [
+ 'allowfullscreen',
+ 'async',
+ 'autofocus',
+ 'autoplay',
+ 'checked',
+ 'controls',
+ 'default',
+ 'defer',
+ 'disabled',
+ 'formnovalidate',
+ 'hidden',
+ 'inert',
+ 'ismap',
+ 'itemscope',
+ 'loop',
+ 'multiple',
+ 'muted',
+ 'nomodule',
+ 'novalidate',
+ 'open',
+ 'playsinline',
+ 'readonly',
+ 'required',
+ 'reversed',
+ 'selected',
+];
+const childrenToStringToBuffer = (children, buffer) => {
+ for (let i = 0, len = children.length; i < len; i++) {
+ const child = children[i];
+ if (typeof child === 'string') {
+ (0, html_1.escapeToBuffer)(child, buffer);
+ }
+ else if (typeof child === 'boolean' || child === null || child === undefined) {
+ continue;
+ }
+ else if (child instanceof JSXNode) {
+ child.toStringToBuffer(buffer);
+ }
+ else if (typeof child === 'number' || child.isEscaped) {
+ buffer[0] += child;
+ }
+ else {
+ // `child` type is `Child[]`, so stringify recursively
+ childrenToStringToBuffer(child, buffer);
+ }
+ }
+};
+class JSXNode {
+ constructor(tag, props, children) {
+ this.isEscaped = true;
+ this.tag = tag;
+ this.props = props;
+ this.children = children;
+ }
+ toString() {
+ const buffer = [''];
+ this.toStringToBuffer(buffer);
+ return buffer[0];
+ }
+ toStringToBuffer(buffer) {
+ const tag = this.tag;
+ const props = this.props;
+ let { children } = this;
+ buffer[0] += `<${tag}`;
+ const propsKeys = Object.keys(props || {});
+ for (let i = 0, len = propsKeys.length; i < len; i++) {
+ const v = props[propsKeys[i]];
+ if (typeof v === 'string') {
+ buffer[0] += ` ${propsKeys[i]}="`;
+ (0, html_1.escapeToBuffer)(v, buffer);
+ buffer[0] += '"';
+ }
+ else if (typeof v === 'number') {
+ buffer[0] += ` ${propsKeys[i]}="${v}"`;
+ }
+ else if (v === null || v === undefined) {
+ // Do nothing
+ }
+ else if (typeof v === 'boolean' && booleanAttributes.includes(propsKeys[i])) {
+ if (v) {
+ buffer[0] += ` ${propsKeys[i]}=""`;
+ }
+ }
+ else if (propsKeys[i] === 'dangerouslySetInnerHTML') {
+ if (children.length > 0) {
+ throw 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.';
+ }
+ const escapedString = new String(v.__html);
+ escapedString.isEscaped = true;
+ children = [escapedString];
+ }
+ else {
+ buffer[0] += ` ${propsKeys[i]}="`;
+ (0, html_1.escapeToBuffer)(v.toString(), buffer);
+ buffer[0] += '"';
+ }
+ }
+ if (emptyTags.includes(tag)) {
+ buffer[0] += '/>';
+ return;
+ }
+ buffer[0] += '>';
+ childrenToStringToBuffer(children, buffer);
+ buffer[0] += `</${tag}>`;
+ }
+}
+exports.JSXNode = JSXNode;
+class JSXFunctionNode extends JSXNode {
+ toStringToBuffer(buffer) {
+ const { children } = this;
+ const res = this.tag.call(null, {
+ ...this.props,
+ children: children.length <= 1 ? children[0] : children,
+ });
+ if (res instanceof JSXNode) {
+ res.toStringToBuffer(buffer);
+ }
+ else if (typeof res === 'number' || res.isEscaped) {
+ buffer[0] += res;
+ }
+ else {
+ (0, html_1.escapeToBuffer)(res, buffer);
+ }
+ }
+}
+class JSXFragmentNode extends JSXNode {
+ toStringToBuffer(buffer) {
+ childrenToStringToBuffer(this.children, buffer);
+ }
+}
+const jsxFn = (tag, props, ...children) => {
+ if (typeof tag === 'function') {
+ return new JSXFunctionNode(tag, props, children);
+ }
+ else {
+ return new JSXNode(tag, props, children);
+ }
+};
+exports.jsx = jsxFn;
+const shallowEqual = (a, b) => {
+ if (a === b) {
+ return true;
+ }
+ const aKeys = Object.keys(a);
+ const bKeys = Object.keys(b);
+ if (aKeys.length !== bKeys.length) {
+ return false;
+ }
+ for (let i = 0, len = aKeys.length; i < len; i++) {
+ if (a[aKeys[i]] !== b[aKeys[i]]) {
+ return false;
+ }
+ }
+ return true;
+};
+const memo = (component, propsAreEqual = shallowEqual) => {
+ let computed = undefined;
+ let prevProps = undefined;
+ return ((props) => {
+ if (prevProps && !propsAreEqual(prevProps, props)) {
+ computed = undefined;
+ }
+ prevProps = props;
+ return (computed || (computed = component(props)));
+ });
+};
+exports.memo = memo;
+const Fragment = (props) => {
+ return new JSXFragmentNode('', {}, props.children || []);
+};
+exports.Fragment = Fragment;
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/jsx/jsx-dev-runtime.d.ts b/cli/bench/testdata/npm/hono/dist/middleware/jsx/jsx-dev-runtime.d.ts
new file mode 100644
index 000000000..d76fc7124
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/jsx/jsx-dev-runtime.d.ts
@@ -0,0 +1,2 @@
+import type { JSXNode } from '.';
+export declare function jsxDEV(tag: string | Function, props: Record<string, any>): JSXNode;
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/jsx/jsx-dev-runtime.js b/cli/bench/testdata/npm/hono/dist/middleware/jsx/jsx-dev-runtime.js
new file mode 100644
index 000000000..6aa4bfa00
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/jsx/jsx-dev-runtime.js
@@ -0,0 +1,10 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.jsxDEV = void 0;
+const _1 = require(".");
+function jsxDEV(tag, props) {
+ const children = props.children ?? [];
+ delete props['children'];
+ return (0, _1.jsx)(tag, props, children);
+}
+exports.jsxDEV = jsxDEV;
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/jsx/jsx-runtime.d.ts b/cli/bench/testdata/npm/hono/dist/middleware/jsx/jsx-runtime.d.ts
new file mode 100644
index 000000000..4d505cdf8
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/jsx/jsx-runtime.d.ts
@@ -0,0 +1,2 @@
+export { jsxDEV as jsx } from './jsx-dev-runtime';
+export { jsxDEV as jsxs } from './jsx-dev-runtime';
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/jsx/jsx-runtime.js b/cli/bench/testdata/npm/hono/dist/middleware/jsx/jsx-runtime.js
new file mode 100644
index 000000000..ee8c3fe72
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/jsx/jsx-runtime.js
@@ -0,0 +1,7 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.jsxs = exports.jsx = void 0;
+var jsx_dev_runtime_1 = require("./jsx-dev-runtime");
+Object.defineProperty(exports, "jsx", { enumerable: true, get: function () { return jsx_dev_runtime_1.jsxDEV; } });
+var jsx_dev_runtime_2 = require("./jsx-dev-runtime");
+Object.defineProperty(exports, "jsxs", { enumerable: true, get: function () { return jsx_dev_runtime_2.jsxDEV; } });
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/jwt/index.d.ts b/cli/bench/testdata/npm/hono/dist/middleware/jwt/index.d.ts
new file mode 100644
index 000000000..5b13b4816
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/jwt/index.d.ts
@@ -0,0 +1,7 @@
+import type { Context } from '../../context';
+import type { Next } from '../../hono';
+export declare const jwt: (options: {
+ secret: string;
+ cookie?: string;
+ alg?: string;
+}) => (ctx: Context, next: Next) => Promise<void>;
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/jwt/index.js b/cli/bench/testdata/npm/hono/dist/middleware/jwt/index.js
new file mode 100644
index 000000000..6f486560b
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/jwt/index.js
@@ -0,0 +1,63 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.jwt = void 0;
+const jwt_1 = require("../../utils/jwt");
+const jwt = (options) => {
+ if (!options) {
+ throw new Error('JWT auth middleware requires options for "secret');
+ }
+ if (!crypto.subtle || !crypto.subtle.importKey) {
+ throw new Error('`crypto.subtle.importKey` is undefined. JWT auth middleware requires it.');
+ }
+ return async (ctx, next) => {
+ const credentials = ctx.req.headers.get('Authorization');
+ let token;
+ if (credentials) {
+ const parts = credentials.split(/\s+/);
+ if (parts.length !== 2) {
+ ctx.res = new Response('Unauthorized', {
+ status: 401,
+ headers: {
+ 'WWW-Authenticate': `Bearer realm="${ctx.req.url}",error="invalid_request",error_description="invalid credentials structure"`,
+ },
+ });
+ return;
+ }
+ else {
+ token = parts[1];
+ }
+ }
+ else if (options.cookie) {
+ token = ctx.req.cookie(options.cookie);
+ }
+ if (!token) {
+ ctx.res = new Response('Unauthorized', {
+ status: 401,
+ headers: {
+ 'WWW-Authenticate': `Bearer realm="${ctx.req.url}",error="invalid_request",error_description="no authorization included in request"`,
+ },
+ });
+ return;
+ }
+ let authorized = false;
+ let msg = '';
+ try {
+ authorized = await jwt_1.Jwt.verify(token, options.secret, options.alg);
+ }
+ catch (e) {
+ msg = `${e}`;
+ }
+ if (!authorized) {
+ ctx.res = new Response('Unauthorized', {
+ status: 401,
+ statusText: msg,
+ headers: {
+ 'WWW-Authenticate': `Bearer realm="${ctx.req.url}",error="invalid_token",error_description="token verification failure"`,
+ },
+ });
+ return;
+ }
+ await next();
+ };
+};
+exports.jwt = jwt;
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/logger/index.d.ts b/cli/bench/testdata/npm/hono/dist/middleware/logger/index.d.ts
new file mode 100644
index 000000000..232305d2f
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/logger/index.d.ts
@@ -0,0 +1,5 @@
+import type { Context } from '../../context';
+import type { Next } from '../../hono';
+declare type PrintFunc = (str: string, ...rest: string[]) => void;
+export declare const logger: (fn?: PrintFunc) => (c: Context, next: Next) => Promise<void>;
+export {};
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/logger/index.js b/cli/bench/testdata/npm/hono/dist/middleware/logger/index.js
new file mode 100644
index 000000000..44cf994d0
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/logger/index.js
@@ -0,0 +1,49 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.logger = void 0;
+const url_1 = require("../../utils/url");
+var LogPrefix;
+(function (LogPrefix) {
+ LogPrefix["Outgoing"] = "-->";
+ LogPrefix["Incoming"] = "<--";
+ LogPrefix["Error"] = "xxx";
+})(LogPrefix || (LogPrefix = {}));
+const humanize = (times) => {
+ const [delimiter, separator] = [',', '.'];
+ const orderTimes = times.map((v) => v.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1' + delimiter));
+ return orderTimes.join(separator);
+};
+const time = (start) => {
+ const delta = Date.now() - start;
+ return humanize([delta < 1000 ? delta + 'ms' : Math.round(delta / 1000) + 's']);
+};
+const colorStatus = (status) => {
+ const out = {
+ 7: `\x1b[35m${status}\x1b[0m`,
+ 5: `\x1b[31m${status}\x1b[0m`,
+ 4: `\x1b[33m${status}\x1b[0m`,
+ 3: `\x1b[36m${status}\x1b[0m`,
+ 2: `\x1b[32m${status}\x1b[0m`,
+ 1: `\x1b[32m${status}\x1b[0m`,
+ 0: `\x1b[33m${status}\x1b[0m`,
+ };
+ const calculateStatus = (status / 100) | 0;
+ return out[calculateStatus];
+};
+function log(fn, prefix, method, path, status = 0, elapsed) {
+ const out = prefix === LogPrefix.Incoming
+ ? ` ${prefix} ${method} ${path}`
+ : ` ${prefix} ${method} ${path} ${colorStatus(status)} ${elapsed}`;
+ fn(out);
+}
+const logger = (fn = console.log) => {
+ return async (c, next) => {
+ const { method } = c.req;
+ const path = (0, url_1.getPathFromURL)(c.req.url);
+ log(fn, LogPrefix.Incoming, method, path);
+ const start = Date.now();
+ await next();
+ log(fn, LogPrefix.Outgoing, method, path, c.res.status, time(start));
+ };
+};
+exports.logger = logger;
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/powered-by/index.d.ts b/cli/bench/testdata/npm/hono/dist/middleware/powered-by/index.d.ts
new file mode 100644
index 000000000..eb7995b80
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/powered-by/index.d.ts
@@ -0,0 +1,3 @@
+import type { Context } from '../../context';
+import type { Next } from '../../hono';
+export declare const poweredBy: () => (c: Context, next: Next) => Promise<void>;
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/powered-by/index.js b/cli/bench/testdata/npm/hono/dist/middleware/powered-by/index.js
new file mode 100644
index 000000000..c1f73300b
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/powered-by/index.js
@@ -0,0 +1,10 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.poweredBy = void 0;
+const poweredBy = () => {
+ return async (c, next) => {
+ await next();
+ c.res.headers.append('X-Powered-By', 'Hono');
+ };
+};
+exports.poweredBy = poweredBy;
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/pretty-json/index.d.ts b/cli/bench/testdata/npm/hono/dist/middleware/pretty-json/index.d.ts
new file mode 100644
index 000000000..94736847e
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/pretty-json/index.d.ts
@@ -0,0 +1,7 @@
+import type { Context } from '../../context';
+import type { Next } from '../../hono';
+declare type prettyOptions = {
+ space: number;
+};
+export declare const prettyJSON: (options?: prettyOptions) => (c: Context, next: Next) => Promise<void>;
+export {};
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/pretty-json/index.js b/cli/bench/testdata/npm/hono/dist/middleware/pretty-json/index.js
new file mode 100644
index 000000000..08af0fb10
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/pretty-json/index.js
@@ -0,0 +1,11 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.prettyJSON = void 0;
+const prettyJSON = (options = { space: 2 }) => {
+ return async (c, next) => {
+ const pretty = c.req.query('pretty') || c.req.query('pretty') === '' ? true : false;
+ c.pretty(pretty, options.space);
+ await next();
+ };
+};
+exports.prettyJSON = prettyJSON;
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/serve-static/bun.d.ts b/cli/bench/testdata/npm/hono/dist/middleware/serve-static/bun.d.ts
new file mode 100644
index 000000000..be4515aff
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/serve-static/bun.d.ts
@@ -0,0 +1,7 @@
+import type { Context } from '../../context';
+import type { Next } from '../../hono';
+export declare type ServeStaticOptions = {
+ root?: string;
+ path?: string;
+};
+export declare const serveStatic: (options?: ServeStaticOptions) => (c: Context, next: Next) => Promise<Response | undefined>;
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/serve-static/bun.js b/cli/bench/testdata/npm/hono/dist/middleware/serve-static/bun.js
new file mode 100644
index 000000000..d29a7d936
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/serve-static/bun.js
@@ -0,0 +1,38 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.serveStatic = void 0;
+const filepath_1 = require("../../utils/filepath");
+const mime_1 = require("../../utils/mime");
+// @ts-ignore
+const { file } = Bun;
+const DEFAULT_DOCUMENT = 'index.html';
+const serveStatic = (options = { root: '' }) => {
+ return async (c, next) => {
+ // Do nothing if Response is already set
+ if (c.res && c.finalized) {
+ await next();
+ }
+ const url = new URL(c.req.url);
+ let path = (0, filepath_1.getFilePath)({
+ filename: options.path ?? url.pathname,
+ root: options.root,
+ defaultDocument: DEFAULT_DOCUMENT,
+ });
+ path = `./${path}`;
+ const content = file(path);
+ if (content) {
+ const mimeType = (0, mime_1.getMimeType)(path);
+ if (mimeType) {
+ c.header('Content-Type', mimeType);
+ }
+ // Return Response object
+ return c.body(content);
+ }
+ else {
+ console.warn(`Static file: ${path} is not found`);
+ await next();
+ }
+ return;
+ };
+};
+exports.serveStatic = serveStatic;
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/serve-static/index.d.ts b/cli/bench/testdata/npm/hono/dist/middleware/serve-static/index.d.ts
new file mode 100644
index 000000000..21bcb4dc3
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/serve-static/index.d.ts
@@ -0,0 +1 @@
+export { serveStatic } from './serve-static';
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/serve-static/index.js b/cli/bench/testdata/npm/hono/dist/middleware/serve-static/index.js
new file mode 100644
index 000000000..3748e9530
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/serve-static/index.js
@@ -0,0 +1,5 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.serveStatic = void 0;
+var serve_static_1 = require("./serve-static");
+Object.defineProperty(exports, "serveStatic", { enumerable: true, get: function () { return serve_static_1.serveStatic; } });
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/serve-static/module.d.mts b/cli/bench/testdata/npm/hono/dist/middleware/serve-static/module.d.mts
new file mode 100644
index 000000000..36cd766f3
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/serve-static/module.d.mts
@@ -0,0 +1,5 @@
+import type { ServeStaticOptions } from './serve-static';
+declare const module: (options?: ServeStaticOptions) => import("../../hono").Handler<string, {
+ [x: string]: any;
+}>;
+export { module as serveStatic };
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/serve-static/module.mjs b/cli/bench/testdata/npm/hono/dist/middleware/serve-static/module.mjs
new file mode 100644
index 000000000..968fd4433
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/serve-static/module.mjs
@@ -0,0 +1,13 @@
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore
+// For ES module mode
+import manifest from '__STATIC_CONTENT_MANIFEST';
+import { serveStatic } from './serve-static';
+const module = (options = { root: '' }) => {
+ return serveStatic({
+ root: options.root,
+ path: options.path,
+ manifest: options.manifest ? options.manifest : manifest,
+ });
+};
+export { module as serveStatic };
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/serve-static/serve-static.d.ts b/cli/bench/testdata/npm/hono/dist/middleware/serve-static/serve-static.d.ts
new file mode 100644
index 000000000..5ff60c4ca
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/serve-static/serve-static.d.ts
@@ -0,0 +1,9 @@
+/// <reference types="@cloudflare/workers-types" />
+import type { Handler } from '../../hono';
+export declare type ServeStaticOptions = {
+ root?: string;
+ path?: string;
+ manifest?: object | string;
+ namespace?: KVNamespace;
+};
+export declare const serveStatic: (options?: ServeStaticOptions) => Handler;
diff --git a/cli/bench/testdata/npm/hono/dist/middleware/serve-static/serve-static.js b/cli/bench/testdata/npm/hono/dist/middleware/serve-static/serve-static.js
new file mode 100644
index 000000000..a647b7015
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/middleware/serve-static/serve-static.js
@@ -0,0 +1,40 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.serveStatic = void 0;
+const cloudflare_1 = require("../../utils/cloudflare");
+const filepath_1 = require("../../utils/filepath");
+const mime_1 = require("../../utils/mime");
+const DEFAULT_DOCUMENT = 'index.html';
+// This middleware is available only on Cloudflare Workers.
+const serveStatic = (options = { root: '' }) => {
+ return async (c, next) => {
+ // Do nothing if Response is already set
+ if (c.res && c.finalized) {
+ await next();
+ }
+ const url = new URL(c.req.url);
+ const path = (0, filepath_1.getFilePath)({
+ filename: options.path ?? url.pathname,
+ root: options.root,
+ defaultDocument: DEFAULT_DOCUMENT,
+ });
+ const content = await (0, cloudflare_1.getContentFromKVAsset)(path, {
+ manifest: options.manifest,
+ namespace: options.namespace ? options.namespace : c.env ? c.env.__STATIC_CONTENT : undefined,
+ });
+ if (content) {
+ const mimeType = (0, mime_1.getMimeType)(path);
+ if (mimeType) {
+ c.header('Content-Type', mimeType);
+ }
+ // Return Response object
+ return c.body(content);
+ }
+ else {
+ console.warn(`Static file: ${path} is not found`);
+ await next();
+ }
+ return;
+ };
+};
+exports.serveStatic = serveStatic;
diff --git a/cli/bench/testdata/npm/hono/dist/request.d.ts b/cli/bench/testdata/npm/hono/dist/request.d.ts
new file mode 100644
index 000000000..aebc0b855
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/request.d.ts
@@ -0,0 +1,32 @@
+import type { Body } from './utils/body';
+import type { Cookie } from './utils/cookie';
+declare global {
+ interface Request<ParamKeyType extends string = string> {
+ param: {
+ (key: ParamKeyType): string;
+ (): Record<ParamKeyType, string>;
+ };
+ paramData?: Record<ParamKeyType, string>;
+ query: {
+ (key: string): string;
+ (): Record<string, string>;
+ };
+ queries: {
+ (key: string): string[];
+ (): Record<string, string[]>;
+ };
+ header: {
+ (name: string): string;
+ (): Record<string, string>;
+ };
+ cookie: {
+ (name: string): string;
+ (): Cookie;
+ };
+ parsedBody?: Promise<Body>;
+ parseBody: {
+ (): Promise<Body>;
+ };
+ }
+}
+export declare function extendRequestPrototype(): void;
diff --git a/cli/bench/testdata/npm/hono/dist/request.js b/cli/bench/testdata/npm/hono/dist/request.js
new file mode 100644
index 000000000..fb900d743
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/request.js
@@ -0,0 +1,78 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.extendRequestPrototype = void 0;
+const body_1 = require("./utils/body");
+const cookie_1 = require("./utils/cookie");
+function extendRequestPrototype() {
+ if (!!Request.prototype.param) {
+ // already extended
+ return;
+ }
+ Request.prototype.param = function (key) {
+ if (this.paramData) {
+ if (key) {
+ return this.paramData[key];
+ }
+ else {
+ return this.paramData;
+ }
+ }
+ return null;
+ };
+ Request.prototype.header = function (name) {
+ if (name) {
+ return this.headers.get(name);
+ }
+ else {
+ const result = {};
+ for (const [key, value] of this.headers) {
+ result[key] = value;
+ }
+ return result;
+ }
+ };
+ Request.prototype.query = function (key) {
+ const url = new URL(this.url);
+ if (key) {
+ return url.searchParams.get(key);
+ }
+ else {
+ const result = {};
+ for (const key of url.searchParams.keys()) {
+ result[key] = url.searchParams.get(key) || '';
+ }
+ return result;
+ }
+ };
+ Request.prototype.queries = function (key) {
+ const url = new URL(this.url);
+ if (key) {
+ return url.searchParams.getAll(key);
+ }
+ else {
+ const result = {};
+ for (const key of url.searchParams.keys()) {
+ result[key] = url.searchParams.getAll(key);
+ }
+ return result;
+ }
+ };
+ Request.prototype.cookie = function (key) {
+ const cookie = this.headers.get('Cookie') || '';
+ const obj = (0, cookie_1.parse)(cookie);
+ if (key) {
+ const value = obj[key];
+ return value;
+ }
+ else {
+ return obj;
+ }
+ };
+ Request.prototype.parseBody = function () {
+ if (!this.parsedBody) {
+ this.parsedBody = (0, body_1.parseBody)(this);
+ }
+ return this.parsedBody;
+ };
+}
+exports.extendRequestPrototype = extendRequestPrototype;
diff --git a/cli/bench/testdata/npm/hono/dist/router.d.ts b/cli/bench/testdata/npm/hono/dist/router.d.ts
new file mode 100644
index 000000000..753bbbc68
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/router.d.ts
@@ -0,0 +1,10 @@
+export declare const METHOD_NAME_ALL: "ALL";
+export declare const METHOD_NAME_ALL_LOWERCASE: "all";
+export interface Router<T> {
+ add(method: string, path: string, handler: T): void;
+ match(method: string, path: string): Result<T> | null;
+}
+export interface Result<T> {
+ handlers: T[];
+ params: Record<string, string>;
+}
diff --git a/cli/bench/testdata/npm/hono/dist/router.js b/cli/bench/testdata/npm/hono/dist/router.js
new file mode 100644
index 000000000..c861fe9ce
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/router.js
@@ -0,0 +1,5 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.METHOD_NAME_ALL_LOWERCASE = exports.METHOD_NAME_ALL = void 0;
+exports.METHOD_NAME_ALL = 'ALL';
+exports.METHOD_NAME_ALL_LOWERCASE = 'all';
diff --git a/cli/bench/testdata/npm/hono/dist/router/reg-exp-router/index.d.ts b/cli/bench/testdata/npm/hono/dist/router/reg-exp-router/index.d.ts
new file mode 100644
index 000000000..2d0f54ba3
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/router/reg-exp-router/index.d.ts
@@ -0,0 +1 @@
+export { RegExpRouter } from './router';
diff --git a/cli/bench/testdata/npm/hono/dist/router/reg-exp-router/index.js b/cli/bench/testdata/npm/hono/dist/router/reg-exp-router/index.js
new file mode 100644
index 000000000..782e988d9
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/router/reg-exp-router/index.js
@@ -0,0 +1,5 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.RegExpRouter = void 0;
+var router_1 = require("./router");
+Object.defineProperty(exports, "RegExpRouter", { enumerable: true, get: function () { return router_1.RegExpRouter; } });
diff --git a/cli/bench/testdata/npm/hono/dist/router/reg-exp-router/node.d.ts b/cli/bench/testdata/npm/hono/dist/router/reg-exp-router/node.d.ts
new file mode 100644
index 000000000..ee52660f8
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/router/reg-exp-router/node.d.ts
@@ -0,0 +1,14 @@
+export declare type ParamMap = Array<[string, number]>;
+export interface Context {
+ varIndex: number;
+}
+export declare class Node {
+ index?: number;
+ varIndex?: number;
+ children: Record<string, Node>;
+ reverse: boolean;
+ constructor({ reverse }?: Partial<Node>);
+ newChildNode(): Node;
+ insert(tokens: readonly string[], index: number, paramMap: ParamMap, context: Context): void;
+ buildRegExpStr(): string;
+}
diff --git a/cli/bench/testdata/npm/hono/dist/router/reg-exp-router/node.js b/cli/bench/testdata/npm/hono/dist/router/reg-exp-router/node.js
new file mode 100644
index 000000000..c53a23c7b
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/router/reg-exp-router/node.js
@@ -0,0 +1,100 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.Node = void 0;
+const LABEL_REG_EXP_STR = '[^/]+';
+const ONLY_WILDCARD_REG_EXP_STR = '.*';
+const TAIL_WILDCARD_REG_EXP_STR = '(?:|/.*)';
+/**
+ * Sort order:
+ * 1. literal
+ * 2. special pattern (e.g. :label{[0-9]+})
+ * 3. common label pattern (e.g. :label)
+ * 4. wildcard
+ */
+function compareKey(a, b) {
+ if (a.length === 1) {
+ return b.length === 1 ? (a < b ? -1 : 1) : -1;
+ }
+ if (b.length === 1) {
+ return 1;
+ }
+ // wildcard
+ if (a === ONLY_WILDCARD_REG_EXP_STR || a === TAIL_WILDCARD_REG_EXP_STR) {
+ return 1;
+ }
+ else if (b === ONLY_WILDCARD_REG_EXP_STR || b === TAIL_WILDCARD_REG_EXP_STR) {
+ return -1;
+ }
+ // label
+ if (a === LABEL_REG_EXP_STR) {
+ return 1;
+ }
+ else if (b === LABEL_REG_EXP_STR) {
+ return -1;
+ }
+ return a.length === b.length ? (a < b ? -1 : 1) : b.length - a.length;
+}
+class Node {
+ constructor({ reverse } = { reverse: false }) {
+ this.children = {};
+ this.reverse = reverse;
+ }
+ newChildNode() {
+ return new Node({ reverse: this.reverse });
+ }
+ insert(tokens, index, paramMap, context) {
+ var _a;
+ if (tokens.length === 0) {
+ this.index = index;
+ return;
+ }
+ const [token, ...restTokens] = tokens;
+ const pattern = token === '*'
+ ? restTokens.length === 0
+ ? ['', '', ONLY_WILDCARD_REG_EXP_STR] // '*' matches to all the trailing paths
+ : ['', '', LABEL_REG_EXP_STR]
+ : token === '/*'
+ ? ['', '', TAIL_WILDCARD_REG_EXP_STR] // '/path/to/*' is /\/path\/to(?:|/.*)$
+ : token.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
+ let node;
+ if (pattern) {
+ const name = pattern[1];
+ const regexpStr = pattern[2] || LABEL_REG_EXP_STR;
+ node = this.children[regexpStr];
+ if (!node) {
+ node = this.children[regexpStr] = this.newChildNode();
+ if (name !== '') {
+ node.varIndex = context.varIndex++;
+ }
+ }
+ if (name !== '') {
+ paramMap.push([name, node.varIndex]);
+ }
+ }
+ else {
+ node = (_a = this.children)[token] || (_a[token] = this.newChildNode());
+ }
+ node.insert(restTokens, index, paramMap, context);
+ }
+ buildRegExpStr() {
+ let childKeys = Object.keys(this.children).sort(compareKey);
+ if (this.reverse) {
+ childKeys = childKeys.reverse();
+ }
+ const strList = childKeys.map((k) => {
+ const c = this.children[k];
+ return (typeof c.varIndex === 'number' ? `(${k})@${c.varIndex}` : k) + c.buildRegExpStr();
+ });
+ if (typeof this.index === 'number') {
+ strList.unshift(`#${this.index}`);
+ }
+ if (strList.length === 0) {
+ return '';
+ }
+ if (strList.length === 1) {
+ return strList[0];
+ }
+ return '(?:' + strList.join('|') + ')';
+ }
+}
+exports.Node = Node;
diff --git a/cli/bench/testdata/npm/hono/dist/router/reg-exp-router/router.d.ts b/cli/bench/testdata/npm/hono/dist/router/reg-exp-router/router.d.ts
new file mode 100644
index 000000000..6d06b30bd
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/router/reg-exp-router/router.d.ts
@@ -0,0 +1,34 @@
+import type { Router, Result } from '../../router';
+interface Hint {
+ components: string[];
+ regExpComponents: Array<true | string>;
+ componentsLength: number;
+ endWithWildcard: boolean;
+ paramIndexList: number[];
+ maybeHandler: boolean;
+ namedParams: [number, string, string][];
+}
+interface HandlerWithSortIndex<T> {
+ handler: T;
+ index: number;
+}
+interface Route<T> {
+ method: string;
+ path: string;
+ hint: Hint;
+ handlers: HandlerWithSortIndex<T>[];
+ middleware: HandlerWithSortIndex<T>[];
+ paramAliasMap: Record<string, string[]>;
+}
+export declare class RegExpRouter<T> implements Router<T> {
+ routeData?: {
+ index: number;
+ routes: Route<T>[];
+ methods: Set<string>;
+ };
+ add(method: string, path: string, handler: T): void;
+ match(method: string, path: string): Result<T> | null;
+ private buildAllMatchers;
+ private buildMatcher;
+}
+export {};
diff --git a/cli/bench/testdata/npm/hono/dist/router/reg-exp-router/router.js b/cli/bench/testdata/npm/hono/dist/router/reg-exp-router/router.js
new file mode 100644
index 000000000..782bd8ba4
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/router/reg-exp-router/router.js
@@ -0,0 +1,360 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.RegExpRouter = void 0;
+const router_1 = require("../../router");
+const trie_1 = require("./trie");
+const emptyParam = {};
+const nullMatcher = [/^$/, []];
+function initHint(path) {
+ const components = path.match(/\/(?::\w+{[^}]+}|[^\/]*)/g) || [];
+ let componentsLength = components.length;
+ const paramIndexList = [];
+ const regExpComponents = [];
+ const namedParams = [];
+ for (let i = 0, len = components.length; i < len; i++) {
+ if (i === len - 1 && components[i] === '/*') {
+ componentsLength--;
+ break;
+ }
+ const m = components[i].match(/^\/:(\w+)({[^}]+})?/);
+ if (m) {
+ namedParams.push([i, m[1], m[2] || '[^/]+']);
+ regExpComponents[i] = m[2] || true;
+ }
+ else if (components[i] === '/*') {
+ regExpComponents[i] = true;
+ }
+ else {
+ regExpComponents[i] = components[i];
+ }
+ if (/\/(?::|\*)/.test(components[i])) {
+ paramIndexList.push(i);
+ }
+ }
+ return {
+ components,
+ regExpComponents,
+ componentsLength,
+ endWithWildcard: path.endsWith('*'),
+ paramIndexList,
+ namedParams,
+ maybeHandler: true,
+ };
+}
+function compareRoute(a, b) {
+ if (a.path === '*') {
+ return 1;
+ }
+ let i = 0;
+ const len = a.hint.regExpComponents.length;
+ for (; i < len; i++) {
+ if (a.hint.regExpComponents[i] !== b.hint.regExpComponents[i]) {
+ if (a.hint.regExpComponents[i] === true) {
+ break;
+ }
+ return 0;
+ }
+ }
+ // may be ambiguous
+ for (; i < len; i++) {
+ if (a.hint.regExpComponents[i] !== true &&
+ a.hint.regExpComponents[i] !== b.hint.regExpComponents[i]) {
+ return 2;
+ }
+ }
+ return i === b.hint.regExpComponents.length || a.hint.endWithWildcard ? 1 : 0;
+}
+function compareHandler(a, b) {
+ return a.index - b.index;
+}
+function getSortedHandlers(handlers) {
+ return [...handlers].sort(compareHandler).map((h) => h.handler);
+}
+function buildMatcherFromPreprocessedRoutes(routes, hasAmbiguous = false) {
+ const trie = new trie_1.Trie({ reverse: hasAmbiguous });
+ const handlers = [];
+ if (routes.length === 0) {
+ return nullMatcher;
+ }
+ for (let i = 0, len = routes.length; i < len; i++) {
+ const paramMap = trie.insert(routes[i].path, i);
+ handlers[i] = [
+ [...routes[i].middleware, ...routes[i].handlers],
+ Object.keys(paramMap).length !== 0 ? paramMap : null,
+ ];
+ if (!hasAmbiguous) {
+ handlers[i][0] = getSortedHandlers(handlers[i][0]);
+ }
+ }
+ const [regexp, indexReplacementMap, paramReplacementMap] = trie.buildRegExp();
+ for (let i = 0, len = handlers.length; i < len; i++) {
+ const paramMap = handlers[i][1];
+ if (paramMap) {
+ for (let j = 0, len = paramMap.length; j < len; j++) {
+ paramMap[j][1] = paramReplacementMap[paramMap[j][1]];
+ const aliasTo = routes[i].paramAliasMap[paramMap[j][0]];
+ if (aliasTo) {
+ for (let k = 0, len = aliasTo.length; k < len; k++) {
+ paramMap.push([aliasTo[k], paramMap[j][1]]);
+ }
+ }
+ }
+ }
+ }
+ const handlerMap = [];
+ // using `in` because indexReplacementMap is a sparse array
+ for (const i in indexReplacementMap) {
+ handlerMap[i] = handlers[indexReplacementMap[i]];
+ }
+ return [regexp, handlerMap];
+}
+function verifyDuplicateParam(routes) {
+ const nameMap = {};
+ for (let i = 0, len = routes.length; i < len; i++) {
+ const route = routes[i];
+ for (let k = 0, len = route.hint.namedParams.length; k < len; k++) {
+ const [index, name] = route.hint.namedParams[k];
+ if (name in nameMap && index !== nameMap[name]) {
+ return false;
+ }
+ else {
+ nameMap[name] = index;
+ }
+ }
+ const paramAliasMap = route.paramAliasMap;
+ const paramAliasMapKeys = Object.keys(paramAliasMap);
+ for (let k = 0, len = paramAliasMapKeys.length; k < len; k++) {
+ const aliasFrom = paramAliasMapKeys[k];
+ for (let l = 0, len = paramAliasMap[aliasFrom].length; l < len; l++) {
+ const aliasTo = paramAliasMap[aliasFrom][l];
+ const index = nameMap[aliasFrom];
+ if (aliasTo in nameMap && index !== nameMap[aliasTo]) {
+ return false;
+ }
+ else {
+ nameMap[aliasTo] = index;
+ }
+ }
+ }
+ }
+ return true;
+}
+class RegExpRouter {
+ constructor() {
+ this.routeData = { index: 0, routes: [], methods: new Set() };
+ }
+ add(method, path, handler) {
+ if (!this.routeData) {
+ throw new Error('Can not add a route since the matcher is already built.');
+ }
+ this.routeData.index++;
+ const { index, routes, methods } = this.routeData;
+ if (path === '/*') {
+ path = '*';
+ }
+ const hint = initHint(path);
+ const handlerWithSortIndex = {
+ index,
+ handler,
+ };
+ for (let i = 0, len = routes.length; i < len; i++) {
+ if (routes[i].method === method && routes[i].path === path) {
+ routes[i].handlers.push(handlerWithSortIndex);
+ return;
+ }
+ }
+ methods.add(method);
+ routes.push({
+ method,
+ path,
+ hint,
+ handlers: [handlerWithSortIndex],
+ middleware: [],
+ paramAliasMap: {},
+ });
+ }
+ match(method, path) {
+ const [primaryMatchers, secondaryMatchers, hasAmbiguous] = this.buildAllMatchers();
+ this.match = hasAmbiguous
+ ? (method, path) => {
+ const matcher = (primaryMatchers[method] ||
+ primaryMatchers[router_1.METHOD_NAME_ALL]);
+ let match = path.match(matcher[0]);
+ if (!match) {
+ // do not support secondary matchers here.
+ return null;
+ }
+ const params = {};
+ const handlers = new Set();
+ let regExpSrc = matcher[0].source;
+ while (match) {
+ let index = match.indexOf('', 1);
+ for (;;) {
+ const [handler, paramMap] = matcher[1][index];
+ if (paramMap) {
+ for (let i = 0, len = paramMap.length; i < len; i++) {
+ params[paramMap[i][0]] = match[paramMap[i][1]];
+ }
+ }
+ for (let i = 0, len = handler.length; i < len; i++) {
+ handlers.add(handler[i]);
+ }
+ const newIndex = match.indexOf('', index + 1);
+ if (newIndex === -1) {
+ break;
+ }
+ index = newIndex;
+ }
+ regExpSrc = regExpSrc.replace(new RegExp(`((?:(?:\\(\\?:|.)*?\\([^)]*\\)){${index - 1}}.*?)\\(\\)`), '$1(^)');
+ match = path.match(new RegExp(regExpSrc));
+ }
+ return { handlers: getSortedHandlers(handlers.values()), params };
+ }
+ : (method, path) => {
+ let matcher = (primaryMatchers[method] || primaryMatchers[router_1.METHOD_NAME_ALL]);
+ let match = path.match(matcher[0]);
+ if (!match) {
+ const matchers = secondaryMatchers[method] || secondaryMatchers[router_1.METHOD_NAME_ALL];
+ for (let i = 0, len = matchers.length; i < len && !match; i++) {
+ matcher = matchers[i];
+ match = path.match(matcher[0]);
+ }
+ if (!match) {
+ return null;
+ }
+ }
+ const index = match.indexOf('', 1);
+ const [handlers, paramMap] = matcher[1][index];
+ if (!paramMap) {
+ return { handlers, params: emptyParam };
+ }
+ const params = {};
+ for (let i = 0, len = paramMap.length; i < len; i++) {
+ params[paramMap[i][0]] = match[paramMap[i][1]];
+ }
+ return { handlers, params };
+ };
+ return this.match(method, path);
+ }
+ buildAllMatchers() {
+ // @ts-ignore
+ this.routeData.routes.sort(({ hint: a }, { hint: b }) => {
+ if (a.componentsLength !== b.componentsLength) {
+ return a.componentsLength - b.componentsLength;
+ }
+ for (let i = 0, len = Math.min(a.paramIndexList.length, b.paramIndexList.length) + 1; i < len; i++) {
+ if (a.paramIndexList[i] !== b.paramIndexList[i]) {
+ if (a.paramIndexList[i] === undefined) {
+ return -1;
+ }
+ else if (b.paramIndexList[i] === undefined) {
+ return 1;
+ }
+ else {
+ return a.paramIndexList[i] - b.paramIndexList[i];
+ }
+ }
+ }
+ if (a.endWithWildcard !== b.endWithWildcard) {
+ return a.endWithWildcard ? -1 : 1;
+ }
+ return 0;
+ });
+ const primaryMatchers = {};
+ const secondaryMatchers = {};
+ let hasAmbiguous = false;
+ // @ts-ignore
+ this.routeData.methods.forEach((method) => {
+ let _hasAmbiguous;
+ [primaryMatchers[method], secondaryMatchers[method], _hasAmbiguous] =
+ this.buildMatcher(method);
+ hasAmbiguous = hasAmbiguous || _hasAmbiguous;
+ });
+ primaryMatchers[router_1.METHOD_NAME_ALL] || (primaryMatchers[router_1.METHOD_NAME_ALL] = nullMatcher);
+ secondaryMatchers[router_1.METHOD_NAME_ALL] || (secondaryMatchers[router_1.METHOD_NAME_ALL] = []);
+ delete this.routeData; // to reduce memory usage
+ return [primaryMatchers, secondaryMatchers, hasAmbiguous];
+ }
+ buildMatcher(method) {
+ var _a, _b;
+ let hasAmbiguous = false;
+ const targetMethods = new Set([method, router_1.METHOD_NAME_ALL]);
+ // @ts-ignore
+ const routes = this.routeData.routes.filter(({ method }) => targetMethods.has(method));
+ // Reset temporary data per method
+ for (let i = 0, len = routes.length; i < len; i++) {
+ routes[i].middleware = [];
+ routes[i].paramAliasMap = {};
+ }
+ // preprocess routes
+ for (let i = 0, len = routes.length; i < len; i++) {
+ for (let j = i + 1; j < len; j++) {
+ const compareResult = compareRoute(routes[i], routes[j]);
+ // i includes j
+ if (compareResult === 1) {
+ const components = routes[j].hint.components;
+ const namedParams = routes[i].hint.namedParams;
+ for (let k = 0, len = namedParams.length; k < len; k++) {
+ const c = components[namedParams[k][0]];
+ const m = c.match(/^\/:(\w+)({[^}]+})?/);
+ if (m && namedParams[k][1] === m[1]) {
+ continue;
+ }
+ if (m) {
+ (_a = routes[j].paramAliasMap)[_b = m[1]] || (_a[_b] = []);
+ routes[j].paramAliasMap[m[1]].push(namedParams[k][1]);
+ }
+ else {
+ components[namedParams[k][0]] = `/:${namedParams[k][1]}{${c.substring(1)}}`;
+ routes[j].hint.namedParams.push([
+ namedParams[k][0],
+ namedParams[k][1],
+ c.substring(1),
+ ]);
+ routes[j].path = components.join('');
+ }
+ }
+ if (routes[j].hint.components.length < routes[i].hint.components.length) {
+ routes[j].middleware.push(...routes[i].handlers.map((h) => ({
+ index: h.index,
+ handler: h.handler,
+ })));
+ }
+ else {
+ routes[j].middleware.push(...routes[i].handlers);
+ }
+ routes[i].hint.maybeHandler = false;
+ }
+ else if (compareResult === 2) {
+ // ambiguous
+ hasAmbiguous = true;
+ if (!verifyDuplicateParam([routes[i], routes[j]])) {
+ throw new Error('Duplicate param name');
+ }
+ }
+ }
+ if (!verifyDuplicateParam([routes[i]])) {
+ throw new Error('Duplicate param name');
+ }
+ }
+ if (hasAmbiguous) {
+ return [buildMatcherFromPreprocessedRoutes(routes, hasAmbiguous), [], hasAmbiguous];
+ }
+ const primaryRoutes = [];
+ const secondaryRoutes = [];
+ for (let i = 0, len = routes.length; i < len; i++) {
+ if (routes[i].hint.maybeHandler || !routes[i].hint.endWithWildcard) {
+ primaryRoutes.push(routes[i]);
+ }
+ else {
+ secondaryRoutes.push(routes[i]);
+ }
+ }
+ return [
+ buildMatcherFromPreprocessedRoutes(primaryRoutes, hasAmbiguous),
+ [buildMatcherFromPreprocessedRoutes(secondaryRoutes, hasAmbiguous)],
+ hasAmbiguous,
+ ];
+ }
+}
+exports.RegExpRouter = RegExpRouter;
diff --git a/cli/bench/testdata/npm/hono/dist/router/reg-exp-router/trie.d.ts b/cli/bench/testdata/npm/hono/dist/router/reg-exp-router/trie.d.ts
new file mode 100644
index 000000000..3f57ff559
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/router/reg-exp-router/trie.d.ts
@@ -0,0 +1,14 @@
+import type { ParamMap, Context } from './node';
+import { Node } from './node';
+export type { ParamMap } from './node';
+export declare type ReplacementMap = number[];
+interface InitOptions {
+ reverse: boolean;
+}
+export declare class Trie {
+ context: Context;
+ root: Node;
+ constructor({ reverse }?: InitOptions);
+ insert(path: string, index: number): ParamMap;
+ buildRegExp(): [RegExp, ReplacementMap, ReplacementMap];
+}
diff --git a/cli/bench/testdata/npm/hono/dist/router/reg-exp-router/trie.js b/cli/bench/testdata/npm/hono/dist/router/reg-exp-router/trie.js
new file mode 100644
index 000000000..dfcc657f3
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/router/reg-exp-router/trie.js
@@ -0,0 +1,42 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.Trie = void 0;
+const node_1 = require("./node");
+class Trie {
+ constructor({ reverse } = { reverse: false }) {
+ this.context = { varIndex: 0 };
+ this.root = new node_1.Node({ reverse });
+ }
+ insert(path, index) {
+ const paramMap = [];
+ /**
+ * - pattern (:label, :label{0-9]+}, ...)
+ * - /* wildcard
+ * - character
+ */
+ const tokens = path.match(/(?::[^\/]+)|(?:\/\*$)|./g);
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-ignore
+ this.root.insert(tokens, index, paramMap, this.context);
+ return paramMap;
+ }
+ buildRegExp() {
+ let regexp = this.root.buildRegExpStr();
+ let captureIndex = 0;
+ const indexReplacementMap = [];
+ const paramReplacementMap = [];
+ regexp = regexp.replace(/#(\d+)|@(\d+)|\.\*\$/g, (_, handlerIndex, paramIndex) => {
+ if (typeof handlerIndex !== 'undefined') {
+ indexReplacementMap[++captureIndex] = Number(handlerIndex);
+ return '$()';
+ }
+ if (typeof paramIndex !== 'undefined') {
+ paramReplacementMap[Number(paramIndex)] = ++captureIndex;
+ return '';
+ }
+ return '';
+ });
+ return [new RegExp(`^${regexp}`), indexReplacementMap, paramReplacementMap];
+ }
+}
+exports.Trie = Trie;
diff --git a/cli/bench/testdata/npm/hono/dist/router/trie-router/index.d.ts b/cli/bench/testdata/npm/hono/dist/router/trie-router/index.d.ts
new file mode 100644
index 000000000..3a38be4f9
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/router/trie-router/index.d.ts
@@ -0,0 +1 @@
+export { TrieRouter } from './router';
diff --git a/cli/bench/testdata/npm/hono/dist/router/trie-router/index.js b/cli/bench/testdata/npm/hono/dist/router/trie-router/index.js
new file mode 100644
index 000000000..7e966aa09
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/router/trie-router/index.js
@@ -0,0 +1,5 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.TrieRouter = void 0;
+var router_1 = require("./router");
+Object.defineProperty(exports, "TrieRouter", { enumerable: true, get: function () { return router_1.TrieRouter; } });
diff --git a/cli/bench/testdata/npm/hono/dist/router/trie-router/node.d.ts b/cli/bench/testdata/npm/hono/dist/router/trie-router/node.d.ts
new file mode 100644
index 000000000..a489b17f6
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/router/trie-router/node.d.ts
@@ -0,0 +1,20 @@
+import type { Result } from '../../router';
+import type { Pattern } from '../../utils/url';
+declare type HandlerSet<T> = {
+ handler: T;
+ score: number;
+ name: string;
+};
+export declare class Node<T> {
+ methods: Record<string, HandlerSet<T>>[];
+ children: Record<string, Node<T>>;
+ patterns: Pattern[];
+ order: number;
+ name: string;
+ handlerSetCache: Record<string, HandlerSet<T>[]>;
+ constructor(method?: string, handler?: T, children?: Record<string, Node<T>>);
+ insert(method: string, path: string, handler: T): Node<T>;
+ private getHandlerSets;
+ search(method: string, path: string): Result<T> | null;
+}
+export {};
diff --git a/cli/bench/testdata/npm/hono/dist/router/trie-router/node.js b/cli/bench/testdata/npm/hono/dist/router/trie-router/node.js
new file mode 100644
index 000000000..d40f604e7
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/router/trie-router/node.js
@@ -0,0 +1,168 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.Node = void 0;
+const router_1 = require("../../router");
+const url_1 = require("../../utils/url");
+function findParam(node, name) {
+ for (let i = 0, len = node.patterns.length; i < len; i++) {
+ if (typeof node.patterns[i] === 'object' && node.patterns[i][1] === name) {
+ return true;
+ }
+ }
+ const nodes = Object.values(node.children);
+ for (let i = 0, len = nodes.length; i < len; i++) {
+ if (findParam(nodes[i], name)) {
+ return true;
+ }
+ }
+ return false;
+}
+class Node {
+ constructor(method, handler, children) {
+ this.order = 0;
+ this.children = children || {};
+ this.methods = [];
+ this.name = '';
+ if (method && handler) {
+ const m = {};
+ m[method] = { handler: handler, score: 0, name: this.name };
+ this.methods = [m];
+ }
+ this.patterns = [];
+ this.handlerSetCache = {};
+ }
+ insert(method, path, handler) {
+ this.name = `${method} ${path}`;
+ this.order = ++this.order;
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
+ let curNode = this;
+ const parts = (0, url_1.splitPath)(path);
+ const parentPatterns = [];
+ const errorMessage = (name) => {
+ return `Duplicate param name, use another name instead of '${name}' - ${method} ${path} <--- '${name}'`;
+ };
+ for (let i = 0, len = parts.length; i < len; i++) {
+ const p = parts[i];
+ if (Object.keys(curNode.children).includes(p)) {
+ parentPatterns.push(...curNode.patterns);
+ curNode = curNode.children[p];
+ continue;
+ }
+ curNode.children[p] = new Node();
+ const pattern = (0, url_1.getPattern)(p);
+ if (pattern) {
+ if (typeof pattern === 'object') {
+ for (let j = 0, len = parentPatterns.length; j < len; j++) {
+ if (typeof parentPatterns[j] === 'object' && parentPatterns[j][1] === pattern[1]) {
+ throw new Error(errorMessage(pattern[1]));
+ }
+ }
+ if (Object.values(curNode.children).some((n) => findParam(n, pattern[1]))) {
+ throw new Error(errorMessage(pattern[1]));
+ }
+ }
+ curNode.patterns.push(pattern);
+ parentPatterns.push(...curNode.patterns);
+ }
+ parentPatterns.push(...curNode.patterns);
+ curNode = curNode.children[p];
+ }
+ if (!curNode.methods.length) {
+ curNode.methods = [];
+ }
+ const m = {};
+ const handlerSet = { handler: handler, name: this.name, score: this.order };
+ m[method] = handlerSet;
+ curNode.methods.push(m);
+ return curNode;
+ }
+ getHandlerSets(node, method, wildcard) {
+ var _a, _b;
+ return ((_a = node.handlerSetCache)[_b = `${method}:${wildcard ? '1' : '0'}`] || (_a[_b] = (() => {
+ const handlerSets = [];
+ node.methods.map((m) => {
+ const handlerSet = m[method] || m[router_1.METHOD_NAME_ALL];
+ if (handlerSet !== undefined) {
+ const hs = { ...handlerSet };
+ handlerSets.push(hs);
+ return;
+ }
+ });
+ return handlerSets;
+ })()));
+ }
+ search(method, path) {
+ const handlerSets = [];
+ const params = {};
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
+ const curNode = this;
+ let curNodes = [curNode];
+ const parts = (0, url_1.splitPath)(path);
+ for (let i = 0, len = parts.length; i < len; i++) {
+ const part = parts[i];
+ const isLast = i === len - 1;
+ const tempNodes = [];
+ let matched = false;
+ for (let j = 0, len2 = curNodes.length; j < len2; j++) {
+ const node = curNodes[j];
+ const nextNode = node.children[part];
+ if (nextNode) {
+ if (isLast === true) {
+ // '/hello/*' => match '/hello'
+ if (nextNode.children['*']) {
+ handlerSets.push(...this.getHandlerSets(nextNode.children['*'], method, true));
+ }
+ handlerSets.push(...this.getHandlerSets(nextNode, method));
+ matched = true;
+ }
+ tempNodes.push(nextNode);
+ }
+ for (let k = 0, len3 = node.patterns.length; k < len3; k++) {
+ const pattern = node.patterns[k];
+ // Wildcard
+ // '/hello/*/foo' => match /hello/bar/foo
+ if (pattern === '*') {
+ const astNode = node.children['*'];
+ if (astNode) {
+ handlerSets.push(...this.getHandlerSets(astNode, method));
+ tempNodes.push(astNode);
+ }
+ continue;
+ }
+ if (part === '')
+ continue;
+ // Named match
+ // `/posts/:id` => match /posts/123
+ const [key, name, matcher] = pattern;
+ if (matcher === true || (matcher instanceof RegExp && matcher.test(part))) {
+ if (typeof key === 'string') {
+ if (isLast === true) {
+ handlerSets.push(...this.getHandlerSets(node.children[key], method));
+ }
+ tempNodes.push(node.children[key]);
+ }
+ // '/book/a' => not-slug
+ // '/book/:slug' => slug
+ // GET /book/a ~> no-slug, param['slug'] => undefined
+ // GET /book/foo ~> slug, param['slug'] => foo
+ if (typeof name === 'string' && !matched) {
+ params[name] = part;
+ }
+ }
+ }
+ }
+ curNodes = tempNodes;
+ }
+ if (handlerSets.length <= 0)
+ return null;
+ const handlers = handlerSets
+ .sort((a, b) => {
+ return a.score - b.score;
+ })
+ .map((s) => {
+ return s.handler;
+ });
+ return { handlers, params };
+ }
+}
+exports.Node = Node;
diff --git a/cli/bench/testdata/npm/hono/dist/router/trie-router/router.d.ts b/cli/bench/testdata/npm/hono/dist/router/trie-router/router.d.ts
new file mode 100644
index 000000000..e8a16efb5
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/router/trie-router/router.d.ts
@@ -0,0 +1,8 @@
+import type { Result, Router } from '../../router';
+import { Node } from './node';
+export declare class TrieRouter<T> implements Router<T> {
+ node: Node<T>;
+ constructor();
+ add(method: string, path: string, handler: T): void;
+ match(method: string, path: string): Result<T> | null;
+}
diff --git a/cli/bench/testdata/npm/hono/dist/router/trie-router/router.js b/cli/bench/testdata/npm/hono/dist/router/trie-router/router.js
new file mode 100644
index 000000000..2ddad93c3
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/router/trie-router/router.js
@@ -0,0 +1,16 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.TrieRouter = void 0;
+const node_1 = require("./node");
+class TrieRouter {
+ constructor() {
+ this.node = new node_1.Node();
+ }
+ add(method, path, handler) {
+ this.node.insert(method, path, handler);
+ }
+ match(method, path) {
+ return this.node.search(method, path);
+ }
+}
+exports.TrieRouter = TrieRouter;
diff --git a/cli/bench/testdata/npm/hono/dist/utils/body.d.ts b/cli/bench/testdata/npm/hono/dist/utils/body.d.ts
new file mode 100644
index 000000000..87407539c
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/body.d.ts
@@ -0,0 +1,2 @@
+export declare type Body = string | object | Record<string, string | File> | ArrayBuffer;
+export declare const parseBody: (r: Request | Response) => Promise<Body>;
diff --git a/cli/bench/testdata/npm/hono/dist/utils/body.js b/cli/bench/testdata/npm/hono/dist/utils/body.js
new file mode 100644
index 000000000..5deeca1cd
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/body.js
@@ -0,0 +1,31 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.parseBody = void 0;
+const parseBody = async (r) => {
+ const contentType = r.headers.get('Content-Type') || '';
+ if (contentType.includes('application/json')) {
+ let body = {};
+ try {
+ body = await r.json();
+ }
+ catch { } // Do nothing
+ return body;
+ }
+ else if (contentType.includes('application/text')) {
+ return await r.text();
+ }
+ else if (contentType.startsWith('text')) {
+ return await r.text();
+ }
+ else if (contentType.includes('form')) {
+ const form = {};
+ const data = [...(await r.formData())].reduce((acc, cur) => {
+ acc[cur[0]] = cur[1];
+ return acc;
+ }, form);
+ return data;
+ }
+ const arrayBuffer = await r.arrayBuffer();
+ return arrayBuffer;
+};
+exports.parseBody = parseBody;
diff --git a/cli/bench/testdata/npm/hono/dist/utils/buffer.d.ts b/cli/bench/testdata/npm/hono/dist/utils/buffer.d.ts
new file mode 100644
index 000000000..f30e3f9d4
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/buffer.d.ts
@@ -0,0 +1,3 @@
+export declare const equal: (a: ArrayBuffer, b: ArrayBuffer) => boolean;
+export declare const timingSafeEqual: (a: string | object | boolean, b: string | object | boolean, hashFunction?: Function) => Promise<boolean>;
+export declare const bufferToString: (buffer: ArrayBuffer) => string;
diff --git a/cli/bench/testdata/npm/hono/dist/utils/buffer.js b/cli/bench/testdata/npm/hono/dist/utils/buffer.js
new file mode 100644
index 000000000..58ee6f9ae
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/buffer.js
@@ -0,0 +1,39 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.bufferToString = exports.timingSafeEqual = exports.equal = void 0;
+const crypto_1 = require("./crypto");
+const equal = (a, b) => {
+ if (a === b) {
+ return true;
+ }
+ if (a.byteLength !== b.byteLength) {
+ return false;
+ }
+ const va = new DataView(a);
+ const vb = new DataView(b);
+ let i = va.byteLength;
+ while (i--) {
+ if (va.getUint8(i) !== vb.getUint8(i)) {
+ return false;
+ }
+ }
+ return true;
+};
+exports.equal = equal;
+const timingSafeEqual = async (a, b, hashFunction) => {
+ if (!hashFunction) {
+ hashFunction = crypto_1.sha256;
+ }
+ const sa = await hashFunction(a);
+ const sb = await hashFunction(b);
+ return sa === sb && a === b;
+};
+exports.timingSafeEqual = timingSafeEqual;
+const bufferToString = (buffer) => {
+ if (buffer instanceof ArrayBuffer) {
+ const enc = new TextDecoder('utf-8');
+ return enc.decode(buffer);
+ }
+ return buffer;
+};
+exports.bufferToString = bufferToString;
diff --git a/cli/bench/testdata/npm/hono/dist/utils/cloudflare.d.ts b/cli/bench/testdata/npm/hono/dist/utils/cloudflare.d.ts
new file mode 100644
index 000000000..abdc25a5b
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/cloudflare.d.ts
@@ -0,0 +1,6 @@
+/// <reference types="@cloudflare/workers-types" />
+export declare type KVAssetOptions = {
+ manifest?: object | string;
+ namespace?: KVNamespace;
+};
+export declare const getContentFromKVAsset: (path: string, options?: KVAssetOptions) => Promise<ArrayBuffer | null>;
diff --git a/cli/bench/testdata/npm/hono/dist/utils/cloudflare.js b/cli/bench/testdata/npm/hono/dist/utils/cloudflare.js
new file mode 100644
index 000000000..4ba9a7e52
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/cloudflare.js
@@ -0,0 +1,39 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.getContentFromKVAsset = void 0;
+const getContentFromKVAsset = async (path, options) => {
+ let ASSET_MANIFEST = {};
+ if (options && options.manifest) {
+ if (typeof options.manifest === 'string') {
+ ASSET_MANIFEST = JSON.parse(options.manifest);
+ }
+ else {
+ ASSET_MANIFEST = options.manifest;
+ }
+ }
+ else {
+ if (typeof __STATIC_CONTENT_MANIFEST === 'string') {
+ ASSET_MANIFEST = JSON.parse(__STATIC_CONTENT_MANIFEST);
+ }
+ else {
+ ASSET_MANIFEST = __STATIC_CONTENT_MANIFEST;
+ }
+ }
+ let ASSET_NAMESPACE;
+ if (options && options.namespace) {
+ ASSET_NAMESPACE = options.namespace;
+ }
+ else {
+ ASSET_NAMESPACE = __STATIC_CONTENT;
+ }
+ const key = ASSET_MANIFEST[path] || path;
+ if (!key) {
+ return null;
+ }
+ let content = await ASSET_NAMESPACE.get(key, { type: 'arrayBuffer' });
+ if (content) {
+ content = content;
+ }
+ return content;
+};
+exports.getContentFromKVAsset = getContentFromKVAsset;
diff --git a/cli/bench/testdata/npm/hono/dist/utils/cookie.d.ts b/cli/bench/testdata/npm/hono/dist/utils/cookie.d.ts
new file mode 100644
index 000000000..d467efde5
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/cookie.d.ts
@@ -0,0 +1,13 @@
+export declare type Cookie = Record<string, string>;
+export declare type CookieOptions = {
+ domain?: string;
+ expires?: Date;
+ httpOnly?: boolean;
+ maxAge?: number;
+ path?: string;
+ secure?: boolean;
+ signed?: boolean;
+ sameSite?: 'Strict' | 'Lax' | 'None';
+};
+export declare const parse: (cookie: string) => Cookie;
+export declare const serialize: (name: string, value: string, opt?: CookieOptions) => string;
diff --git a/cli/bench/testdata/npm/hono/dist/utils/cookie.js b/cli/bench/testdata/npm/hono/dist/utils/cookie.js
new file mode 100644
index 000000000..13a18602f
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/cookie.js
@@ -0,0 +1,40 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.serialize = exports.parse = void 0;
+const parse = (cookie) => {
+ const pairs = cookie.split(/;\s*/g);
+ const parsedCookie = {};
+ for (let i = 0, len = pairs.length; i < len; i++) {
+ const pair = pairs[i].split(/\s*=\s*([^\s]+)/);
+ parsedCookie[pair[0]] = decodeURIComponent(pair[1]);
+ }
+ return parsedCookie;
+};
+exports.parse = parse;
+const serialize = (name, value, opt = {}) => {
+ value = encodeURIComponent(value);
+ let cookie = `${name}=${value}`;
+ if (opt.maxAge) {
+ cookie += `; Max-Age=${Math.floor(opt.maxAge)}`;
+ }
+ if (opt.domain) {
+ cookie += '; Domain=' + opt.domain;
+ }
+ if (opt.path) {
+ cookie += '; Path=' + opt.path;
+ }
+ if (opt.expires) {
+ cookie += '; Expires=' + opt.expires.toUTCString();
+ }
+ if (opt.httpOnly) {
+ cookie += '; HttpOnly';
+ }
+ if (opt.secure) {
+ cookie += '; Secure';
+ }
+ if (opt.sameSite) {
+ cookie += `; SameSite=${opt.sameSite}`;
+ }
+ return cookie;
+};
+exports.serialize = serialize;
diff --git a/cli/bench/testdata/npm/hono/dist/utils/crypto.d.ts b/cli/bench/testdata/npm/hono/dist/utils/crypto.d.ts
new file mode 100644
index 000000000..540afb399
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/crypto.d.ts
@@ -0,0 +1,10 @@
+declare type Algorithm = {
+ name: string;
+ alias: string;
+};
+declare type Data = string | boolean | number | object | ArrayBufferView | ArrayBuffer | ReadableStream;
+export declare const sha256: (data: Data) => Promise<string | null>;
+export declare const sha1: (data: Data) => Promise<string | null>;
+export declare const md5: (data: Data) => Promise<string | null>;
+export declare const createHash: (data: Data, algorithm: Algorithm) => Promise<string | null>;
+export {};
diff --git a/cli/bench/testdata/npm/hono/dist/utils/crypto.js b/cli/bench/testdata/npm/hono/dist/utils/crypto.js
new file mode 100644
index 000000000..0d259ae1c
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/crypto.js
@@ -0,0 +1,53 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.createHash = exports.md5 = exports.sha1 = exports.sha256 = void 0;
+const sha256 = async (data) => {
+ const algorithm = { name: 'SHA-256', alias: 'sha256' };
+ const hash = await (0, exports.createHash)(data, algorithm);
+ return hash;
+};
+exports.sha256 = sha256;
+const sha1 = async (data) => {
+ const algorithm = { name: 'SHA-1', alias: 'sha1' };
+ const hash = await (0, exports.createHash)(data, algorithm);
+ return hash;
+};
+exports.sha1 = sha1;
+const md5 = async (data) => {
+ const algorithm = { name: 'MD5', alias: 'md5' };
+ const hash = await (0, exports.createHash)(data, algorithm);
+ return hash;
+};
+exports.md5 = md5;
+const createHash = async (data, algorithm) => {
+ let sourceBuffer;
+ if (data instanceof ReadableStream) {
+ let body = '';
+ const reader = data.getReader();
+ await reader?.read().then(async (chuck) => {
+ const value = await (0, exports.createHash)(chuck.value || '', algorithm);
+ body += value;
+ });
+ return body;
+ }
+ if (ArrayBuffer.isView(data) || data instanceof ArrayBuffer) {
+ sourceBuffer = data;
+ }
+ else {
+ if (typeof data === 'object') {
+ data = JSON.stringify(data);
+ }
+ sourceBuffer = new TextEncoder().encode(String(data));
+ }
+ if (crypto && crypto.subtle) {
+ const buffer = await crypto.subtle.digest({
+ name: algorithm.name,
+ }, sourceBuffer);
+ const hash = Array.prototype.map
+ .call(new Uint8Array(buffer), (x) => ('00' + x.toString(16)).slice(-2))
+ .join('');
+ return hash;
+ }
+ return null;
+};
+exports.createHash = createHash;
diff --git a/cli/bench/testdata/npm/hono/dist/utils/encode.d.ts b/cli/bench/testdata/npm/hono/dist/utils/encode.d.ts
new file mode 100644
index 000000000..e1db501e0
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/encode.d.ts
@@ -0,0 +1,7 @@
+export declare const encodeBase64: (str: string) => string;
+export declare const decodeBase64: (str: string) => string;
+export declare const encodeBase64URL: (str: string) => string;
+export declare const decodeBase64URL: (str: string) => string;
+export declare const utf8ToUint8Array: (str: string) => Uint8Array;
+export declare const arrayBufferToBase64: (buf: ArrayBuffer) => Promise<string>;
+export declare const arrayBufferToBase64URL: (buf: ArrayBuffer) => Promise<string>;
diff --git a/cli/bench/testdata/npm/hono/dist/utils/encode.js b/cli/bench/testdata/npm/hono/dist/utils/encode.js
new file mode 100644
index 000000000..46e61c079
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/encode.js
@@ -0,0 +1,80 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.arrayBufferToBase64URL = exports.arrayBufferToBase64 = exports.utf8ToUint8Array = exports.decodeBase64URL = exports.encodeBase64URL = exports.decodeBase64 = exports.encodeBase64 = void 0;
+const encodeBase64 = (str) => {
+ if (str === null) {
+ throw new TypeError('1st argument of "encodeBase64" should not be null.');
+ }
+ try {
+ const encoder = new TextEncoder();
+ const bytes = encoder.encode(str);
+ return btoa(String.fromCharCode(...bytes));
+ }
+ catch { }
+ try {
+ return Buffer.from(str).toString('base64');
+ }
+ catch (e) {
+ console.error('If you want to do "encodeBase64", polyfill "buffer" module.');
+ throw e;
+ }
+};
+exports.encodeBase64 = encodeBase64;
+const decodeBase64 = (str) => {
+ if (str === null) {
+ throw new TypeError('1st argument of "decodeBase64" should not be null.');
+ }
+ try {
+ const text = atob(str);
+ const bytes = new Uint8Array(text.split('').map((c) => c.charCodeAt(0)));
+ const decoder = new TextDecoder();
+ return decoder.decode(bytes);
+ }
+ catch { }
+ try {
+ return Buffer.from(str, 'base64').toString();
+ }
+ catch (e) {
+ console.error('If you want to do "decodeBase64", polyfill "buffer" module.');
+ throw e;
+ }
+};
+exports.decodeBase64 = decodeBase64;
+const encodeBase64URL = (str) => {
+ return (0, exports.encodeBase64)(str).replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
+};
+exports.encodeBase64URL = encodeBase64URL;
+const decodeBase64URL = (str) => {
+ const pad = (s) => {
+ const diff = s.length % 4;
+ if (diff === 2) {
+ return `${s}==`;
+ }
+ if (diff === 3) {
+ return `${s}=`;
+ }
+ return s;
+ };
+ return (0, exports.decodeBase64)(pad(str).replace(/-/g, '+').replace('_', '/'));
+};
+exports.decodeBase64URL = decodeBase64URL;
+const utf8ToUint8Array = (str) => {
+ const encoder = new TextEncoder();
+ return encoder.encode(str);
+};
+exports.utf8ToUint8Array = utf8ToUint8Array;
+const arrayBufferToBase64 = async (buf) => {
+ if (typeof btoa === 'function') {
+ return btoa(String.fromCharCode(...new Uint8Array(buf)));
+ }
+ try {
+ return Buffer.from(String.fromCharCode(...new Uint8Array(buf))).toString('base64');
+ }
+ catch (e) { }
+ return '';
+};
+exports.arrayBufferToBase64 = arrayBufferToBase64;
+const arrayBufferToBase64URL = async (buf) => {
+ return (await (0, exports.arrayBufferToBase64)(buf)).replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
+};
+exports.arrayBufferToBase64URL = arrayBufferToBase64URL;
diff --git a/cli/bench/testdata/npm/hono/dist/utils/filepath.d.ts b/cli/bench/testdata/npm/hono/dist/utils/filepath.d.ts
new file mode 100644
index 000000000..99453d5d6
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/filepath.d.ts
@@ -0,0 +1,7 @@
+declare type FilePathOptions = {
+ filename: string;
+ root?: string;
+ defaultDocument?: string;
+};
+export declare const getFilePath: (options: FilePathOptions) => string;
+export {};
diff --git a/cli/bench/testdata/npm/hono/dist/utils/filepath.js b/cli/bench/testdata/npm/hono/dist/utils/filepath.js
new file mode 100644
index 000000000..43451a9cc
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/filepath.js
@@ -0,0 +1,25 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.getFilePath = void 0;
+const getFilePath = (options) => {
+ let filename = options.filename;
+ let root = options.root || '';
+ const defaultDocument = options.defaultDocument || 'index.html';
+ if (filename.endsWith('/')) {
+ // /top/ => /top/index.html
+ filename = filename.concat(defaultDocument);
+ }
+ else if (!filename.match(/\.[a-zA-Z0-9]+$/)) {
+ // /top => /top/index.html
+ filename = filename.concat('/' + defaultDocument);
+ }
+ // /foo.html => foo.html
+ filename = filename.replace(/^\.?\//, '');
+ // assets/ => assets
+ root = root.replace(/\/$/, '');
+ // ./assets/foo.html => assets/foo.html
+ let path = root ? root + '/' + filename : filename;
+ path = path.replace(/^\.?\//, '');
+ return path;
+};
+exports.getFilePath = getFilePath;
diff --git a/cli/bench/testdata/npm/hono/dist/utils/html.d.ts b/cli/bench/testdata/npm/hono/dist/utils/html.d.ts
new file mode 100644
index 000000000..d8d5cd4e7
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/html.d.ts
@@ -0,0 +1,6 @@
+export declare type HtmlEscaped = {
+ isEscaped: true;
+};
+export declare type HtmlEscapedString = string & HtmlEscaped;
+export declare type StringBuffer = [string];
+export declare const escapeToBuffer: (str: string, buffer: StringBuffer) => void;
diff --git a/cli/bench/testdata/npm/hono/dist/utils/html.js b/cli/bench/testdata/npm/hono/dist/utils/html.js
new file mode 100644
index 000000000..920739092
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/html.js
@@ -0,0 +1,38 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.escapeToBuffer = void 0;
+// The `escapeToBuffer` implementation is based on code from the MIT licensed `react-dom` package.
+// https://github.com/facebook/react/blob/main/packages/react-dom/src/server/escapeTextForBrowser.js
+const escapeRe = /[&<>"]/;
+const escapeToBuffer = (str, buffer) => {
+ const match = str.search(escapeRe);
+ if (match === -1) {
+ buffer[0] += str;
+ return;
+ }
+ let escape;
+ let index;
+ let lastIndex = 0;
+ for (index = match; index < str.length; index++) {
+ switch (str.charCodeAt(index)) {
+ case 34: // "
+ escape = '&quot;';
+ break;
+ case 38: // &
+ escape = '&amp;';
+ break;
+ case 60: // <
+ escape = '&lt;';
+ break;
+ case 62: // >
+ escape = '&gt;';
+ break;
+ default:
+ continue;
+ }
+ buffer[0] += str.substring(lastIndex, index) + escape;
+ lastIndex = index + 1;
+ }
+ buffer[0] += str.substring(lastIndex, index);
+};
+exports.escapeToBuffer = escapeToBuffer;
diff --git a/cli/bench/testdata/npm/hono/dist/utils/http-status.d.ts b/cli/bench/testdata/npm/hono/dist/utils/http-status.d.ts
new file mode 100644
index 000000000..5002ec0ba
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/http-status.d.ts
@@ -0,0 +1,2 @@
+export declare const getStatusText: (statusCode: StatusCode) => string;
+export declare type StatusCode = 100 | 101 | 102 | 103 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 226 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 429 | 431 | 444 | 449 | 450 | 451 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 598 | 599;
diff --git a/cli/bench/testdata/npm/hono/dist/utils/http-status.js b/cli/bench/testdata/npm/hono/dist/utils/http-status.js
new file mode 100644
index 000000000..295d3f1ec
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/http-status.js
@@ -0,0 +1,50 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.getStatusText = void 0;
+const getStatusText = (statusCode) => {
+ const text = statuses[statusCode];
+ return text;
+};
+exports.getStatusText = getStatusText;
+const statuses = {
+ 100: 'Continue',
+ 101: 'Switching Protocols',
+ 102: 'Processing',
+ 103: 'Early Hints',
+ 200: 'OK',
+ 201: 'Created',
+ 202: 'Accepted',
+ 204: 'No Content',
+ 206: 'Partial Content',
+ 301: 'Moved Permanently',
+ 302: 'Moved Temporarily',
+ 303: 'See Other',
+ 304: 'Not Modified',
+ 307: 'Temporary Redirect',
+ 308: 'Permanent Redirect',
+ 400: 'Bad Request',
+ 401: 'Unauthorized',
+ 402: 'Payment Required',
+ 403: 'Forbidden',
+ 404: 'Not Found',
+ 405: 'Not Allowed',
+ 406: 'Not Acceptable',
+ 408: 'Request Time-out',
+ 409: 'Conflict',
+ 410: 'Gone',
+ 411: 'Length Required',
+ 412: 'Precondition Failed',
+ 413: 'Request Entity Too Large',
+ 414: 'Request-URI Too Large',
+ 415: 'Unsupported Media Type',
+ 416: 'Requested Range Not Satisfiable',
+ 421: 'Misdirected Request',
+ 429: 'Too Many Requests',
+ 500: 'Internal Server Error',
+ 501: 'Not Implemented',
+ 502: 'Bad Gateway',
+ 503: 'Service Temporarily Unavailable',
+ 504: 'Gateway Time-out',
+ 505: 'HTTP Version Not Supported',
+ 507: 'Insufficient Storage',
+};
diff --git a/cli/bench/testdata/npm/hono/dist/utils/jwt/index.d.ts b/cli/bench/testdata/npm/hono/dist/utils/jwt/index.d.ts
new file mode 100644
index 000000000..8581a525a
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/jwt/index.d.ts
@@ -0,0 +1 @@
+export * as Jwt from './jwt';
diff --git a/cli/bench/testdata/npm/hono/dist/utils/jwt/index.js b/cli/bench/testdata/npm/hono/dist/utils/jwt/index.js
new file mode 100644
index 000000000..221dba30c
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/jwt/index.js
@@ -0,0 +1,27 @@
+"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() { return m[k]; } };
+ }
+ Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
+}) : function(o, v) {
+ o["default"] = v;
+});
+var __importStar = (this && this.__importStar) || function (mod) {
+ if (mod && mod.__esModule) return mod;
+ var result = {};
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
+ __setModuleDefault(result, mod);
+ return result;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.Jwt = void 0;
+exports.Jwt = __importStar(require("./jwt"));
diff --git a/cli/bench/testdata/npm/hono/dist/utils/jwt/jwt.d.ts b/cli/bench/testdata/npm/hono/dist/utils/jwt/jwt.d.ts
new file mode 100644
index 000000000..46aba49e5
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/jwt/jwt.d.ts
@@ -0,0 +1,7 @@
+import { AlgorithmTypes } from './types';
+export declare const sign: (payload: unknown, secret: string, alg?: AlgorithmTypes) => Promise<string>;
+export declare const verify: (token: string, secret: string, alg?: AlgorithmTypes) => Promise<boolean>;
+export declare const decode: (token: string) => {
+ header: any;
+ payload: any;
+};
diff --git a/cli/bench/testdata/npm/hono/dist/utils/jwt/jwt.js b/cli/bench/testdata/npm/hono/dist/utils/jwt/jwt.js
new file mode 100644
index 000000000..73a3f2df4
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/jwt/jwt.js
@@ -0,0 +1,101 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.decode = exports.verify = exports.sign = void 0;
+const encode_1 = require("../../utils/encode");
+const types_1 = require("./types");
+const types_2 = require("./types");
+var CryptoKeyFormat;
+(function (CryptoKeyFormat) {
+ CryptoKeyFormat["RAW"] = "raw";
+ CryptoKeyFormat["PKCS8"] = "pkcs8";
+ CryptoKeyFormat["SPKI"] = "spki";
+ CryptoKeyFormat["JWK"] = "jwk";
+})(CryptoKeyFormat || (CryptoKeyFormat = {}));
+var CryptoKeyUsage;
+(function (CryptoKeyUsage) {
+ CryptoKeyUsage["Ecrypt"] = "encrypt";
+ CryptoKeyUsage["Decrypt"] = "decrypt";
+ CryptoKeyUsage["Sign"] = "sign";
+ CryptoKeyUsage["Verify"] = "verify";
+ CryptoKeyUsage["Deriverkey"] = "deriveKey";
+ CryptoKeyUsage["DeriveBits"] = "deriveBits";
+ CryptoKeyUsage["WrapKey"] = "wrapKey";
+ CryptoKeyUsage["UnwrapKey"] = "unwrapKey";
+})(CryptoKeyUsage || (CryptoKeyUsage = {}));
+const param = (name) => {
+ switch (name.toUpperCase()) {
+ case 'HS256':
+ return {
+ name: 'HMAC',
+ hash: {
+ name: 'SHA-256',
+ },
+ };
+ case 'HS384':
+ return {
+ name: 'HMAC',
+ hash: {
+ name: 'SHA-384',
+ },
+ };
+ case 'HS512':
+ return {
+ name: 'HMAC',
+ hash: {
+ name: 'SHA-512',
+ },
+ };
+ default:
+ throw new types_2.JwtAlgorithmNotImplemented(name);
+ }
+};
+const signing = async (data, secret, alg = types_1.AlgorithmTypes.HS256) => {
+ if (!crypto.subtle || !crypto.subtle.importKey) {
+ throw new Error('`crypto.subtle.importKey` is undefined. JWT auth middleware requires it.');
+ }
+ const cryptoKey = await crypto.subtle.importKey(CryptoKeyFormat.RAW, (0, encode_1.utf8ToUint8Array)(secret), param(alg), false, [CryptoKeyUsage.Sign]);
+ return await crypto.subtle.sign(param(alg), cryptoKey, (0, encode_1.utf8ToUint8Array)(data));
+};
+const sign = async (payload, secret, alg = types_1.AlgorithmTypes.HS256) => {
+ const encodedPayload = await (0, encode_1.encodeBase64URL)(JSON.stringify(payload));
+ const encodedHeader = await (0, encode_1.encodeBase64URL)(JSON.stringify({ alg, typ: 'JWT' }));
+ const partialToken = `${encodedHeader}.${encodedPayload}`;
+ const signature = await (0, encode_1.arrayBufferToBase64URL)(await signing(partialToken, secret, alg));
+ return `${partialToken}.${signature}`;
+};
+exports.sign = sign;
+const verify = async (token, secret, alg = types_1.AlgorithmTypes.HS256) => {
+ const tokenParts = token.split('.');
+ if (tokenParts.length !== 3) {
+ throw new types_2.JwtTokenInvalid(token);
+ }
+ const { payload } = (0, exports.decode)(token);
+ if (payload.nbf && payload.nbf > Math.floor(Date.now() / 1000)) {
+ throw new types_2.JwtTokenNotBefore(token);
+ }
+ if (payload.exp && payload.exp <= Math.floor(Date.now() / 1000)) {
+ throw new types_2.JwtTokenExpired(token);
+ }
+ const signature = await (0, encode_1.arrayBufferToBase64URL)(await signing(tokenParts.slice(0, 2).join('.'), secret, alg));
+ if (signature !== tokenParts[2]) {
+ throw new types_2.JwtTokenSignatureMismatched(token);
+ }
+ return true;
+};
+exports.verify = verify;
+// eslint-disable-next-line
+const decode = (token) => {
+ try {
+ const [h, p] = token.split('.');
+ const header = JSON.parse((0, encode_1.decodeBase64URL)(h));
+ const payload = JSON.parse((0, encode_1.decodeBase64URL)(p));
+ return {
+ header,
+ payload,
+ };
+ }
+ catch (e) {
+ throw new types_2.JwtTokenInvalid(token);
+ }
+};
+exports.decode = decode;
diff --git a/cli/bench/testdata/npm/hono/dist/utils/jwt/types.d.ts b/cli/bench/testdata/npm/hono/dist/utils/jwt/types.d.ts
new file mode 100644
index 000000000..b3c8f3f17
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/jwt/types.d.ts
@@ -0,0 +1,25 @@
+export declare class JwtAlgorithmNotImplemented extends Error {
+ constructor(token: string);
+}
+/**
+ * Export for backward compatibility
+ * @deprecated Use JwtAlgorithmNotImplemented instead
+**/
+export declare const JwtAlorithmNotImplemented: typeof JwtAlgorithmNotImplemented;
+export declare class JwtTokenInvalid extends Error {
+ constructor(token: string);
+}
+export declare class JwtTokenNotBefore extends Error {
+ constructor(token: string);
+}
+export declare class JwtTokenExpired extends Error {
+ constructor(token: string);
+}
+export declare class JwtTokenSignatureMismatched extends Error {
+ constructor(token: string);
+}
+export declare enum AlgorithmTypes {
+ HS256 = "HS256",
+ HS384 = "HS384",
+ HS512 = "HS512"
+}
diff --git a/cli/bench/testdata/npm/hono/dist/utils/jwt/types.js b/cli/bench/testdata/npm/hono/dist/utils/jwt/types.js
new file mode 100644
index 000000000..638bdbe6e
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/jwt/types.js
@@ -0,0 +1,49 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.AlgorithmTypes = exports.JwtTokenSignatureMismatched = exports.JwtTokenExpired = exports.JwtTokenNotBefore = exports.JwtTokenInvalid = exports.JwtAlorithmNotImplemented = exports.JwtAlgorithmNotImplemented = void 0;
+class JwtAlgorithmNotImplemented extends Error {
+ constructor(token) {
+ super(`invalid JWT token: ${token}`);
+ this.name = 'JwtAlgorithmNotImplemented';
+ }
+}
+exports.JwtAlgorithmNotImplemented = JwtAlgorithmNotImplemented;
+/**
+ * Export for backward compatibility
+ * @deprecated Use JwtAlgorithmNotImplemented instead
+**/
+exports.JwtAlorithmNotImplemented = JwtAlgorithmNotImplemented;
+class JwtTokenInvalid extends Error {
+ constructor(token) {
+ super(`invalid JWT token: ${token}`);
+ this.name = 'JwtTokenInvalid';
+ }
+}
+exports.JwtTokenInvalid = JwtTokenInvalid;
+class JwtTokenNotBefore extends Error {
+ constructor(token) {
+ super(`token (${token}) is being used before it's valid`);
+ this.name = 'JwtTokenNotBefore';
+ }
+}
+exports.JwtTokenNotBefore = JwtTokenNotBefore;
+class JwtTokenExpired extends Error {
+ constructor(token) {
+ super(`token (${token}) expired`);
+ this.name = 'JwtTokenExpired';
+ }
+}
+exports.JwtTokenExpired = JwtTokenExpired;
+class JwtTokenSignatureMismatched extends Error {
+ constructor(token) {
+ super(`token(${token}) signature mismatched`);
+ this.name = 'JwtTokenSignatureMismatched';
+ }
+}
+exports.JwtTokenSignatureMismatched = JwtTokenSignatureMismatched;
+var AlgorithmTypes;
+(function (AlgorithmTypes) {
+ AlgorithmTypes["HS256"] = "HS256";
+ AlgorithmTypes["HS384"] = "HS384";
+ AlgorithmTypes["HS512"] = "HS512";
+})(AlgorithmTypes = exports.AlgorithmTypes || (exports.AlgorithmTypes = {}));
diff --git a/cli/bench/testdata/npm/hono/dist/utils/mime.d.ts b/cli/bench/testdata/npm/hono/dist/utils/mime.d.ts
new file mode 100644
index 000000000..83e4db22e
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/mime.d.ts
@@ -0,0 +1 @@
+export declare const getMimeType: (filename: string) => string | undefined;
diff --git a/cli/bench/testdata/npm/hono/dist/utils/mime.js b/cli/bench/testdata/npm/hono/dist/utils/mime.js
new file mode 100644
index 000000000..18aa76d52
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/mime.js
@@ -0,0 +1,92 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.getMimeType = void 0;
+const getMimeType = (filename) => {
+ const regexp = /\.([a-zA-Z0-9]+?)$/;
+ const match = filename.match(regexp);
+ if (!match)
+ return;
+ let mimeType = mimes[match[1]];
+ if ((mimeType && mimeType.startsWith('text')) || mimeType === 'application/json') {
+ mimeType += '; charset=utf-8';
+ }
+ return mimeType;
+};
+exports.getMimeType = getMimeType;
+const mimes = {
+ aac: 'audio/aac',
+ abw: 'application/x-abiword',
+ arc: 'application/x-freearc',
+ avi: 'video/x-msvideo',
+ azw: 'application/vnd.amazon.ebook',
+ bin: 'application/octet-stream',
+ bmp: 'image/bmp',
+ bz: 'application/x-bzip',
+ bz2: 'application/x-bzip2',
+ csh: 'application/x-csh',
+ css: 'text/css',
+ csv: 'text/csv',
+ doc: 'application/msword',
+ docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+ eot: 'application/vnd.ms-fontobject',
+ epub: 'application/epub+zip',
+ gz: 'application/gzip',
+ gif: 'image/gif',
+ htm: 'text/html',
+ html: 'text/html',
+ ico: 'image/x-icon',
+ ics: 'text/calendar',
+ jar: 'application/java-archive',
+ jpeg: 'image/jpeg',
+ jpg: 'image/jpeg',
+ js: 'text/javascript',
+ json: 'application/json',
+ jsonld: 'application/ld+json',
+ map: 'application/json',
+ mid: 'audio/x-midi',
+ midi: 'audio/x-midi',
+ mjs: 'text/javascript',
+ mp3: 'audio/mpeg',
+ mpeg: 'video/mpeg',
+ mpkg: 'application/vnd.apple.installer+xml',
+ odp: 'application/vnd.oasis.opendocument.presentation',
+ ods: 'application/vnd.oasis.opendocument.spreadsheet',
+ odt: 'application/vnd.oasis.opendocument.text',
+ oga: 'audio/ogg',
+ ogv: 'video/ogg',
+ ogx: 'application/ogg',
+ opus: 'audio/opus',
+ otf: 'font/otf',
+ png: 'image/png',
+ pdf: 'application/pdf',
+ php: 'application/php',
+ ppt: 'application/vnd.ms-powerpoint',
+ pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
+ rar: 'application/vnd.rar',
+ rtf: 'application/rtf',
+ sh: 'application/x-sh',
+ svg: 'image/svg+xml',
+ swf: 'application/x-shockwave-flash',
+ tar: 'application/x-tar',
+ tif: 'image/tiff',
+ tiff: 'image/tiff',
+ ts: 'video/mp2t',
+ ttf: 'font/ttf',
+ txt: 'text/plain',
+ vsd: 'application/vnd.visio',
+ wav: 'audio/wav',
+ weba: 'audio/webm',
+ webm: 'video/webm',
+ webp: 'image/webp',
+ woff: 'font/woff',
+ woff2: 'font/woff2',
+ xhtml: 'application/xhtml+xml',
+ xls: 'application/vnd.ms-excel',
+ xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+ xml: 'application/xml',
+ xul: 'application/vnd.mozilla.xul+xml',
+ zip: 'application/zip',
+ '3gp': 'video/3gpp',
+ '3g2': 'video/3gpp2',
+ '7z': 'application/x-7z-compressed',
+};
diff --git a/cli/bench/testdata/npm/hono/dist/utils/url.d.ts b/cli/bench/testdata/npm/hono/dist/utils/url.d.ts
new file mode 100644
index 000000000..16e077f04
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/url.d.ts
@@ -0,0 +1,6 @@
+export declare type Pattern = readonly [string, string, RegExp | true] | '*';
+export declare const splitPath: (path: string) => string[];
+export declare const getPattern: (label: string) => Pattern | null;
+export declare const getPathFromURL: (url: string, strict?: boolean) => string;
+export declare const isAbsoluteURL: (url: string) => boolean;
+export declare const mergePath: (...paths: string[]) => string;
diff --git a/cli/bench/testdata/npm/hono/dist/utils/url.js b/cli/bench/testdata/npm/hono/dist/utils/url.js
new file mode 100644
index 000000000..0e8fc33a3
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/dist/utils/url.js
@@ -0,0 +1,83 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.mergePath = exports.isAbsoluteURL = exports.getPathFromURL = exports.getPattern = exports.splitPath = void 0;
+const URL_REGEXP = /^https?:\/\/[a-zA-Z0-9\-\.:]+(\/?[^?#]*)/;
+const splitPath = (path) => {
+ const paths = path.split(/\//); // faster than path.split('/')
+ if (paths[0] === '') {
+ paths.shift();
+ }
+ return paths;
+};
+exports.splitPath = splitPath;
+const patternCache = {};
+const getPattern = (label) => {
+ // * => wildcard
+ // :id{[0-9]+} => ([0-9]+)
+ // :id => (.+)
+ //const name = ''
+ if (label === '*') {
+ return '*';
+ }
+ const match = label.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
+ if (match) {
+ if (!patternCache[label]) {
+ if (match[2]) {
+ patternCache[label] = [label, match[1], new RegExp('^' + match[2] + '$')];
+ }
+ else {
+ patternCache[label] = [label, match[1], true];
+ }
+ }
+ return patternCache[label];
+ }
+ return null;
+};
+exports.getPattern = getPattern;
+const getPathFromURL = (url, strict = true) => {
+ const queryIndex = url.indexOf('?');
+ const result = url.substring(url.indexOf('/', 8), queryIndex === -1 ? url.length : queryIndex);
+ // if strict routing is false => `/hello/hey/` and `/hello/hey` are treated the same
+ // default is true
+ if (strict === false && result.endsWith('/')) {
+ return result.slice(0, -1);
+ }
+ return result;
+};
+exports.getPathFromURL = getPathFromURL;
+const isAbsoluteURL = (url) => {
+ const match = url.match(URL_REGEXP);
+ if (match) {
+ return true;
+ }
+ return false;
+};
+exports.isAbsoluteURL = isAbsoluteURL;
+const mergePath = (...paths) => {
+ let p = '';
+ let endsWithSlash = false;
+ for (let path of paths) {
+ /* ['/hey/','/say'] => ['/hey', '/say'] */
+ if (p.endsWith('/')) {
+ p = p.slice(0, -1);
+ endsWithSlash = true;
+ }
+ /* ['/hey','say'] => ['/hey', '/say'] */
+ if (!path.startsWith('/')) {
+ path = `/${path}`;
+ }
+ /* ['/hey/', '/'] => `/hey/` */
+ if (path === '/' && endsWithSlash) {
+ p = `${p}/`;
+ }
+ else if (path !== '/') {
+ p = `${p}${path}`;
+ }
+ /* ['/', '/'] => `/` */
+ if (path === '/' && p === '') {
+ p = '/';
+ }
+ }
+ return p;
+};
+exports.mergePath = mergePath;
diff --git a/cli/bench/testdata/npm/hono/package.json b/cli/bench/testdata/npm/hono/package.json
new file mode 100644
index 000000000..0adf8d494
--- /dev/null
+++ b/cli/bench/testdata/npm/hono/package.json
@@ -0,0 +1,168 @@
+{
+ "name": "hono",
+ "version": "2.0.9",
+ "description": "Ultrafast web framework for Cloudflare Workers.",
+ "main": "dist/index.js",
+ "types": "dist/index.d.ts",
+ "files": [
+ "dist"
+ ],
+ "scripts": {
+ "test": "jest",
+ "test:deno": "deno test --allow-read deno_test",
+ "test:bun": "bun wiptest --jsx-import-source ../src/middleware/jsx/jsx-dev-runtime bun_test/index.test.tsx",
+ "test:all": "yarn test && yarn test:deno && yarn test:bun",
+ "lint": "eslint --ext js,ts src .eslintrc.js",
+ "lint:fix": "eslint --ext js,ts src .eslintrc.js --fix",
+ "denoify": "rimraf deno_dist && denoify && rimraf 'deno_dist/**/*.test.ts'",
+ "build": "rimraf dist && tsc --project tsconfig.build.esm.json && tsc --project tsconfig.build.json",
+ "watch": "tsc --project tsconfig.build.json -w",
+ "prerelease": "yarn denoify && yarn test:deno && yarn build",
+ "release": "np"
+ },
+ "exports": {
+ ".": "./dist/index.js",
+ "./basic-auth": "./dist/middleware/basic-auth/index.js",
+ "./bearer-auth": "./dist/middleware/bearer-auth/index.js",
+ "./cache": "./dist/middleware/cache/index.js",
+ "./compress": "./dist/middleware/compress/index.js",
+ "./cors": "./dist/middleware/cors/index.js",
+ "./etag": "./dist/middleware/etag/index.js",
+ "./html": "./dist/middleware/html/index.js",
+ "./jsx": "./dist/middleware/jsx/index.js",
+ "./jsx/jsx-dev-runtime": "./dist/middleware/jsx/jsx-dev-runtime.js",
+ "./jsx/jsx-runtime": "./dist/middleware/jsx/jsx-runtime.js",
+ "./jwt": "./dist/middleware/jwt/index.js",
+ "./logger": "./dist/middleware/logger/index.js",
+ "./powered-by": "./dist/middleware/powered-by/index.js",
+ "./pretty-json": "./dist/middleware/pretty-json/index.js",
+ "./serve-static": "./dist/middleware/serve-static/index.js",
+ "./serve-static.bun": "./dist/middleware/serve-static/bun.js",
+ "./serve-static.module": "./dist/middleware/serve-static/module.mjs",
+ "./router/trie-router": "./dist/router/trie-router/index.js",
+ "./router/reg-exp-router": "./dist/router/reg-exp-router/index.js",
+ "./utils/jwt": "./dist/utils/jwt/index.js",
+ "./utils/*": "./dist/utils/*.js"
+ },
+ "typesVersions": {
+ "*": {
+ "basic-auth": [
+ "./dist/middleware/basic-auth"
+ ],
+ "bearer-auth": [
+ "./dist/middleware/bearer-auth"
+ ],
+ "cache": [
+ "./dist/middleware/cache"
+ ],
+ "compress": [
+ "./dist/middleware/compress"
+ ],
+ "cors": [
+ "./dist/middleware/cors"
+ ],
+ "etag": [
+ "./dist/middleware/etag"
+ ],
+ "html": [
+ "./dist/middleware/html"
+ ],
+ "jsx": [
+ "./dist/middleware/jsx"
+ ],
+ "jsx/jsx-runtime": [
+ "./dist/middleware/jsx/jsx-runtime.d.ts"
+ ],
+ "jsx/jsx-dev-runtime": [
+ "./dist/middleware/jsx/jsx-dev-runtime.d.ts"
+ ],
+ "jwt": [
+ "./dist/middleware/jwt"
+ ],
+ "logger": [
+ "./dist/middleware/logger"
+ ],
+ "powered-by": [
+ "./dist/middleware/powered-by"
+ ],
+ "pretty-json": [
+ "./dist/middleware/pretty-json"
+ ],
+ "serve-static": [
+ "./dist/middleware/serve-static/index.d.ts"
+ ],
+ "serve-static.bun": [
+ "./dist/middleware/serve-static/bun.d.ts"
+ ],
+ "serve-static.module": [
+ "./dist/middleware/serve-static/module.d.mts"
+ ],
+ "router/trie-router": [
+ "./dist/router/trie-router/router.d.ts"
+ ],
+ "router/reg-exp-router": [
+ "./dist/router/reg-exp-router/router.d.ts"
+ ],
+ "utils/jwt": [
+ "./dist/utils/jwt/index.d.ts"
+ ],
+ "utils/*": [
+ "./dist/utils/*"
+ ]
+ }
+ },
+ "author": "Yusuke Wada <yusuke@kamawada.com> (https://github.com/yusukebe)",
+ "license": "MIT",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/honojs/hono.git"
+ },
+ "publishConfig": {
+ "registry": "https://registry.npmjs.org"
+ },
+ "homepage": "https://github.com/honojs/hono",
+ "keywords": [
+ "hono",
+ "web",
+ "app",
+ "http",
+ "application",
+ "framework",
+ "router",
+ "cloudflare",
+ "workers",
+ "fastly",
+ "compute@edge",
+ "deno",
+ "bun"
+ ],
+ "devDependencies": {
+ "@cloudflare/workers-types": "^3.7.1",
+ "@types/crypto-js": "^4.1.1",
+ "@types/jest": "^27.4.1",
+ "@types/node": "^17.0.29",
+ "@typescript-eslint/eslint-plugin": "^5.21.0",
+ "@typescript-eslint/parser": "^5.21.0",
+ "crypto-js": "^4.1.1",
+ "denoify": "^0.11.1",
+ "eslint": "^8.14.0",
+ "eslint-config-prettier": "^8.5.0",
+ "eslint-define-config": "^1.4.0",
+ "eslint-import-resolver-typescript": "^2.7.1",
+ "eslint-plugin-eslint-comments": "^3.2.0",
+ "eslint-plugin-flowtype": "^8.0.3",
+ "eslint-plugin-import": "^2.26.0",
+ "eslint-plugin-node": "^11.1.0",
+ "form-data": "^4.0.0",
+ "jest": "27.5.1",
+ "jest-environment-miniflare": "^2.6.0",
+ "np": "^7.6.2",
+ "prettier": "^2.6.2",
+ "rimraf": "^3.0.2",
+ "ts-jest": "^27.1.4",
+ "typescript": "^4.6.3"
+ },
+ "engines": {
+ "node": ">=11.0.0"
+ }
+}
diff --git a/tools/lint.js b/tools/lint.js
index 7bd7658b8..c1b9b3050 100755
--- a/tools/lint.js
+++ b/tools/lint.js
@@ -21,6 +21,7 @@ async function dlint() {
":!:cli/tests/testdata/038_checkjs.js",
":!:cli/tests/testdata/error_008_checkjs.js",
":!:cli/bench/http/node*.js",
+ ":!:cli/bench/testdata/npm/*",
":!:cli/bench/testdata/express-router.js",
":!:cli/bench/testdata/react-dom.js",
":!:cli/compilers/wasm_wrap.js",