| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400 |
- var __defProp = Object.defineProperty;
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
- var __getOwnPropNames = Object.getOwnPropertyNames;
- var __hasOwnProp = Object.prototype.hasOwnProperty;
- var __export = (target, all) => {
- for (var name in all)
- __defProp(target, name, { get: all[name], enumerable: true });
- };
- var __copyProps = (to, from, except, desc) => {
- if (from && typeof from === "object" || typeof from === "function") {
- for (let key of __getOwnPropNames(from))
- if (!__hasOwnProp.call(to, key) && key !== except)
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
- }
- return to;
- };
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
- var hono_base_exports = {};
- __export(hono_base_exports, {
- HonoBase: () => Hono
- });
- module.exports = __toCommonJS(hono_base_exports);
- var import_compose = require("./compose");
- var import_context = require("./context");
- var import_router = require("./router");
- var import_constants = require("./utils/constants");
- var import_url = require("./utils/url");
- const notFoundHandler = (c) => {
- return c.text("404 Not Found", 404);
- };
- const errorHandler = (err, c) => {
- if ("getResponse" in err) {
- const res = err.getResponse();
- return c.newResponse(res.body, res);
- }
- console.error(err);
- return c.text("Internal Server Error", 500);
- };
- class Hono {
- get;
- post;
- put;
- delete;
- options;
- patch;
- all;
- on;
- use;
- /*
- This class is like an abstract class and does not have a router.
- To use it, inherit the class and implement router in the constructor.
- */
- router;
- getPath;
- // Cannot use `#` because it requires visibility at JavaScript runtime.
- _basePath = "/";
- #path = "/";
- routes = [];
- constructor(options = {}) {
- const allMethods = [...import_router.METHODS, import_router.METHOD_NAME_ALL_LOWERCASE];
- allMethods.forEach((method) => {
- this[method] = (args1, ...args) => {
- if (typeof args1 === "string") {
- this.#path = args1;
- } else {
- this.#addRoute(method, this.#path, args1);
- }
- args.forEach((handler) => {
- this.#addRoute(method, this.#path, handler);
- });
- return this;
- };
- });
- this.on = (method, path, ...handlers) => {
- for (const p of [path].flat()) {
- this.#path = p;
- for (const m of [method].flat()) {
- handlers.map((handler) => {
- this.#addRoute(m.toUpperCase(), this.#path, handler);
- });
- }
- }
- return this;
- };
- this.use = (arg1, ...handlers) => {
- if (typeof arg1 === "string") {
- this.#path = arg1;
- } else {
- this.#path = "*";
- handlers.unshift(arg1);
- }
- handlers.forEach((handler) => {
- this.#addRoute(import_router.METHOD_NAME_ALL, this.#path, handler);
- });
- return this;
- };
- const { strict, ...optionsWithoutStrict } = options;
- Object.assign(this, optionsWithoutStrict);
- this.getPath = strict ?? true ? options.getPath ?? import_url.getPath : import_url.getPathNoStrict;
- }
- #clone() {
- const clone = new Hono({
- router: this.router,
- getPath: this.getPath
- });
- clone.errorHandler = this.errorHandler;
- clone.#notFoundHandler = this.#notFoundHandler;
- clone.routes = this.routes;
- return clone;
- }
- #notFoundHandler = notFoundHandler;
- // Cannot use `#` because it requires visibility at JavaScript runtime.
- errorHandler = errorHandler;
- /**
- * `.route()` allows grouping other Hono instance in routes.
- *
- * @see {@link https://hono.dev/docs/api/routing#grouping}
- *
- * @param {string} path - base Path
- * @param {Hono} app - other Hono instance
- * @returns {Hono} routed Hono instance
- *
- * @example
- * ```ts
- * const app = new Hono()
- * const app2 = new Hono()
- *
- * app2.get("/user", (c) => c.text("user"))
- * app.route("/api", app2) // GET /api/user
- * ```
- */
- route(path, app) {
- const subApp = this.basePath(path);
- app.routes.map((r) => {
- let handler;
- if (app.errorHandler === errorHandler) {
- handler = r.handler;
- } else {
- handler = async (c, next) => (await (0, import_compose.compose)([], app.errorHandler)(c, () => r.handler(c, next))).res;
- handler[import_constants.COMPOSED_HANDLER] = r.handler;
- }
- subApp.#addRoute(r.method, r.path, handler);
- });
- return this;
- }
- /**
- * `.basePath()` allows base paths to be specified.
- *
- * @see {@link https://hono.dev/docs/api/routing#base-path}
- *
- * @param {string} path - base Path
- * @returns {Hono} changed Hono instance
- *
- * @example
- * ```ts
- * const api = new Hono().basePath('/api')
- * ```
- */
- basePath(path) {
- const subApp = this.#clone();
- subApp._basePath = (0, import_url.mergePath)(this._basePath, path);
- return subApp;
- }
- /**
- * `.onError()` handles an error and returns a customized Response.
- *
- * @see {@link https://hono.dev/docs/api/hono#error-handling}
- *
- * @param {ErrorHandler} handler - request Handler for error
- * @returns {Hono} changed Hono instance
- *
- * @example
- * ```ts
- * app.onError((err, c) => {
- * console.error(`${err}`)
- * return c.text('Custom Error Message', 500)
- * })
- * ```
- */
- onError = (handler) => {
- this.errorHandler = handler;
- return this;
- };
- /**
- * `.notFound()` allows you to customize a Not Found Response.
- *
- * @see {@link https://hono.dev/docs/api/hono#not-found}
- *
- * @param {NotFoundHandler} handler - request handler for not-found
- * @returns {Hono} changed Hono instance
- *
- * @example
- * ```ts
- * app.notFound((c) => {
- * return c.text('Custom 404 Message', 404)
- * })
- * ```
- */
- notFound = (handler) => {
- this.#notFoundHandler = handler;
- return this;
- };
- /**
- * `.mount()` allows you to mount applications built with other frameworks into your Hono application.
- *
- * @see {@link https://hono.dev/docs/api/hono#mount}
- *
- * @param {string} path - base Path
- * @param {Function} applicationHandler - other Request Handler
- * @param {MountOptions} [options] - options of `.mount()`
- * @returns {Hono} mounted Hono instance
- *
- * @example
- * ```ts
- * import { Router as IttyRouter } from 'itty-router'
- * import { Hono } from 'hono'
- * // Create itty-router application
- * const ittyRouter = IttyRouter()
- * // GET /itty-router/hello
- * ittyRouter.get('/hello', () => new Response('Hello from itty-router'))
- *
- * const app = new Hono()
- * app.mount('/itty-router', ittyRouter.handle)
- * ```
- *
- * @example
- * ```ts
- * const app = new Hono()
- * // Send the request to another application without modification.
- * app.mount('/app', anotherApp, {
- * replaceRequest: (req) => req,
- * })
- * ```
- */
- mount(path, applicationHandler, options) {
- let replaceRequest;
- let optionHandler;
- if (options) {
- if (typeof options === "function") {
- optionHandler = options;
- } else {
- optionHandler = options.optionHandler;
- if (options.replaceRequest === false) {
- replaceRequest = (request) => request;
- } else {
- replaceRequest = options.replaceRequest;
- }
- }
- }
- const getOptions = optionHandler ? (c) => {
- const options2 = optionHandler(c);
- return Array.isArray(options2) ? options2 : [options2];
- } : (c) => {
- let executionContext = void 0;
- try {
- executionContext = c.executionCtx;
- } catch {
- }
- return [c.env, executionContext];
- };
- replaceRequest ||= (() => {
- const mergedPath = (0, import_url.mergePath)(this._basePath, path);
- const pathPrefixLength = mergedPath === "/" ? 0 : mergedPath.length;
- return (request) => {
- const url = new URL(request.url);
- url.pathname = url.pathname.slice(pathPrefixLength) || "/";
- return new Request(url, request);
- };
- })();
- const handler = async (c, next) => {
- const res = await applicationHandler(replaceRequest(c.req.raw), ...getOptions(c));
- if (res) {
- return res;
- }
- await next();
- };
- this.#addRoute(import_router.METHOD_NAME_ALL, (0, import_url.mergePath)(path, "*"), handler);
- return this;
- }
- #addRoute(method, path, handler) {
- method = method.toUpperCase();
- path = (0, import_url.mergePath)(this._basePath, path);
- const r = { basePath: this._basePath, path, method, handler };
- this.router.add(method, path, [handler, r]);
- this.routes.push(r);
- }
- #handleError(err, c) {
- if (err instanceof Error) {
- return this.errorHandler(err, c);
- }
- throw err;
- }
- #dispatch(request, executionCtx, env, method) {
- if (method === "HEAD") {
- return (async () => new Response(null, await this.#dispatch(request, executionCtx, env, "GET")))();
- }
- const path = this.getPath(request, { env });
- const matchResult = this.router.match(method, path);
- const c = new import_context.Context(request, {
- path,
- matchResult,
- env,
- executionCtx,
- notFoundHandler: this.#notFoundHandler
- });
- if (matchResult[0].length === 1) {
- let res;
- try {
- res = matchResult[0][0][0][0](c, async () => {
- c.res = await this.#notFoundHandler(c);
- });
- } catch (err) {
- return this.#handleError(err, c);
- }
- return res instanceof Promise ? res.then(
- (resolved) => resolved || (c.finalized ? c.res : this.#notFoundHandler(c))
- ).catch((err) => this.#handleError(err, c)) : res ?? this.#notFoundHandler(c);
- }
- const composed = (0, import_compose.compose)(matchResult[0], this.errorHandler, this.#notFoundHandler);
- return (async () => {
- try {
- const context = await composed(c);
- if (!context.finalized) {
- throw new Error(
- "Context is not finalized. Did you forget to return a Response object or `await next()`?"
- );
- }
- return context.res;
- } catch (err) {
- return this.#handleError(err, c);
- }
- })();
- }
- /**
- * `.fetch()` will be entry point of your app.
- *
- * @see {@link https://hono.dev/docs/api/hono#fetch}
- *
- * @param {Request} request - request Object of request
- * @param {Env} Env - env Object
- * @param {ExecutionContext} - context of execution
- * @returns {Response | Promise<Response>} response of request
- *
- */
- fetch = (request, ...rest) => {
- return this.#dispatch(request, rest[1], rest[0], request.method);
- };
- /**
- * `.request()` is a useful method for testing.
- * You can pass a URL or pathname to send a GET request.
- * app will return a Response object.
- * ```ts
- * test('GET /hello is ok', async () => {
- * const res = await app.request('/hello')
- * expect(res.status).toBe(200)
- * })
- * ```
- * @see https://hono.dev/docs/api/hono#request
- */
- request = (input, requestInit, Env, executionCtx) => {
- if (input instanceof Request) {
- return this.fetch(requestInit ? new Request(input, requestInit) : input, Env, executionCtx);
- }
- input = input.toString();
- return this.fetch(
- new Request(
- /^https?:\/\//.test(input) ? input : `http://localhost${(0, import_url.mergePath)("/", input)}`,
- requestInit
- ),
- Env,
- executionCtx
- );
- };
- /**
- * `.fire()` automatically adds a global fetch event listener.
- * This can be useful for environments that adhere to the Service Worker API, such as non-ES module Cloudflare Workers.
- * @deprecated
- * Use `fire` from `hono/service-worker` instead.
- * ```ts
- * import { Hono } from 'hono'
- * import { fire } from 'hono/service-worker'
- *
- * const app = new Hono()
- * // ...
- * fire(app)
- * ```
- * @see https://hono.dev/docs/api/hono#fire
- * @see https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
- * @see https://developers.cloudflare.com/workers/reference/migrate-to-module-workers/
- */
- fire = () => {
- addEventListener("fetch", (event) => {
- event.respondWith(this.#dispatch(event.request, event, void 0, event.request.method));
- });
- };
- }
- // Annotate the CommonJS export names for ESM import in node:
- 0 && (module.exports = {
- HonoBase
- });
|