// NOTE: THIS IS A FORK OF https://github.com/honojs/hono/blob/139e863aa214118397e442329121f8f39833b2f9/src/types.ts import type { Context as Context_hono } from 'hono' import type { IfAnyThenEmptyObject, RemoveBlankRecord, UnionToIntersection, } from 'hono/utils/types' import type { FrogBase, RouteOptions } from '../frog-base.js' import type { Context, FrameContext, TransactionContext } from './context.js' import type { Env } from './env.js' import type { FrameResponse } from './frame.js' import type { HandlerResponse } from './response.js' import type { TransactionResponse } from './transaction.js' //////////////////////////////////////// ////// ////// ////// Values ////// ////// ////// //////////////////////////////////////// export type Next = () => Promise export type Input = { in?: Partial out?: Partial<{ [K in keyof ValidationTargets]: unknown }> } export type BlankSchema = {} export type BlankInput = {} //////////////////////////////////////// ////// ////// ////// Handlers ////// ////// ////// //////////////////////////////////////// export type FrameHandler< E extends Env = any, P extends string = any, I extends Input = BlankInput, > = (c: FrameContext) => HandlerResponse export type TransactionHandler< E extends Env = any, P extends string = any, I extends Input = BlankInput, > = (c: TransactionContext) => HandlerResponse export type Handler< E extends Env = any, P extends string = any, I extends Input = BlankInput, R extends HandlerResponse = any, > = (c: Context) => R export type MiddlewareHandler< E extends Env = any, P extends string = string, I extends Input = {}, // biome-ignore lint/suspicious/noConfusingVoidType: > = (c: Context_hono, next: Next) => Promise export type H< E extends Env = any, P extends string = any, I extends Input = BlankInput, R extends HandlerResponse = any, M extends string = string, > = M extends 'frame' ? FrameHandler : M extends 'transaction' ? TransactionHandler : Handler //////////////////////////////////////// ////// ////// ////// HandlerInterface ////// ////// ////// //////////////////////////////////////// export interface HandlerInterface< E extends Env = Env, M extends string = string, S extends Schema = {}, BasePath extends string = '/', > { // app.get(path, handler, options) < P extends string, MergedPath extends MergePath = MergePath, R extends HandlerResponse = any, I extends Input = BlankInput, E2 extends Env = E, >( path: P, handler: H, options?: RouteOptions, ): FrogBase< E, S & ToSchema, I['in'], MergeTypedResponseData>, BasePath > // app.get(path, middleware, handler) < P extends string, MergedPath extends MergePath = MergePath, R extends HandlerResponse = any, I extends Input = BlankInput, I2 extends Input = I, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, >( path: P, middleware: MiddlewareHandler, handler: H, options?: RouteOptions, ): FrogBase< E, S & ToSchema, I2['in'], MergeTypedResponseData>, BasePath > // app.get(path, middleware x2, handler) < P extends string, MergedPath extends MergePath = MergePath, R extends HandlerResponse = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, E2 extends Env = E, E3 extends Env = E, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, >( path: P, middleware: MiddlewareHandler, middleware_2: MiddlewareHandler, handler: H, options?: RouteOptions, ): FrogBase< E, S & ToSchema, I3['in'], MergeTypedResponseData>, BasePath > // app.get(path, middleware x3, handler) < P extends string, MergedPath extends MergePath = MergePath, R extends HandlerResponse = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, >( path: P, middleware: MiddlewareHandler, middleware_2: MiddlewareHandler, middleware_3: MiddlewareHandler, handler: H, options?: RouteOptions, ): FrogBase< E, S & ToSchema, I4['in'], MergeTypedResponseData>, BasePath > // app.get(path, middleware x4, handler) < P extends string, MergedPath extends MergePath = MergePath, R extends HandlerResponse = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, >( path: P, middleware: MiddlewareHandler, middleware_2: MiddlewareHandler, middleware_3: MiddlewareHandler, middleware_4: MiddlewareHandler, handler: H, options?: RouteOptions, ): FrogBase< E, S & ToSchema, I5['in'], MergeTypedResponseData>, BasePath > // app.get(path, middleware x5, handler) < P extends string, MergedPath extends MergePath = MergePath, R extends HandlerResponse = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, >( path: P, middleware: MiddlewareHandler, middleware_2: MiddlewareHandler, middleware_3: MiddlewareHandler, middleware_4: MiddlewareHandler, middleware_5: MiddlewareHandler, handler: H, options?: RouteOptions, ): FrogBase< E, S & ToSchema, I6['in'], MergeTypedResponseData>, BasePath > // app.get(path, middleware x6, handler) < P extends string, MergedPath extends MergePath = MergePath, R extends HandlerResponse = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = E, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, >( path: P, middleware: MiddlewareHandler, middleware_2: MiddlewareHandler, middleware_3: MiddlewareHandler, middleware_4: MiddlewareHandler, middleware_5: MiddlewareHandler, middleware_6: MiddlewareHandler, handler: H, options?: RouteOptions, ): FrogBase< E, S & ToSchema, I7['in'], MergeTypedResponseData>, BasePath > // app.get(path, middleware x7, handler) < P extends string, MergedPath extends MergePath = MergePath, R extends HandlerResponse = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = E, E8 extends Env = E, E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, >( path: P, middleware: MiddlewareHandler, middleware_2: MiddlewareHandler, middleware_3: MiddlewareHandler, middleware_4: MiddlewareHandler, middleware_5: MiddlewareHandler, middleware_6: MiddlewareHandler, middleware_7: MiddlewareHandler, handler: H, options?: RouteOptions, ): FrogBase< E, S & ToSchema, I8['in'], MergeTypedResponseData>, BasePath > // app.get(path, middleware x8, handler) < P extends string, MergedPath extends MergePath = MergePath, R extends HandlerResponse = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = E, E8 extends Env = E, E9 extends Env = E, E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>, >( path: P, middleware: MiddlewareHandler, middleware_2: MiddlewareHandler, middleware_3: MiddlewareHandler, middleware_4: MiddlewareHandler, middleware_5: MiddlewareHandler, middleware_6: MiddlewareHandler, middleware_7: MiddlewareHandler, middleware_8: MiddlewareHandler, handler: H, options?: RouteOptions, ): FrogBase< E, S & ToSchema, I9['in'], MergeTypedResponseData>, BasePath > // app.get(path, middleware x9, handler) < P extends string, MergedPath extends MergePath = MergePath, R extends HandlerResponse = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, I10 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8 & I9, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = E, E8 extends Env = E, E9 extends Env = E, E10 extends Env = E, E11 extends Env = IntersectNonAnyTypes< [E, E2, E3, E4, E5, E6, E7, E8, E9, E10] >, >( path: P, middleware: MiddlewareHandler, middleware_2: MiddlewareHandler, middleware_3: MiddlewareHandler, middleware_4: MiddlewareHandler, middleware_5: MiddlewareHandler, middleware_6: MiddlewareHandler, middleware_7: MiddlewareHandler, middleware_8: MiddlewareHandler, middleware_9: MiddlewareHandler, handler: H, options?: RouteOptions, ): FrogBase< E, S & ToSchema, I10['in'], MergeTypedResponseData>, BasePath > } //////////////////////////////////////// ////// ////// ////// MiddlewareHandlerInterface ////// ////// ////// //////////////////////////////////////// export interface MiddlewareHandlerInterface< E extends Env = Env, S extends Schema = {}, BasePath extends string = '/', > { //// app.use(...handlers[]) ( ...handlers: MiddlewareHandler>>[] ): FrogBase, S, BasePath> // app.use(handler) ( handler: MiddlewareHandler>>, ): FrogBase, S, BasePath> // app.use(handler x2) < E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, P extends string = MergePath>, >( ...handlers: [MiddlewareHandler, MiddlewareHandler] ): FrogBase, S, BasePath> // app.use(handler x3) < E2 extends Env = E, E3 extends Env = E, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, P extends string = MergePath>, >( ...handlers: [ MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, ] ): FrogBase, S, BasePath> // app.use(handler x4) < E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, P extends string = MergePath>, >( ...handlers: [ MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, ] ): FrogBase, S, BasePath> // app.use(handler x5) < E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, P extends string = MergePath>, >( ...handlers: [ MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, ] ): FrogBase, S, BasePath> // app.use(handler x6) < E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, P extends string = MergePath>, >( ...handlers: [ MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, ] ): FrogBase, S, BasePath> // app.use(handler x7) < E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = E, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, P extends string = MergePath>, >( ...handlers: [ MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, ] ): FrogBase< IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, S, BasePath > // app.use(handler x8) < E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = E, E8 extends Env = E, E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, P extends string = MergePath>, >( ...handlers: [ MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, ] ): FrogBase< IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>, S, BasePath > // app.use(handler x9) < E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = E, E8 extends Env = E, E9 extends Env = E, E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>, P extends string = MergePath>, >( ...handlers: [ MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, ] ): FrogBase< IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>, S, BasePath > // app.use(handler x10) < E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = E, E8 extends Env = E, E9 extends Env = E, E10 extends Env = E, E11 extends Env = IntersectNonAnyTypes< [E, E2, E3, E4, E5, E6, E7, E8, E9, E10] >, P extends string = MergePath>, >( ...handlers: [ MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, MiddlewareHandler, ] ): FrogBase< IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11]>, S, BasePath > //// app.use(path, ...handlers[])

