From ce85283539c186bb2a87f2841db48bb2077765b7 Mon Sep 17 00:00:00 2001 From: hotwater Date: Sat, 13 Apr 2024 02:25:08 +0300 Subject: [PATCH 1/9] feat: cast actions deeplink v2 --- playground/src/castAction.tsx | 30 +- src/components/Button.tsx | 9 +- src/frog-base.tsx | 57 +- src/types/octicon.ts | 166 ++--- src/types/routes.ts | 1061 ++++++++++++++++++++++--------- src/utils/getRouteParameters.ts | 8 +- 6 files changed, 896 insertions(+), 435 deletions(-) diff --git a/playground/src/castAction.tsx b/playground/src/castAction.tsx index 2d3926a2..76cce0be 100644 --- a/playground/src/castAction.tsx +++ b/playground/src/castAction.tsx @@ -36,18 +36,24 @@ export const app = new Frog() ), intents: [ - - Add - , + Add, ], }), ) - .castAction('/action', async (c) => { - console.log( - `Cast Action to ${JSON.stringify(c.actionData.castId)} from ${ - c.actionData.fid - }`, - ) - if (Math.random() > 0.5) return c.error({ message: 'Action failed :(' }) - return c.res({ message: 'Action Succeeded' }) - }) + .castAction( + '/action', + async (c) => { + console.log( + `Cast Action to ${JSON.stringify(c.actionData.castId)} from ${ + c.actionData.fid + }`, + ) + if (Math.random() > 0.5) return c.error({ message: 'Action failed :(' }) + return c.res({ message: 'Action Succeeded' }) + }, + { + name: 'Log This!', + icon: 'log', + description: 'This cast action will log something!', + }, + ) diff --git a/src/components/Button.tsx b/src/components/Button.tsx index 49a2ff14..16cbe677 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -1,5 +1,4 @@ import type { HtmlEscapedString } from 'hono/utils/html' -import type { Octicon } from '../types/octicon.js' export const buttonPrefix = { addCastAction: '_a', @@ -43,18 +42,12 @@ export function ButtonRoot({ export type ButtonAddCastActionProps = ButtonProps & { /** Action path */ action: string - /** Name of the action. 30 characters maximum */ - name: string - /** Octicon name. @see https://primer.style/foundations/icons */ - icon: Octicon } ButtonAddCastAction.__type = 'button' export function ButtonAddCastAction({ action, children, - name, - icon, // @ts-ignore - private index = 1, }: ButtonAddCastActionProps) { @@ -67,7 +60,7 @@ export function ButtonAddCastAction({ , , ] as unknown as HtmlEscapedString } diff --git a/src/frog-base.tsx b/src/frog-base.tsx index 93164327..2b5a72c2 100644 --- a/src/frog-base.tsx +++ b/src/frog-base.tsx @@ -16,6 +16,7 @@ import type { ImageOptions, } from './types/frame.js' import type { Hub } from './types/hub.js' +import type { Octicon } from './types/octicon.js' import type { CastActionHandler, FrameHandler, @@ -168,9 +169,22 @@ export type FrogConstructorParameters< verify?: boolean | 'silent' | undefined } -export type RouteOptions = Pick & { - fonts?: ImageOptions['fonts'] | (() => Promise) -} +export type RouteOptions = Pick< + FrogConstructorParameters, + 'verify' +> & + (M extends 'frame' + ? { + fonts?: ImageOptions['fonts'] | (() => Promise) + } + : M extends 'cast-action' + ? { + name: string + icon: Octicon + description?: string + aboutUrl?: string + } + : {}) /** * A Frog instance. @@ -299,15 +313,36 @@ export class FrogBase< castAction: HandlerInterface = ( ...parameters: any[] ) => { - const [path, middlewares, handler, options = {}] = getRouteParameters< + const [path, middlewares, handler, options] = getRouteParameters< env, - CastActionHandler + CastActionHandler, + 'cast-action' >(...parameters) - const { verify = this.verify } = options + const { verify = this.verify, ...installParameters } = options + + // Cast Action Route (implements GET and POST). + this.hono.use(parseHonoPath(path), ...middlewares, async (c) => { + const url = getRequestUrl(c.req) + const origin = this.origin ?? url.origin + const baseUrl = origin + parsePath(this.basePath) + + if (c.req.method === 'GET') { + console.log({ + ...installParameters, + action: { + type: 'post', + }, + }) + return c.json({ + ...installParameters, + postUrl: baseUrl + parsePath(path), + action: { + type: 'post', + }, + }) + } - // Cast Action Route (implements POST). - this.hono.post(parseHonoPath(path), ...middlewares, async (c) => { const { context } = getCastActionContext({ context: await requestBodyToContext(c, { hub: @@ -342,7 +377,8 @@ export class FrogBase< ) => { const [path, middlewares, handler, options = {}] = getRouteParameters< env, - FrameHandler + FrameHandler, + 'frame' >(...parameters) const { verify = this.verify } = options @@ -726,7 +762,8 @@ export class FrogBase< ) => { const [path, middlewares, handler, options = {}] = getRouteParameters< env, - TransactionHandler + TransactionHandler, + 'transaction' >(...parameters) const { verify = this.verify } = options diff --git a/src/types/octicon.ts b/src/types/octicon.ts index cc0b42e6..48a00157 100644 --- a/src/types/octicon.ts +++ b/src/types/octicon.ts @@ -1,126 +1,126 @@ export type Octicon = - | 'number' - | 'search' - | 'image' + | 'accessibility' | 'alert' - | 'code' - | 'meter' - | 'ruby' - | 'video' - | 'filter' - | 'stop' - | 'plus' - | 'info' - | 'check' - | 'book' - | 'question' - | 'mail' - | 'home' - | 'star' - | 'inbox' - | 'lock' - | 'eye' - | 'heart' - | 'unlock' - | 'play' - | 'tag' - | 'calendar' - | 'database' - | 'hourglass' - | 'key' - | 'gift' - | 'sync' | 'archive' + | 'beaker' | 'bell' - | 'bookmark' - | 'briefcase' - | 'bug' - | 'clock' - | 'credit-card' - | 'globe' - | 'infinity' - | 'light-bulb' - | 'location' - | 'megaphone' - | 'moon' - | 'note' - | 'pencil' - | 'pin' - | 'quote' - | 'reply' - | 'rocket' - | 'shield' - | 'stopwatch' - | 'tools' - | 'trash' - | 'comment' - | 'gear' - | 'file' - | 'hash' - | 'square' - | 'sun' - | 'zap' - | 'sign-out' - | 'sign-in' - | 'paste' - | 'mortar-board' - | 'history' - | 'plug' | 'bell-slash' - | 'diamond' - | 'id-badge' - | 'person' - | 'smiley' - | 'pulse' - | 'beaker' - | 'flame' - | 'people' - | 'person-add' - | 'broadcast' - | 'graph' - | 'shield-check' - | 'shield-lock' - | 'telescope' - | 'webhook' - | 'accessibility' - | 'report' - | 'verified' | 'blocked' + | 'book' + | 'bookmark' | 'bookmark-slash' + | 'briefcase' + | 'broadcast' + | 'bug' + | 'calendar' + | 'check' | 'checklist' | 'circle-slash' + | 'clock' + | 'code' + | 'comment' + | 'credit-card' | 'cross-reference' + | 'database' | 'dependabot' | 'device-camera' | 'device-camera-video' | 'device-desktop' | 'device-mobile' + | 'diamond' | 'dot' + | 'eye' | 'eye-closed' + | 'file' + | 'filter' + | 'flame' + | 'gear' + | 'gift' + | 'globe' + | 'graph' + | 'hash' + | 'heart' + | 'history' + | 'home' + | 'hourglass' + | 'id-badge' + | 'image' + | 'inbox' + | 'infinity' + | 'info' | 'iterations' + | 'key' | 'key-asterisk' | 'law' + | 'light-bulb' | 'link-external' | 'list-ordered' | 'list-unordered' + | 'location' + | 'lock' | 'log' + | 'mail' + | 'megaphone' | 'mention' + | 'meter' | 'milestone' + | 'moon' + | 'mortar-board' | 'mute' | 'no-entry' | 'north-star' + | 'note' + | 'number' | 'organization' | 'paintbrush' | 'paper-airplane' + | 'paste' + | 'pencil' + | 'people' + | 'person' + | 'person-add' + | 'pin' + | 'play' + | 'plug' + | 'plus' | 'project' + | 'pulse' + | 'question' + | 'quote' + | 'reply' + | 'report' + | 'rocket' + | 'ruby' + | 'search' + | 'shield' + | 'shield-check' + | 'shield-lock' | 'shield-x' + | 'sign-in' + | 'sign-out' | 'skip' + | 'smiley' + | 'square' | 'squirrel' | 'stack' + | 'star' + | 'stop' + | 'stopwatch' + | 'sun' + | 'sync' + | 'tag' | 'tasklist' + | 'telescope' | 'thumbsdown' | 'thumbsup' + | 'tools' + | 'trash' | 'typography' + | 'unlock' | 'unmute' - | 'workflow' + | 'verified' | 'versions' + | 'video' + | 'webhook' + | 'workflow' + | 'zap' diff --git a/src/types/routes.ts b/src/types/routes.ts index be33e1b7..80ea7ee0 100644 --- a/src/types/routes.ts +++ b/src/types/routes.ts @@ -93,328 +93,753 @@ export type H< ////// ////// //////////////////////////////////////// -export interface 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 = 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 - > -} +> = /* We enforce `options` parameter to not be partial for Cast Actions*/ +M extends 'cast-action' + ? { + // app.castAction(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< + M, + MergePath, + I['in'], + MergeTypedResponseData + >, + BasePath + > + + // app.castAction(path, middleware, handler, options) + < + 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< + M, + MergePath, + I2['in'], + MergeTypedResponseData + >, + BasePath + > + + // app.castAction(path, middleware x2, handler, options) + < + 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< + M, + MergePath, + I3['in'], + MergeTypedResponseData + >, + BasePath + > + + // app.castAction(path, middleware x3, handler, options) + < + 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< + M, + MergePath, + I4['in'], + MergeTypedResponseData + >, + BasePath + > + + // app.castAction(path, middleware x4, handler, options) + < + 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< + M, + MergePath, + I5['in'], + MergeTypedResponseData + >, + BasePath + > + + // app.castAction(path, middleware x5, handler, options) + < + 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< + M, + MergePath, + I6['in'], + MergeTypedResponseData + >, + BasePath + > + + // app.castAction(path, middleware x6, handler, options) + < + 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< + M, + MergePath, + I7['in'], + MergeTypedResponseData + >, + BasePath + > + + // app.castAction(path, middleware x7, handler, options) + < + 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< + M, + MergePath, + I8['in'], + MergeTypedResponseData + >, + BasePath + > + + // app.castAction(path, middleware x8, handler, options) + < + 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< + M, + MergePath, + I9['in'], + MergeTypedResponseData + >, + BasePath + > + + // app.castAction(path, middleware x9, handler, options) + < + 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< + M, + MergePath, + I10['in'], + MergeTypedResponseData + >, + BasePath + > + } + : { + // 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< + M, + MergePath, + 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< + M, + MergePath, + 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< + M, + MergePath, + 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< + M, + MergePath, + 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< + M, + MergePath, + 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< + M, + MergePath, + 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< + M, + MergePath, + 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< + M, + MergePath, + 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< + M, + MergePath, + 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< + M, + MergePath, + I10['in'], + MergeTypedResponseData + >, + BasePath + > + } //////////////////////////////////////// ////// ////// diff --git a/src/utils/getRouteParameters.ts b/src/utils/getRouteParameters.ts index b126fa10..569bb8aa 100644 --- a/src/utils/getRouteParameters.ts +++ b/src/utils/getRouteParameters.ts @@ -2,10 +2,10 @@ import type { RouteOptions } from '../frog-base.js' import type { Env } from '../types/env.js' import type { MiddlewareHandler } from '../types/routes.js' -export function getRouteParameters( +export function getRouteParameters( ...parameters: any[] -): [string, MiddlewareHandler[], handler, RouteOptions] { - const options: RouteOptions | undefined = +): [string, MiddlewareHandler[], handler, RouteOptions] { + const options: RouteOptions | undefined = typeof parameters[parameters.length - 1] === 'object' ? parameters[parameters.length - 1] : undefined @@ -17,5 +17,5 @@ export function getRouteParameters( else middlewares.push(parameters[i]) } - return [parameters[0], middlewares, handler!, options ?? {}] + return [parameters[0], middlewares, handler!, options!] } From 14a35d2fdfcc5121888054bcea24e8a71c8437f9 Mon Sep 17 00:00:00 2001 From: hotwater Date: Sat, 13 Apr 2024 02:40:49 +0300 Subject: [PATCH 2/9] chore: changesets --- .changeset/old-buses-poke.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/old-buses-poke.md diff --git a/.changeset/old-buses-poke.md b/.changeset/old-buses-poke.md new file mode 100644 index 00000000..607310e5 --- /dev/null +++ b/.changeset/old-buses-poke.md @@ -0,0 +1,5 @@ +--- +"frog": minor +--- + +Deprecated the Cast Actions Deeplink V1 format in favor of V2. [See more](https://warpcast.notion.site/Spec-Farcaster-Actions-84d5a85d479a43139ea883f6823d8caa). From fb2c5d5df97e6cf3445cd7adb9371f8badb0f20e Mon Sep 17 00:00:00 2001 From: hotwater Date: Sat, 13 Apr 2024 02:45:54 +0300 Subject: [PATCH 3/9] docs: update --- site/pages/concepts/cast-actions.mdx | 52 +++++++++---------- .../reference/frog-cast-action-context.mdx | 12 ++--- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/site/pages/concepts/cast-actions.mdx b/site/pages/concepts/cast-actions.mdx index b5740049..a884263e 100644 --- a/site/pages/concepts/cast-actions.mdx +++ b/site/pages/concepts/cast-actions.mdx @@ -33,25 +33,25 @@ app.frame('/', (c) => { ), intents: [ - + Add , ] }) }) -app.castAction('/log-this', (c) => { - console.log( - `Cast Action to ${JSON.stringify(c.actionData.castId)} from ${ - c.actionData.fid - }`, - ) - return c.res({ message:'Action Succeeded' }) -}) +app.castAction( + '/log-this', + (c) => { + console.log( + `Cast Action to ${JSON.stringify(c.actionData.castId)} from ${ + c.actionData.fid + }`, + ) + return c.res({ message: 'Action Succeeded' }) + }, + { name: "Log This!", icon: "log" }) +) ``` ::: @@ -82,11 +82,7 @@ app.frame('/', (c) => { ), intents: [ - + Add , ] @@ -130,14 +126,18 @@ app.frame('/', (c) => { }) }) -app.castAction('/log-this', (c) => { // [!code focus] - console.log( // [!code focus] - `Cast Action to ${JSON.stringify(c.actionData.castId)} from ${ // [!code focus] - c.actionData.fid // [!code focus] - }`, // [!code focus] - ) // [!code focus] - return c.res({ message: 'Action Succeeded' }) // [!code focus] -}) // [!code focus] +app.castAction( + '/log-this', // [!code focus] + (c) => { // [!code focus] + console.log( // [!code focus] + `Cast Action to ${JSON.stringify(c.actionData.castId)} from ${ // [!code focus] + c.actionData.fid // [!code focus] + }`, // [!code focus] + ) // [!code focus] + return c.res({ message: 'Action Succeeded' }) // [!code focus] + }, // [!code focus] + { name: "Log This!", icon: "log" }) // [!code focus] +) // [!code focus] ``` A breakdown of the `/log-this` route handler: diff --git a/site/pages/reference/frog-cast-action-context.mdx b/site/pages/reference/frog-cast-action-context.mdx index 8bf8a5dc..a73a1038 100644 --- a/site/pages/reference/frog-cast-action-context.mdx +++ b/site/pages/reference/frog-cast-action-context.mdx @@ -10,7 +10,7 @@ export const app = new Frog() app.castAction('/', (c) => { // [!code focus] return c.res({/* ... */}) -}) +}, {/**/}) ``` :::tip[Tip] @@ -35,7 +35,7 @@ app.castAction('/', (c) => { const { actionData } = c const { castId, fid, messageHash, network, timestamp, url } = actionData // [!code focus] return c.res({/* ... */}) -}) +}, {/**/}) ``` ## error @@ -74,7 +74,7 @@ export const app = new Frog() app.castAction('/', (c) => { const { req } = c // [!code focus] return c.res({/* ... */}) -}) +}, {/**/}) ``` ## res @@ -93,7 +93,7 @@ export const app = new Frog() app.castAction('/', (c) => { return c.res({/* ... */}) // [!code focus] -}) +}, {/**/}) ``` ## var @@ -118,7 +118,7 @@ app.use(async (c, next) => { app.castAction('/', (c) => { const message = c.var.message // [!code focus] return c.res({/* ... */}) -}) +}, {/**/}) ``` ## verified @@ -138,5 +138,5 @@ export const app = new Frog() app.castAction('/', (c) => { const { verified } = c // [!code focus] return c.res({/* ... */}) -}) +}, {/**/}) ``` From f6e8e4c9cde65bd76205c83af3626c02756b520b Mon Sep 17 00:00:00 2001 From: hotwater Date: Sat, 13 Apr 2024 02:50:04 +0300 Subject: [PATCH 4/9] chore: update changesets --- .changeset/old-buses-poke.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.changeset/old-buses-poke.md b/.changeset/old-buses-poke.md index 607310e5..46bb9393 100644 --- a/.changeset/old-buses-poke.md +++ b/.changeset/old-buses-poke.md @@ -3,3 +3,7 @@ --- Deprecated the Cast Actions Deeplink V1 format in favor of V2. [See more](https://warpcast.notion.site/Spec-Farcaster-Actions-84d5a85d479a43139ea883f6823d8caa). + +Breaking changes have affected `Button.AddCastAction` and `.castAction` handler: +- `Button.AddCastAction` now only accepts `action` property; +- `.castAction` handler now requries a third parameter (`options`) to be set. Properties that were removed from `Button.AddCastAction` have migrated here, and `aboutUrl` and `description` were added along. From 1d78c2387d69bb6fb76642e57b85bcd630345196 Mon Sep 17 00:00:00 2001 From: Vladyslav Dalechyn Date: Sat, 13 Apr 2024 14:19:59 +0300 Subject: [PATCH 5/9] nit: drop console.log --- src/frog-base.tsx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/frog-base.tsx b/src/frog-base.tsx index 2b5a72c2..154c835b 100644 --- a/src/frog-base.tsx +++ b/src/frog-base.tsx @@ -328,12 +328,6 @@ export class FrogBase< const baseUrl = origin + parsePath(this.basePath) if (c.req.method === 'GET') { - console.log({ - ...installParameters, - action: { - type: 'post', - }, - }) return c.json({ ...installParameters, postUrl: baseUrl + parsePath(path), From 758e2c765b1d648faab23aaf06cf16beb4306604 Mon Sep 17 00:00:00 2001 From: hotwater Date: Fri, 26 Apr 2024 13:35:47 +0300 Subject: [PATCH 6/9] refactor: apply changes from code review --- src/frog-base.tsx | 10 +- src/types/response.ts | 2 +- src/types/routes.ts | 1081 +++++++++-------------------- src/utils/getCastActionContext.ts | 4 +- src/utils/getRouteParameters.ts | 21 +- 5 files changed, 363 insertions(+), 755 deletions(-) diff --git a/src/frog-base.tsx b/src/frog-base.tsx index 154c835b..9693ee1f 100644 --- a/src/frog-base.tsx +++ b/src/frog-base.tsx @@ -169,15 +169,15 @@ export type FrogConstructorParameters< verify?: boolean | 'silent' | undefined } -export type RouteOptions = Pick< +export type RouteOptions = Pick< FrogConstructorParameters, 'verify' > & - (M extends 'frame' + (method extends 'frame' ? { fonts?: ImageOptions['fonts'] | (() => Promise) } - : M extends 'cast-action' + : method extends 'castAction' ? { name: string icon: Octicon @@ -310,13 +310,13 @@ export class FrogBase< }) } - castAction: HandlerInterface = ( + castAction: HandlerInterface = ( ...parameters: any[] ) => { const [path, middlewares, handler, options] = getRouteParameters< env, CastActionHandler, - 'cast-action' + 'castAction' >(...parameters) const { verify = this.verify, ...installParameters } = options diff --git a/src/types/response.ts b/src/types/response.ts index f28620be..7d155844 100644 --- a/src/types/response.ts +++ b/src/types/response.ts @@ -6,7 +6,7 @@ export type BaseError = { message: string; statusCode?: ClientErrorStatusCode } export type BaseErrorResponseFn = (response: BaseError) => TypedResponse export type TypedResponse = { - format: 'cast-action' | 'frame' | 'transaction' + format: 'castAction' | 'frame' | 'transaction' } & OneOf< { data: data; status: 'success' } | { error: BaseError; status: 'error' } > diff --git a/src/types/routes.ts b/src/types/routes.ts index 80ea7ee0..3334a830 100644 --- a/src/types/routes.ts +++ b/src/types/routes.ts @@ -83,7 +83,7 @@ export type H< ? FrameHandler : M extends 'transaction' ? TransactionHandler - : M extends 'cast-action' + : M extends 'castAction' ? CastActionHandler : Handler @@ -98,748 +98,343 @@ export type HandlerInterface< M extends string = string, S extends Schema = {}, BasePath extends string = '/', -> = /* We enforce `options` parameter to not be partial for Cast Actions*/ -M extends 'cast-action' - ? { - // app.castAction(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< - M, - MergePath, - I['in'], - MergeTypedResponseData - >, - BasePath - > - - // app.castAction(path, middleware, handler, options) - < - 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< - M, - MergePath, - I2['in'], - MergeTypedResponseData - >, - BasePath - > - - // app.castAction(path, middleware x2, handler, options) - < - 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< - M, - MergePath, - I3['in'], - MergeTypedResponseData - >, - BasePath - > - - // app.castAction(path, middleware x3, handler, options) - < - 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< - M, - MergePath, - I4['in'], - MergeTypedResponseData - >, - BasePath - > - - // app.castAction(path, middleware x4, handler, options) - < - 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< - M, - MergePath, - I5['in'], - MergeTypedResponseData - >, - BasePath - > - - // app.castAction(path, middleware x5, handler, options) - < - 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< - M, - MergePath, - I6['in'], - MergeTypedResponseData - >, - BasePath - > - - // app.castAction(path, middleware x6, handler, options) - < - 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< - M, - MergePath, - I7['in'], - MergeTypedResponseData - >, - BasePath - > - - // app.castAction(path, middleware x7, handler, options) - < - 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< - M, - MergePath, - I8['in'], - MergeTypedResponseData - >, - BasePath - > - - // app.castAction(path, middleware x8, handler, options) - < - 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< - M, - MergePath, - I9['in'], - MergeTypedResponseData - >, - BasePath - > - - // app.castAction(path, middleware x9, handler, options) - < - 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< - M, - MergePath, - I10['in'], - MergeTypedResponseData - >, - BasePath - > - } - : { - // 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< - M, - MergePath, - 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< - M, - MergePath, - 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< - M, - MergePath, - 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< - M, - MergePath, - 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< - M, - MergePath, - 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< - M, - MergePath, - 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< - M, - MergePath, - 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< - M, - MergePath, - 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< - M, - MergePath, - 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< - M, - MergePath, - I10['in'], - MergeTypedResponseData - >, - BasePath - > - } +> = { + // 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, + ...rest: M extends 'castAction' + ? [options: RouteOptions] + : [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, + ...rest: M extends 'castAction' + ? [options: RouteOptions] + : [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, + ...rest: M extends 'castAction' + ? [options: RouteOptions] + : [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, + ...rest: M extends 'castAction' + ? [options: RouteOptions] + : [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, + ...rest: M extends 'castAction' + ? [options: RouteOptions] + : [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, + ...rest: M extends 'castAction' + ? [options: RouteOptions] + : [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, + ...rest: M extends 'castAction' + ? [options: RouteOptions] + : [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, + ...rest: M extends 'castAction' + ? [options: RouteOptions] + : [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, + ...rest: M extends 'castAction' + ? [options: RouteOptions] + : [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, + ...rest: M extends 'castAction' + ? [options: RouteOptions] + : [options?: RouteOptions] + ): FrogBase< + E, + S & + ToSchema, I10['in'], MergeTypedResponseData>, + BasePath + > +} //////////////////////////////////////// ////// ////// diff --git a/src/utils/getCastActionContext.ts b/src/utils/getCastActionContext.ts index 91332337..4a2f17e9 100644 --- a/src/utils/getCastActionContext.ts +++ b/src/utils/getCastActionContext.ts @@ -36,7 +36,7 @@ export function getCastActionContext< env, error: (data) => ({ error: data, - format: 'cast-action', + format: 'castAction', status: 'error', }), actionData: { @@ -51,7 +51,7 @@ export function getCastActionContext< req, res: (data) => ({ data, - format: 'cast-action', + format: 'castAction', status: 'success', }), var: context.var, diff --git a/src/utils/getRouteParameters.ts b/src/utils/getRouteParameters.ts index 569bb8aa..4e8d1d64 100644 --- a/src/utils/getRouteParameters.ts +++ b/src/utils/getRouteParameters.ts @@ -2,10 +2,23 @@ import type { RouteOptions } from '../frog-base.js' import type { Env } from '../types/env.js' import type { MiddlewareHandler } from '../types/routes.js' -export function getRouteParameters( +export function getRouteParameters< + env extends Env, + handler, + method extends string, +>( ...parameters: any[] -): [string, MiddlewareHandler[], handler, RouteOptions] { - const options: RouteOptions | undefined = +): [ + string, + MiddlewareHandler[], + handler, + method extends 'castAction' + ? RouteOptions + : RouteOptions | undefined, +] { + const options: method extends 'castAction' + ? RouteOptions + : RouteOptions | undefined = typeof parameters[parameters.length - 1] === 'object' ? parameters[parameters.length - 1] : undefined @@ -17,5 +30,5 @@ export function getRouteParameters( else middlewares.push(parameters[i]) } - return [parameters[0], middlewares, handler!, options!] + return [parameters[0], middlewares, handler!, options] as const } From 84cb63abfdbd96ff8737667f1a5a8c48d01958c8 Mon Sep 17 00:00:00 2001 From: hotwater Date: Fri, 26 Apr 2024 14:55:18 +0300 Subject: [PATCH 7/9] docs: fix --- site/pages/concepts/cast-actions.mdx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/site/pages/concepts/cast-actions.mdx b/site/pages/concepts/cast-actions.mdx index a884263e..9bdea789 100644 --- a/site/pages/concepts/cast-actions.mdx +++ b/site/pages/concepts/cast-actions.mdx @@ -62,9 +62,7 @@ app.castAction( In the example above, we are rendering Add Action intent: -1. `action` property is used to set the path to the cast action route. -2. `name` property is used to set the name of the action. It must be less than 30 characters -3. `icon` property is used to associate your Cast Action with one of the Octicons. You can see the supported list [here](https://warpcast.notion.site/Spec-Farcaster-Actions-84d5a85d479a43139ea883f6823d8caa). +`action` property is used to set the path to the cast action route. ```tsx twoslash [src/index.tsx] // @noErrors @@ -97,7 +95,13 @@ app.frame('/', (c) => { Without a route handler to handle the Action request, the Cast Action will be meaningless. -Thus, let's define a `/log-this` route to handle the the Cast Action: +To specify the name and icon for your action, the next properties are used in the action handler definition: +1. `name` property is used to set the name of the action. It must be less than 30 characters +2. `icon` property is used to associate your Cast Action with one of the Octicons. You can see the supported list [here](https://warpcast.notion.site/Spec-Farcaster-Actions-84d5a85d479a43139ea883f6823d8caa). +3. (optional) `description` property is used to describe your action, up to 80 characters. +4. (optional) `aboutUrl` property is used to show an "About" link when installing an action. + +Let's define a `/log-this` route to handle the the Cast Action: ```tsx twoslash [src/index.tsx] // @noErrors @@ -148,7 +152,7 @@ A breakdown of the `/log-this` route handler: ::: -### 5. Bonus: Learn the API +### 3. Bonus: Learn the API You can learn more about the transaction APIs here: From 1c0821bab26ec1ff9fb04c303971c7c480bb4c2a Mon Sep 17 00:00:00 2001 From: hotwater Date: Fri, 26 Apr 2024 14:56:47 +0300 Subject: [PATCH 8/9] docs: nit --- site/pages/concepts/cast-actions.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/site/pages/concepts/cast-actions.mdx b/site/pages/concepts/cast-actions.mdx index 9bdea789..11fca7c6 100644 --- a/site/pages/concepts/cast-actions.mdx +++ b/site/pages/concepts/cast-actions.mdx @@ -150,8 +150,6 @@ A breakdown of the `/log-this` route handler: - We are responding with a `c.res` response and specifying a `message` that will appear in the success toast. -::: - ### 3. Bonus: Learn the API You can learn more about the transaction APIs here: From 18f31ae9c0c4ecd485307316146715a2c5dcc3e7 Mon Sep 17 00:00:00 2001 From: hotwater Date: Fri, 26 Apr 2024 15:35:55 +0300 Subject: [PATCH 9/9] docs: fix --- site/pages/concepts/cast-actions.mdx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/site/pages/concepts/cast-actions.mdx b/site/pages/concepts/cast-actions.mdx index 11fca7c6..d94a3acc 100644 --- a/site/pages/concepts/cast-actions.mdx +++ b/site/pages/concepts/cast-actions.mdx @@ -119,11 +119,7 @@ app.frame('/', (c) => { ), intents: [ - + Add , ]