frog
Version:
1,688 lines (1,595 loc) • 48.8 kB
text/typescript
// 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 { StatusCode } from 'hono/utils/http-status'
import type {
IfAnyThenEmptyObject,
RemoveBlankRecord,
UnionToIntersection,
} from 'hono/utils/types'
import type { FrogBase, RouteOptions } from '../frog-base.js'
import type { CastActionResponse } from './castAction.js'
import type { ComposerActionResponse } from './composerAction.js'
import type {
CastActionContext,
ComposerActionContext,
FrameBaseContext,
FrameContext,
ImageContext,
SignatureContext,
TransactionContext,
} from './context.js'
import type { Env } from './env.js'
import type { FrameResponse } from './frame.js'
import type { ImageResponse } from './image.js'
import type { HandlerResponse } from './response.js'
import type { SignatureResponse } from './signature.js'
import type { TransactionResponse } from './transaction.js'
////////////////////////////////////////
////// //////
////// Values //////
////// //////
////////////////////////////////////////
export type Next = () => Promise<void>
export type Input = {
in?: Partial<ValidationTargets>
out?: Partial<{ [K in keyof ValidationTargets]: unknown }>
}
export type BlankSchema = {}
export type BlankInput = {}
////////////////////////////////////////
////// //////
////// Handlers //////
////// //////
////////////////////////////////////////
export type CastActionHandler<
E extends Env = any,
P extends string = any,
I extends Input = BlankInput,
> = (c: CastActionContext<E, P, I>) => HandlerResponse<CastActionResponse>
export type ComposerActionHandler<
E extends Env = any,
P extends string = any,
I extends Input = BlankInput,
> = (
c: ComposerActionContext<E, P, I>,
) => HandlerResponse<ComposerActionResponse>
export type FrameHandler<
E extends Env = any,
P extends string = any,
I extends Input = BlankInput,
> = (c: FrameContext<E, P, I>) => HandlerResponse<FrameResponse>
export type ImageHandler<
E extends Env = any,
P extends string = any,
I extends Input = BlankInput,
> = (c: ImageContext<E, P, I>) => HandlerResponse<ImageResponse>
export type TransactionHandler<
E extends Env = any,
P extends string = any,
I extends Input = BlankInput,
> = (c: TransactionContext<E, P, I>) => HandlerResponse<TransactionResponse>
export type SignatureHandler<
E extends Env = any,
P extends string = any,
I extends Input = BlankInput,
> = (c: SignatureContext<E, P, I>) => HandlerResponse<SignatureResponse>
export type Handler<
E extends Env = any,
P extends string = any,
I extends Input = BlankInput,
R extends HandlerResponse<any> = any,
> = (c: FrameBaseContext<E, P, I>) => R
export type MiddlewareHandler<
E extends Env = any,
P extends string = string,
I extends Input = {},
// biome-ignore lint/suspicious/noConfusingVoidType:
> = (c: Context_hono<E, P, I>, next: Next) => Promise<Response | void>
export type H<
E extends Env = any,
P extends string = any,
I extends Input = BlankInput,
R extends HandlerResponse<any> = any,
M extends string = string,
> = M extends 'frame'
? FrameHandler<E, P, I>
: M extends 'transaction'
? TransactionHandler<E, P, I>
: M extends 'castAction'
? CastActionHandler<E, P, I>
: M extends 'composerAction'
? ComposerActionHandler<E, P, I>
: M extends 'image'
? ImageHandler<E, P, I>
: M extends 'signature'
? SignatureHandler<E, P, I>
: Handler<E, P, I, R>
////////////////////////////////////////
////// //////
////// HandlerInterface //////
////// //////
////////////////////////////////////////
export type 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<BasePath, P> = MergePath<BasePath, P>,
R extends HandlerResponse<any> = any,
I extends Input = BlankInput,
E2 extends Env = E,
>(
path: P,
handler: H<E2, MergedPath, I, R, M>,
...rest: M extends 'castAction' | 'composerAction'
? [options: RouteOptions<M, E2, MergedPath, I>]
: [options?: RouteOptions<M>]
): FrogBase<
E,
S & ToSchema<M, MergePath<BasePath, P>, I['in'], MergeTypedResponseData<R>>,
BasePath
>
// app.get(path, middleware, handler)
<
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
R extends HandlerResponse<any> = any,
I extends Input = BlankInput,
I2 extends Input = I,
E2 extends Env = E,
E3 extends Env = IntersectNonAnyTypes<[E, E2]>,
>(
path: P,
middleware: MiddlewareHandler<E2, MergedPath, I>,
handler: H<E3, MergedPath, I2, R, M>,
...rest: M extends 'castAction' | 'composerAction'
? [options: RouteOptions<M, E2, MergedPath, I>]
: [options?: RouteOptions<M>]
): FrogBase<
E,
S &
ToSchema<M, MergePath<BasePath, P>, I2['in'], MergeTypedResponseData<R>>,
BasePath
>
// app.get(path, middleware x2, handler)
<
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
R extends HandlerResponse<any> = 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<E2, MergedPath, I>,
middleware_2: MiddlewareHandler<E3, MergedPath, I2>,
handler: H<E4, MergedPath, I3, R, M>,
...rest: M extends 'castAction' | 'composerAction'
? [options: RouteOptions<M, E2, MergedPath, I>]
: [options?: RouteOptions<M>]
): FrogBase<
E,
S &
ToSchema<M, MergePath<BasePath, P>, I3['in'], MergeTypedResponseData<R>>,
BasePath
>
// app.get(path, middleware x3, handler)
<
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
R extends HandlerResponse<any> = 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<E2, MergedPath, I>,
middleware_2: MiddlewareHandler<E3, MergedPath, I2>,
middleware_3: MiddlewareHandler<E4, MergedPath, I3>,
handler: H<E5, MergedPath, I4, R, M>,
...rest: M extends 'castAction' | 'composerAction'
? [options: RouteOptions<M, E2, MergedPath, I>]
: [options?: RouteOptions<M>]
): FrogBase<
E,
S &
ToSchema<M, MergePath<BasePath, P>, I4['in'], MergeTypedResponseData<R>>,
BasePath
>
// app.get(path, middleware x4, handler)
<
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
R extends HandlerResponse<any> = 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<E2, MergedPath, I>,
middleware_2: MiddlewareHandler<E3, MergedPath, I2>,
middleware_3: MiddlewareHandler<E4, MergedPath, I3>,
middleware_4: MiddlewareHandler<E5, MergedPath, I4>,
handler: H<E6, MergedPath, I5, R, M>,
...rest: M extends 'castAction' | 'composerAction'
? [options: RouteOptions<M, E2, MergedPath, I>]
: [options?: RouteOptions<M>]
): FrogBase<
E,
S &
ToSchema<M, MergePath<BasePath, P>, I5['in'], MergeTypedResponseData<R>>,
BasePath
>
// app.get(path, middleware x5, handler)
<
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
R extends HandlerResponse<any> = 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<E2, MergedPath, I>,
middleware_2: MiddlewareHandler<E3, MergedPath, I2>,
middleware_3: MiddlewareHandler<E4, MergedPath, I3>,
middleware_4: MiddlewareHandler<E5, MergedPath, I4>,
middleware_5: MiddlewareHandler<E6, MergedPath, I5>,
handler: H<E7, MergedPath, I6, R, M>,
...rest: M extends 'castAction' | 'composerAction'
? [options: RouteOptions<M, E2, MergedPath, I>]
: [options?: RouteOptions<M>]
): FrogBase<
E,
S &
ToSchema<M, MergePath<BasePath, P>, I6['in'], MergeTypedResponseData<R>>,
BasePath
>
// app.get(path, middleware x6, handler)
<
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
R extends HandlerResponse<any> = 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<E2, MergedPath, I>,
middleware_2: MiddlewareHandler<E3, MergedPath, I2>,
middleware_3: MiddlewareHandler<E4, MergedPath, I3>,
middleware_4: MiddlewareHandler<E5, MergedPath, I4>,
middleware_5: MiddlewareHandler<E6, MergedPath, I5>,
middleware_6: MiddlewareHandler<E7, MergedPath, I6>,
handler: H<E8, MergedPath, I7, R, M>,
...rest: M extends 'castAction' | 'composerAction'
? [options: RouteOptions<M, E2, MergedPath, I>]
: [options?: RouteOptions<M>]
): FrogBase<
E,
S &
ToSchema<M, MergePath<BasePath, P>, I7['in'], MergeTypedResponseData<R>>,
BasePath
>
// app.get(path, middleware x7, handler)
<
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
R extends HandlerResponse<any> = 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<E2, MergedPath, I>,
middleware_2: MiddlewareHandler<E3, MergedPath, I2>,
middleware_3: MiddlewareHandler<E4, MergedPath, I3>,
middleware_4: MiddlewareHandler<E5, MergedPath, I4>,
middleware_5: MiddlewareHandler<E6, MergedPath, I5>,
middleware_6: MiddlewareHandler<E7, MergedPath, I6>,
middleware_7: MiddlewareHandler<E8, MergedPath, I7>,
handler: H<E9, MergedPath, I8, R, M>,
...rest: M extends 'castAction' | 'composerAction'
? [options: RouteOptions<M, E2, MergedPath, I>]
: [options?: RouteOptions<M>]
): FrogBase<
E,
S &
ToSchema<M, MergePath<BasePath, P>, I8['in'], MergeTypedResponseData<R>>,
BasePath
>
// app.get(path, middleware x8, handler)
<
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
R extends HandlerResponse<any> = 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<E2, MergedPath, I>,
middleware_2: MiddlewareHandler<E3, MergedPath, I2>,
middleware_3: MiddlewareHandler<E4, MergedPath, I3>,
middleware_4: MiddlewareHandler<E5, MergedPath, I4>,
middleware_5: MiddlewareHandler<E6, MergedPath, I5>,
middleware_6: MiddlewareHandler<E7, MergedPath, I6>,
middleware_7: MiddlewareHandler<E8, MergedPath, I7>,
middleware_8: MiddlewareHandler<E9, MergedPath, I8>,
handler: H<E10, MergedPath, I9, R, M>,
...rest: M extends 'castAction' | 'composerAction'
? [options: RouteOptions<M, E2, MergedPath, I>]
: [options?: RouteOptions<M>]
): FrogBase<
E,
S &
ToSchema<M, MergePath<BasePath, P>, I9['in'], MergeTypedResponseData<R>>,
BasePath
>
// app.get(path, middleware x9, handler)
<
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
R extends HandlerResponse<any> = 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<E2, MergedPath, I>,
middleware_2: MiddlewareHandler<E3, MergedPath, I2>,
middleware_3: MiddlewareHandler<E4, MergedPath, I3>,
middleware_4: MiddlewareHandler<E5, MergedPath, I4>,
middleware_5: MiddlewareHandler<E6, MergedPath, I5>,
middleware_6: MiddlewareHandler<E7, MergedPath, I6>,
middleware_7: MiddlewareHandler<E8, MergedPath, I7>,
middleware_8: MiddlewareHandler<E9, MergedPath, I8>,
middleware_9: MiddlewareHandler<E10, MergedPath, I9>,
handler: H<E11, MergedPath, I10, R, M>,
...rest: M extends 'castAction' | 'composerAction'
? [options: RouteOptions<M, E2, MergedPath, I>]
: [options?: RouteOptions<M>]
): FrogBase<
E,
S &
ToSchema<M, MergePath<BasePath, P>, I10['in'], MergeTypedResponseData<R>>,
BasePath
>
}
////////////////////////////////////////
////// //////
////// MiddlewareHandlerInterface //////
////// //////
////////////////////////////////////////
export interface MiddlewareHandlerInterface<
E extends Env = Env,
S extends Schema = {},
BasePath extends string = '/',
> {
//// app.use(...handlers[])
<E2 extends Env = E>(
...handlers: MiddlewareHandler<E2, MergePath<BasePath, ExtractKey<S>>>[]
): FrogBase<IntersectNonAnyTypes<[E, E2]>, S, BasePath>
// app.use(handler)
<E2 extends Env = E>(
handler: MiddlewareHandler<E2, MergePath<BasePath, ExtractKey<S>>>,
): FrogBase<IntersectNonAnyTypes<[E, E2]>, S, BasePath>
// app.use(handler x2)
<
E2 extends Env = E,
E3 extends Env = IntersectNonAnyTypes<[E, E2]>,
P extends string = MergePath<BasePath, ExtractKey<S>>,
>(
...handlers: [MiddlewareHandler<E2, P>, MiddlewareHandler<E3, P>]
): FrogBase<IntersectNonAnyTypes<[E, E2, E3]>, 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<BasePath, ExtractKey<S>>,
>(
...handlers: [
MiddlewareHandler<E2, P>,
MiddlewareHandler<E3, P>,
MiddlewareHandler<E4, P>,
]
): FrogBase<IntersectNonAnyTypes<[E, E2, E3, E4]>, 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<BasePath, ExtractKey<S>>,
>(
...handlers: [
MiddlewareHandler<E2, P>,
MiddlewareHandler<E3, P>,
MiddlewareHandler<E4, P>,
MiddlewareHandler<E5, P>,
]
): FrogBase<IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, 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<BasePath, ExtractKey<S>>,
>(
...handlers: [
MiddlewareHandler<E2, P>,
MiddlewareHandler<E3, P>,
MiddlewareHandler<E4, P>,
MiddlewareHandler<E5, P>,
MiddlewareHandler<E6, P>,
]
): FrogBase<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, 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<BasePath, ExtractKey<S>>,
>(
...handlers: [
MiddlewareHandler<E2, P>,
MiddlewareHandler<E3, P>,
MiddlewareHandler<E4, P>,
MiddlewareHandler<E5, P>,
MiddlewareHandler<E6, P>,
MiddlewareHandler<E7, P>,
]
): FrogBase<IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, 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<BasePath, ExtractKey<S>>,
>(
...handlers: [
MiddlewareHandler<E2, P>,
MiddlewareHandler<E3, P>,
MiddlewareHandler<E4, P>,
MiddlewareHandler<E5, P>,
MiddlewareHandler<E6, P>,
MiddlewareHandler<E7, P>,
MiddlewareHandler<E8, P>,
]
): 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<BasePath, ExtractKey<S>>,
>(
...handlers: [
MiddlewareHandler<E2, P>,
MiddlewareHandler<E3, P>,
MiddlewareHandler<E4, P>,
MiddlewareHandler<E5, P>,
MiddlewareHandler<E6, P>,
MiddlewareHandler<E7, P>,
MiddlewareHandler<E8, P>,
MiddlewareHandler<E9, P>,
]
): 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<BasePath, ExtractKey<S>>,
>(
...handlers: [
MiddlewareHandler<E2, P>,
MiddlewareHandler<E3, P>,
MiddlewareHandler<E4, P>,
MiddlewareHandler<E5, P>,
MiddlewareHandler<E6, P>,
MiddlewareHandler<E7, P>,
MiddlewareHandler<E8, P>,
MiddlewareHandler<E9, P>,
MiddlewareHandler<E10, P>,
]
): 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<BasePath, ExtractKey<S>>,
>(
...handlers: [
MiddlewareHandler<E2, P>,
MiddlewareHandler<E3, P>,
MiddlewareHandler<E4, P>,
MiddlewareHandler<E5, P>,
MiddlewareHandler<E6, P>,
MiddlewareHandler<E7, P>,
MiddlewareHandler<E8, P>,
MiddlewareHandler<E9, P>,
MiddlewareHandler<E10, P>,
MiddlewareHandler<E11, P>,
]
): FrogBase<
IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11]>,
S,
BasePath
>
//// app.use(path, ...handlers[])
<P extends string, E2 extends Env = E>(
path: P,
...handlers: MiddlewareHandler<E2, MergePath<BasePath, P>>[]
): FrogBase<E, S, BasePath>
}
////////////////////////////////////////
////// //////
////// 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<BasePath, P> = MergePath<BasePath, P>,
R extends HandlerResponse<any> = any,
I extends Input = BlankInput,
E2 extends Env = E,
>(
method: M,
path: P,
handler: H<E2, MergedPath, I, R>,
): FrogBase<
IntersectNonAnyTypes<[E, E2]>,
S & ToSchema<M, MergePath<BasePath, P>, I['in'], MergeTypedResponseData<R>>,
BasePath
>
// app.on(method, path, handler x2)
<
M extends string,
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
R extends HandlerResponse<any> = 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<E2, MergedPath, I>, H<E3, MergedPath, I2, R>]
): FrogBase<
IntersectNonAnyTypes<[E, E2, E3]>,
S &
ToSchema<M, MergePath<BasePath, P>, I2['in'], MergeTypedResponseData<R>>,
BasePath
>
// app.on(method, path, handler x3)
<
M extends string,
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
R extends HandlerResponse<any> = 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<E2, MergedPath, I>,
H<E3, MergedPath, I2>,
H<E4, MergedPath, I3, R>,
]
): FrogBase<
IntersectNonAnyTypes<[E, E2, E3, E4]>,
S &
ToSchema<M, MergePath<BasePath, P>, I3['in'], MergeTypedResponseData<R>>,
BasePath
>
// app.on(method, path, handler x4)
<
M extends string,
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
R extends HandlerResponse<any> = 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<E2, MergedPath, I>,
H<E3, MergedPath, I2>,
H<E4, MergedPath, I3>,
H<E5, MergedPath, I4, R>,
]
): FrogBase<
IntersectNonAnyTypes<[E, E2, E3, E4, E5]>,
S &
ToSchema<M, MergePath<BasePath, P>, I4['in'], MergeTypedResponseData<R>>,
BasePath
>
// app.on(method, path, handler x5)
<
M extends string,
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
R extends HandlerResponse<any> = 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<E2, MergedPath, I>,
H<E3, MergedPath, I2>,
H<E4, MergedPath, I3>,
H<E5, MergedPath, I4>,
H<E6, MergedPath, I5, R>,
]
): FrogBase<
IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>,
S &
ToSchema<M, MergePath<BasePath, P>, I5['in'], MergeTypedResponseData<R>>,
BasePath
>
// app.on(method, path, handler x6)
<
M extends string,
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
R extends HandlerResponse<any> = 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<E2, MergedPath, I>,
H<E3, MergedPath, I2>,
H<E4, MergedPath, I3>,
H<E5, MergedPath, I4>,
H<E6, MergedPath, I5>,
H<E7, MergedPath, I6, R>,
]
): FrogBase<
IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>,
S &
ToSchema<M, MergePath<BasePath, P>, I6['in'], MergeTypedResponseData<R>>,
BasePath
>
// app.on(method, path, handler x7)
<
M extends string,
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
R extends HandlerResponse<any> = 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<E2, MergedPath, I>,
H<E3, MergedPath, I2>,
H<E4, MergedPath, I3>,
H<E5, MergedPath, I4>,
H<E6, MergedPath, I5>,
H<E7, MergedPath, I6>,
H<E8, MergedPath, I7, R>,
]
): FrogBase<
IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>,
S &
ToSchema<M, MergePath<BasePath, P>, I7['in'], MergeTypedResponseData<R>>,
BasePath
>
// app.on(method, path, handler x8)
<
M extends string,
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
R extends HandlerResponse<any> = 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<E2, MergedPath, I>,
H<E3, MergedPath, I2>,
H<E4, MergedPath, I3>,
H<E5, MergedPath, I4>,
H<E6, MergedPath, I5>,
H<E7, MergedPath, I6>,
H<E8, MergedPath, I7>,
H<E9, MergedPath, I8, R>,
]
): FrogBase<
IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>,
S &
ToSchema<M, MergePath<BasePath, P>, I8['in'], MergeTypedResponseData<R>>,
BasePath
>
// app.on(method, path, handler x9)
<
M extends string,
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
R extends HandlerResponse<any> = 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<E2, MergedPath, I>,
H<E3, MergedPath, I2>,
H<E4, MergedPath, I3>,
H<E5, MergedPath, I4>,
H<E6, MergedPath, I5>,
H<E7, MergedPath, I6>,
H<E8, MergedPath, I7>,
H<E9, MergedPath, I8>,
H<E10, MergedPath, I9, R>,
]
): FrogBase<
IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>,
S &
ToSchema<M, MergePath<BasePath, P>, I9['in'], MergeTypedResponseData<R>>,
BasePath
>
// app.on(method, path, handler x10)
<
M extends string,
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
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<E2, MergedPath, I>,
H<E3, MergedPath, I2>,
H<E4, MergedPath, I3>,
H<E5, MergedPath, I4>,
H<E6, MergedPath, I5>,
H<E7, MergedPath, I6>,
H<E8, MergedPath, I7>,
H<E9, MergedPath, I8>,
H<E10, MergedPath, I9>,
H<E11, MergedPath, I10>,
]
): FrogBase<
IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11]>,
S &
ToSchema<
M,
MergePath<BasePath, P>,
I10['in'],
MergeTypedResponseData<HandlerResponse<any>>
>,
BasePath
>
// app.get(method, path, ...handler)
<
M extends string,
P extends string,
R extends HandlerResponse<any> = any,
I extends Input = {},
>(
method: M,
path: P,
...handlers: H<E, MergePath<BasePath, P>, I, R>[]
): FrogBase<
E,
S & ToSchema<M, MergePath<BasePath, P>, I['in'], MergeTypedResponseData<R>>,
BasePath
>
// app.get(method[], path, handler)
<
Ms extends string[],
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
R extends HandlerResponse<any> = any,
I extends Input = BlankInput,
E2 extends Env = E,
>(
methods: Ms,
path: P,
handler: H<E2, MergedPath, I, R>,
): FrogBase<
IntersectNonAnyTypes<[E, E2]>,
S &
ToSchema<
Ms[number],
MergePath<BasePath, P>,
I['in'],
MergeTypedResponseData<R>
>,
BasePath
>
// app.get(method[], path, handler x2)
<
Ms extends string[],
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
R extends HandlerResponse<any> = 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<E2, MergedPath, I>, H<E3, MergedPath, I2, R>]
): FrogBase<
IntersectNonAnyTypes<[E, E2, E3]>,
S &
ToSchema<
Ms[number],
MergePath<BasePath, P>,
I2['in'],
MergeTypedResponseData<R>
>,
BasePath
>
// app.get(method[], path, handler x3)
<
Ms extends string[],
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
R extends HandlerResponse<any> = 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<E2, MergedPath, I>,
H<E3, MergedPath, I2>,
H<E4, MergedPath, I3, R>,
]
): FrogBase<
IntersectNonAnyTypes<[E, E2, E3, E4]>,
S &
ToSchema<
Ms[number],
MergePath<BasePath, P>,
I3['in'],
MergeTypedResponseData<R>
>,
BasePath
>
// app.get(method[], path, handler x4)
<
Ms extends string[],
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
R extends HandlerResponse<any> = 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<E2, MergedPath, I>,
H<E3, MergedPath, I2>,
H<E4, MergedPath, I3>,
H<E5, MergedPath, I4, R>,
]
): FrogBase<
IntersectNonAnyTypes<[E, E2, E3, E4, E5]>,
S &
ToSchema<
Ms[number],
MergePath<BasePath, P>,
I4['in'],
MergeTypedResponseData<R>
>,
BasePath
>
// app.get(method[], path, handler x5)
<
Ms extends string[],
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
R extends HandlerResponse<any> = 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<E2, MergedPath, I>,
H<E3, MergedPath, I2>,
H<E4, MergedPath, I3>,
H<E5, MergedPath, I4>,
H<E6, MergedPath, I5, R>,
]
): FrogBase<
IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>,
S &
ToSchema<
Ms[number],
MergePath<BasePath, P>,
I5['in'],
MergeTypedResponseData<R>
>,
BasePath
>
// app.get(method[], path, handler x6)
<
Ms extends string[],
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
R extends HandlerResponse<any> = 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<E2, MergedPath, I>,
H<E3, MergedPath, I2>,
H<E4, MergedPath, I3>,
H<E5, MergedPath, I4>,
H<E6, MergedPath, I5>,
H<E7, MergedPath, I6, R>,
]
): FrogBase<
IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>,
S &
ToSchema<
Ms[number],
MergePath<BasePath, P>,
I6['in'],
MergeTypedResponseData<R>
>,
BasePath
>
// app.get(method[], path, handler x7)
<
Ms extends string[],
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
R extends HandlerResponse<any> = 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<E2, MergedPath, I>,
H<E3, MergedPath, I2>,
H<E4, MergedPath, I3>,
H<E5, MergedPath, I4>,
H<E6, MergedPath, I5>,
H<E7, MergedPath, I6>,
H<E8, MergedPath, I7, R>,
]
): FrogBase<
IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>,
S &
ToSchema<
Ms[number],
MergePath<BasePath, P>,
I7['in'],
MergeTypedResponseData<R>
>,
BasePath
>
// app.get(method[], path, handler x8)
<
Ms extends string[],
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
R extends HandlerResponse<any> = 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<E2, MergedPath, I>,
H<E3, MergedPath, I2>,
H<E4, MergedPath, I3>,
H<E5, MergedPath, I4>,
H<E6, MergedPath, I5>,
H<E7, MergedPath, I6>,
H<E8, MergedPath, I7>,
H<E9, MergedPath, I8, R>,
]
): FrogBase<
IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>,
S &
ToSchema<
Ms[number],
MergePath<BasePath, P>,
I8['in'],
MergeTypedResponseData<R>
>,
BasePath
>
// app.get(method[], path, handler x9)
<
Ms extends string[],
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
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<E2, MergedPath, I>,
H<E3, MergedPath, I2>,
H<E4, MergedPath, I3>,
H<E5, MergedPath, I4>,
H<E6, MergedPath, I5>,
H<E7, MergedPath, I6>,
H<E8, MergedPath, I7>,
H<E9, MergedPath, I8>,
H<E10, MergedPath, I9>,
]
): FrogBase<
IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>,
S &
ToSchema<
Ms[number],
MergePath<BasePath, P>,
I9['in'],
MergeTypedResponseData<HandlerResponse<any>>
>,
BasePath
>
// app.get(method[], path, handler x10)
<
Ms extends string[],
P extends string,
MergedPath extends MergePath<BasePath, P> = MergePath<BasePath, P>,
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<E2, MergedPath, I>,
H<E3, MergedPath, I2>,
H<E4, MergedPath, I3>,
H<E5, MergedPath, I4>,
H<E6, MergedPath, I5>,
H<E7, MergedPath, I6>,
H<E8, MergedPath, I7>,
H<E9, MergedPath, I8>,
H<E10, MergedPath, I9>,
H<E11, MergedPath, I10>,
]
): FrogBase<
IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11]>,
S &
ToSchema<
Ms[number],
MergePath<BasePath, P>,
I10['in'],
MergeTypedResponseData<HandlerResponse<any>>
>,
BasePath
>
// app.on(method[], path, ...handler)
<
P extends string,
R extends HandlerResponse<any> = any,
I extends Input = {},
>(
methods: string[],
path: P,
...handlers: H<E, MergePath<BasePath, P>, I, R>[]
): FrogBase<
E,
S &
ToSchema<
string,
MergePath<BasePath, P>,
I['in'],
MergeTypedResponseData<R>
>,
BasePath
>
// app.on(method | method[], path[], ...handlers[])
<I extends Input = BlankInput, R extends HandlerResponse<any> = any>(
methods: string | string[],
paths: string[],
...handlers: H<E, any, I, R>[]
): FrogBase<
E,
S & ToSchema<string, string, I['in'], MergeTypedResponseData<R>>,
BasePath
>
}
type ExtractKey<S> = S extends Record<infer Key, unknown>
? 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<K2>]: {
input: unknown extends I ? AddParam<{}, P> : AddParam<I, P>
output: unknown extends O ? {} : O
}
}
}
export type KnownResponseFormat = 'json' | 'text' | 'redirect'
export type ResponseFormat = KnownResponseFormat | string
export type Schema = {
[Path: string]: {
[Method: `$${Lowercase<string>}`]: {
input: Partial<ValidationTargets> & {
param?: Record<string, string | undefined>
}
output: any
outputFormat: ResponseFormat
status: StatusCode
}
}
}
type ExtractParams<Path extends string> = string extends Path
? Record<string, string>
: 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> = 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<SubPath, P & string>]: {
[M in keyof OrigSchema[P]]: OrigSchema[P][M] extends {
input: infer Input
output: infer Output
}
? {
input: Input extends { param: infer _ }
? ExtractParams<SubPath> extends never
? Input
: FlattenIfIntersect<Input & { param: ExtractParams<SubPath> }>
: RemoveBlankRecord<ExtractParams<SubPath>> extends never
? Input
: Input & { param: ExtractParams<SubPath> }
output: Output
}
: never
}
}
export type AddParam<I, P extends string> = ParamKeys<P> extends never
? I
: I extends { param: infer _ }
? I
: I & { param: UnionToIntersection<ParamKeyToRecord<ParamKeys<P>>> }
type AddDollar<T extends string> = `$${Lowercase<T>}`
export type MergePath<A extends string, B extends string> = 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<T = unknown> = {
data: T
format: 'json' // Currently, support only `json` with `c.jsonT()`
}
type ExtractResponseData<T> = T extends Promise<infer T2>
? T2 extends TypedResponse<infer U>
? U
: {}
: T extends TypedResponse<infer U>
? U
: {}
type MergeTypedResponseData<T> = ExtractResponseData<T>
////////////////////////////////////////
////// /////
////// ValidationTargets /////
////// /////
////////////////////////////////////////
export type ValidationTargets = {
json: any
form: Record<string, string | File>
query: Record<string, string | string[]>
param: Record<string, string> | Record<string, string | undefined>
header: Record<string, string>
cookie: Record<string, string>
}
////////////////////////////////////////
////// //////
////// Path parameters //////
////// //////
////////////////////////////////////////
type ParamKeyName<NameWithPattern> =
NameWithPattern extends `${infer Name}{${infer Rest}`
? Rest extends `${infer _Pattern}?`
? `${Name}?`
: Name
: NameWithPattern
type ParamKey<Component> = Component extends `:${infer NameWithPattern}`
? ParamKeyName<NameWithPattern>
: never
export type ParamKeys<Path> = Path extends `${infer Component}/${infer Rest}`
? ParamKey<Component> | ParamKeys<Rest>
: ParamKey<Path>
export type ParamKeyToRecord<T extends string> = T extends `${infer R}?`
? Record<R, string | undefined>
: { [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> = T extends `${infer R}?` ? R : T
export type UndefinedIfHavingQuestion<T> = T extends `${infer _}?`
? string | undefined
: string
////////////////////////////////////////
////// //////
////// Utilities //////
////// //////
////////////////////////////////////////
export type ExtractSchema<T> = UnionToIntersection<
T extends FrogBase<infer _, infer S, any> ? S : never
>
type EnvOrEmpty<T> = T extends Env ? (Env extends T ? {} : T) : T
type IntersectNonAnyTypes<T extends any[]> = T extends [
infer Head,
...infer Rest,
]
? IfAnyThenEmptyObject<EnvOrEmpty<Head>> & IntersectNonAnyTypes<Rest>
: {}