( path: P, ...handlers: MiddlewareHandler>[] ): FrogBase } //////////////////////////////////////// ////// ////// ////// OnHandlerInterface ////// ////// ////// //////////////////////////////////////// export interface OnHandlerInterface< E extends Env = Env, S extends Schema = {}, BasePath extends string = '/', > { // app.on(method, path, handler) < M extends string, P extends string, MergedPath extends MergePath = MergePath, R extends HandlerResponse = any, I extends Input = BlankInput, E2 extends Env = E, >( method: M, path: P, handler: H, ): FrogBase< IntersectNonAnyTypes<[E, E2]>, S & ToSchema, I['in'], MergeTypedResponseData>, BasePath > // app.on(method, path, handler x2) < M extends string, P extends string, MergedPath extends MergePath = MergePath, R extends HandlerResponse = any, I extends Input = BlankInput, I2 extends Input = I, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, >( method: M, path: P, ...handlers: [H, H] ): FrogBase< IntersectNonAnyTypes<[E, E2, E3]>, S & ToSchema, I2['in'], MergeTypedResponseData>, BasePath > // app.on(method, path, handler x3) < M extends string, P extends string, MergedPath extends MergePath = MergePath, R extends HandlerResponse = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, E2 extends Env = E, E3 extends Env = E, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, >( method: M, path: P, ...handlers: [ H, H, H, ] ): FrogBase< IntersectNonAnyTypes<[E, E2, E3, E4]>, S & ToSchema, I3['in'], MergeTypedResponseData>, BasePath > // app.on(method, path, handler x4) < M extends string, P extends string, MergedPath extends MergePath = MergePath, R extends HandlerResponse = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, >( method: M, path: P, ...handlers: [ H, H, H, H, ] ): FrogBase< IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, S & ToSchema, I4['in'], MergeTypedResponseData>, BasePath > // app.on(method, path, handler x5) < M extends string, P extends string, MergedPath extends MergePath = MergePath, R extends HandlerResponse = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, >( method: M, path: P, ...handlers: [ H, H, H, H, H, ] ): FrogBase< IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, S & ToSchema, I5['in'], MergeTypedResponseData>, BasePath > // app.on(method, path, handler x6) < M extends string, P extends string, MergedPath extends MergePath = MergePath, R extends HandlerResponse = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, >( method: M, path: P, ...handlers: [ H, H, H, H, H, H, ] ): FrogBase< IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, S & ToSchema, I6['in'], MergeTypedResponseData>, BasePath > // app.on(method, path, handler x7) < M extends string, P extends string, MergedPath extends MergePath = MergePath, R extends HandlerResponse = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = E, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, >( method: M, path: P, ...handlers: [ H, H, H, H, H, H, H, ] ): FrogBase< IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, S & ToSchema, I7['in'], MergeTypedResponseData>, BasePath > // app.on(method, path, handler x8) < M extends string, P extends string, MergedPath extends MergePath = MergePath, R extends HandlerResponse = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = E, E8 extends Env = E, E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, >( method: M, path: P, ...handlers: [ H, H, H, H, H, H, H, H, ] ): FrogBase< IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>, S & ToSchema, I8['in'], MergeTypedResponseData>, BasePath > // app.on(method, path, handler x9) < M extends string, P extends string, MergedPath extends MergePath = MergePath, R extends HandlerResponse = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = E, E8 extends Env = E, E9 extends Env = E, E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>, >( method: M, path: P, ...handlers: [ H, H, H, H, H, H, H, H, H, ] ): FrogBase< IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>, S & ToSchema, I9['in'], MergeTypedResponseData>, BasePath > // app.on(method, path, handler x10) < M extends string, P extends string, MergedPath extends MergePath = MergePath, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, I10 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8 & I9, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = E, E8 extends Env = E, E9 extends Env = E, E10 extends Env = E, E11 extends Env = IntersectNonAnyTypes< [E, E2, E3, E4, E5, E6, E7, E8, E9, E10] >, >( method: M, path: P, ...handlers: [ H, H, H, H, H, H, H, H, H, H, ] ): FrogBase< IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11]>, S & ToSchema< M, MergePath, I10['in'], MergeTypedResponseData> >, BasePath > // app.get(method, path, ...handler) < M extends string, P extends string, R extends HandlerResponse = any, I extends Input = {}, >( method: M, path: P, ...handlers: H, I, R>[] ): FrogBase< E, S & ToSchema, I['in'], MergeTypedResponseData>, BasePath > // app.get(method[], path, handler) < Ms extends string[], P extends string, MergedPath extends MergePath = MergePath, R extends HandlerResponse = any, I extends Input = BlankInput, E2 extends Env = E, >( methods: Ms, path: P, handler: H, ): FrogBase< IntersectNonAnyTypes<[E, E2]>, S & ToSchema< Ms[number], MergePath, I['in'], MergeTypedResponseData >, BasePath > // app.get(method[], path, handler x2) < Ms extends string[], P extends string, MergedPath extends MergePath = MergePath, R extends HandlerResponse = any, I extends Input = BlankInput, I2 extends Input = I, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, >( methods: Ms, path: P, ...handlers: [H, H] ): FrogBase< IntersectNonAnyTypes<[E, E2, E3]>, S & ToSchema< Ms[number], MergePath, I2['in'], MergeTypedResponseData >, BasePath > // app.get(method[], path, handler x3) < Ms extends string[], P extends string, MergedPath extends MergePath = MergePath, R extends HandlerResponse = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, E2 extends Env = E, E3 extends Env = E, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, >( methods: Ms, path: P, ...handlers: [ H, H, H, ] ): FrogBase< IntersectNonAnyTypes<[E, E2, E3, E4]>, S & ToSchema< Ms[number], MergePath, I3['in'], MergeTypedResponseData >, BasePath > // app.get(method[], path, handler x4) < Ms extends string[], P extends string, MergedPath extends MergePath = MergePath, R extends HandlerResponse = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, >( methods: Ms, path: P, ...handlers: [ H, H, H, H, ] ): FrogBase< IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, S & ToSchema< Ms[number], MergePath, I4['in'], MergeTypedResponseData >, BasePath > // app.get(method[], path, handler x5) < Ms extends string[], P extends string, MergedPath extends MergePath = MergePath, R extends HandlerResponse = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, >( methods: Ms, path: P, ...handlers: [ H, H, H, H, H, ] ): FrogBase< IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, S & ToSchema< Ms[number], MergePath, I5['in'], MergeTypedResponseData >, BasePath > // app.get(method[], path, handler x6) < Ms extends string[], P extends string, MergedPath extends MergePath = MergePath, R extends HandlerResponse = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, >( methods: Ms, path: P, ...handlers: [ H, H, H, H, H, H, ] ): FrogBase< IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, S & ToSchema< Ms[number], MergePath, I6['in'], MergeTypedResponseData >, BasePath > // app.get(method[], path, handler x7) < Ms extends string[], P extends string, MergedPath extends MergePath = MergePath, R extends HandlerResponse = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = E, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, >( methods: Ms, path: P, ...handlers: [ H, H, H, H, H, H, H, ] ): FrogBase< IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, S & ToSchema< Ms[number], MergePath, I7['in'], MergeTypedResponseData >, BasePath > // app.get(method[], path, handler x8) < Ms extends string[], P extends string, MergedPath extends MergePath = MergePath, R extends HandlerResponse = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = E, E8 extends Env = E, E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, >( methods: Ms, path: P, ...handlers: [ H, H, H, H, H, H, H, H, ] ): FrogBase< IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>, S & ToSchema< Ms[number], MergePath, I8['in'], MergeTypedResponseData >, BasePath > // app.get(method[], path, handler x9) < Ms extends string[], P extends string, MergedPath extends MergePath = MergePath, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = E, E8 extends Env = E, E9 extends Env = E, E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>, >( methods: Ms, path: P, ...handlers: [ H, H, H, H, H, H, H, H, H, ] ): FrogBase< IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>, S & ToSchema< Ms[number], MergePath, I9['in'], MergeTypedResponseData> >, BasePath > // app.get(method[], path, handler x10) < Ms extends string[], P extends string, MergedPath extends MergePath = MergePath, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, I10 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8 & I9, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, E7 extends Env = E, E8 extends Env = E, E9 extends Env = E, E10 extends Env = E, E11 extends Env = IntersectNonAnyTypes< [E, E2, E3, E4, E5, E6, E7, E8, E9, E10] >, >( methods: Ms, path: P, ...handlers: [ H, H, H, H, H, H, H, H, H, H, ] ): FrogBase< IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11]>, S & ToSchema< Ms[number], MergePath, I10['in'], MergeTypedResponseData> >, BasePath > // app.on(method[], path, ...handler) < P extends string, R extends HandlerResponse = any, I extends Input = {}, >( methods: string[], path: P, ...handlers: H, I, R>[] ): FrogBase< E, S & ToSchema< string, MergePath, I['in'], MergeTypedResponseData >, BasePath > // app.on(method | method[], path[], ...handlers[]) = any>( methods: string | string[], paths: string[], ...handlers: H[] ): FrogBase< E, S & ToSchema>, BasePath > } type ExtractKey = S extends Record ? Key extends string ? Key : never : string //////////////////////////////////////// ////// ////// ////// ToSchema ////// ////// ////// //////////////////////////////////////// export type ToSchema< M extends string, P extends string, I extends Input['in'], O, > = { [K in P]: { [K2 in M as AddDollar]: { input: unknown extends I ? AddParam<{}, P> : AddParam output: unknown extends O ? {} : O } } } export type Schema = { [Path: string]: { [Method: `$${Lowercase}`]: { input: Partial & { param?: Record } output: any } } } type ExtractParams = string extends Path ? Record : Path extends `${infer _Start}:${infer Param}/${infer Rest}` ? { [K in Param | keyof ExtractParams<`/${Rest}`>]: string } : Path extends `${infer _Start}:${infer Param}` ? { [K in Param]: string } : never type FlattenIfIntersect = T extends infer O ? { [K in keyof O]: O[K] } : never export type MergeSchemaPath< OrigSchema extends Schema, SubPath extends string, > = { [P in keyof OrigSchema as MergePath]: { [M in keyof OrigSchema[P]]: OrigSchema[P][M] extends { input: infer Input output: infer Output } ? { input: Input extends { param: infer _ } ? ExtractParams extends never ? Input : FlattenIfIntersect }> : RemoveBlankRecord> extends never ? Input : Input & { param: ExtractParams } output: Output } : never } } export type AddParam = ParamKeys

