Buckets:
| // src/hono-base.ts | |
| import { compose } from "./compose.js"; | |
| import { Context } from "./context.js"; | |
| import { METHODS, METHOD_NAME_ALL, METHOD_NAME_ALL_LOWERCASE } from "./router.js"; | |
| import { COMPOSED_HANDLER } from "./utils/constants.js"; | |
| import { getPath, getPathNoStrict, mergePath } from "./utils/url.js"; | |
| var notFoundHandler = (c) => { | |
| return c.text("404 Not Found", 404); | |
| }; | |
| var 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); | |
| }; | |
| var Hono = 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 = [...METHODS, 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(METHOD_NAME_ALL, this.#path, handler); | |
| }); | |
| return this; | |
| }; | |
| const { strict, ...optionsWithoutStrict } = options; | |
| Object.assign(this, optionsWithoutStrict); | |
| this.getPath = strict ?? true ? options.getPath ?? getPath : 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 compose([], app.errorHandler)(c, () => r.handler(c, next))).res; | |
| handler[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 = 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 = 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(METHOD_NAME_ALL, mergePath(path, "*"), handler); | |
| return this; | |
| } | |
| #addRoute(method, path, handler) { | |
| method = method.toUpperCase(); | |
| path = 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 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 = 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${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)); | |
| }); | |
| }; | |
| }; | |
| export { | |
| Hono as HonoBase | |
| }; | |
Xet Storage Details
- Size:
- 11.3 kB
- Xet hash:
- eaaa8c2c98ccf5d73f793c6c5996a426a2db61ce08006f68068b5c3dcbd047fd
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.