cloudflare / chanfana

OpenAPI 3 and 3.1 schema generator and validator for Hono, itty-router and more!
https://chanfana.pages.dev
MIT License
275 stars 37 forks source link

Type error when using middleware #70

Closed danielsundq closed 11 months ago

danielsundq commented 1 year ago

There is a type error when using ordinary itty-router middleware together with an OpenAPIRoute class instance:

import { withParams } from 'itty-router';
...
router.get('/devices/:id/alarms', withParams , TodoList);

The error reads:

TS2769: No overload matches this call.   Overload 1 of 3, '(path: string, ...handlers: OpenAPIRouteSchema[]): OpenAPIRouterSchema', gave the following error.     Argument of type '(request: IRequest) => void' is not assignable to parameter of type 'OpenAPIRouteSchema'.   Overload 2 of 3, '(path: string, ...handlers: RouteHandler<IRequest, []>[]): RouterType<Route, any[]>', gave the following error.     Argument of type 'typeof UnitDeviceAlarms' is not assignable to parameter of type 'RouteHandler<IRequest, []>'.       Type 'typeof UnitDeviceAlarms' provides no match for the signature '(request: IRequest): any'.

Note that the route and the middleware works as it should. This is just a type issue.

tuzzmaniandevil commented 11 months ago

Getting the same error. not fond of having to use //@ts-ignore

ashishjullia commented 11 months ago

Hi @danielsundq @tuzzmaniandevil Is it possible to achieve this: https://github.com/cloudflare/itty-router-openapi/issues/84 with a middleware here?

With a framework like expressjs (out of context of cf workers) which provides you (req, res, next) and makes it easier to follow middleware pattern and extracting say (email key) from body as req.body.email.

Is is possible to achieve the same with this itty-rotuer-openapi? I'm aware that it has (request, env, context, data) but unable to get the data.body.email and next in the similar fashion :/

G4brym commented 11 months ago

Hey there, i've just published the new v1.0.0 release that fixes this issue Upgrade to the latest version, if the issue is still not solved please re open this issue to let us know Migration guide to 1.0.0 available here

kwhitley commented 7 months ago

Hi @danielsundq @tuzzmaniandevil Is it possible to achieve this: #84 with a middleware here?

With a framework like expressjs (out of context of cf workers) which provides you (req, res, next) and makes it easier to follow middleware pattern and extracting say (email key) from body as req.body.email.

Is is possible to achieve the same with this itty-rotuer-openapi? I'm aware that it has (request, env, context, data) but unable to get the data.body.email and next in the similar fashion :/

In general, itty follows a different pattern for middleware/handlers. In express, next must be explicitly called to proceed to the next middleware/handler. In itty, this is achieved by simply not returning (from the middleware). Anything that fails to return, or returns undefined, hands the flow back on to the next handler. The equivalent of not firing next (which ends the chain), is returning anything (or throwing an error).

kwhitley commented 7 months ago
const expressMiddleware = (req, res, next) => {
  // do something
  next() // continue to the next handler
}

const ittyMiddleware = (req, ...other) => {
  // do something, but don't return
}

In short, middleware === handler in itty, and either can effectively become middleware by not returning. Likewise, any middleware can intercept the chain (e.g. to return a 401 early) by returning something.