extends never ? I : I extends { param: infer _ } ? I : I & { param: UnionToIntersection>> } type AddDollar = `$${Lowercase}` export type MergePath = A extends '' ? B : A extends '/' ? B : A extends `${infer P}/` ? B extends `/${infer Q}` ? `${P}/${Q}` : `${P}/${B}` : B extends `/${infer Q}` ? Q extends '' ? A : `${A}/${Q}` : `${A}/${B}` //////////////////////////////////////// ////// ////// ////// TypedResponse ////// ////// ////// //////////////////////////////////////// export type TypedResponse = { data: T format: 'json' // Currently, support only `json` with `c.jsonT()` } type ExtractResponseData = T extends Promise ? T2 extends TypedResponse ? U : {} : T extends TypedResponse ? U : {} type MergeTypedResponseData = ExtractResponseData //////////////////////////////////////// ////// ///// ////// ValidationTargets ///// ////// ///// //////////////////////////////////////// export type ValidationTargets = { json: any form: Record query: Record param: Record header: Record cookie: Record } //////////////////////////////////////// ////// ////// ////// Path parameters ////// ////// ////// //////////////////////////////////////// type ParamKeyName = NameWithPattern extends `${infer Name}{${infer Rest}` ? Rest extends `${infer _Pattern}?` ? `${Name}?` : Name : NameWithPattern type ParamKey = Component extends `:${infer NameWithPattern}` ? ParamKeyName : never export type ParamKeys = Path extends `${infer Component}/${infer Rest}` ? ParamKey | ParamKeys : ParamKey export type ParamKeyToRecord = T extends `${infer R}?` ? Record : { [K in T]: string } //////////////////////////////////////// ////// ////// ///// For HonoRequest ////// ////// ////// //////////////////////////////////////// export type InputToDataByTarget< T extends Input['out'], Target extends keyof ValidationTargets, > = T extends { [K in Target]: infer R } ? R : never export type RemoveQuestion = T extends `${infer R}?` ? R : T export type UndefinedIfHavingQuestion = T extends `${infer _}?` ? string | undefined : string //////////////////////////////////////// ////// ////// ////// Utilities ////// ////// ////// //////////////////////////////////////// export type ExtractSchema = UnionToIntersection< T extends FrogBase ? S : never > type EnvOrEmpty = T extends Env ? (Env extends T ? {} : T) : T type IntersectNonAnyTypes = T extends [ infer Head, ...infer Rest, ] ? IfAnyThenEmptyObject> & IntersectNonAnyTypes : {}