diff --git a/src/koa-utils.ts b/src/koa-utils.ts index 7c2b399..ff4c56d 100644 --- a/src/koa-utils.ts +++ b/src/koa-utils.ts @@ -94,11 +94,6 @@ export type EndpointImplementation< context: ContextOfEndpoint, ) => Response | Promise; -export type OneSchemaRouterMiddleware = ( - context: Context, - next: () => Promise, -) => any | Promise; - export const implementRoute = < Route extends string, Request, @@ -108,9 +103,6 @@ export const implementRoute = < route: Route, router: R, parse: (ctx: ContextOfEndpoint, data: unknown) => Request, - middlewares: OneSchemaRouterMiddleware< - ContextOfEndpoint - >[], implementation: EndpointImplementation, ) => { // Separate method and path. e.g. 'POST my/route' => ['POST', 'my/route'] @@ -171,19 +163,19 @@ export const implementRoute = < // Register the route + handler on the router. switch (method) { case 'POST': - router.post(path, ...middlewares, handler); + router.post(path, handler); break; case 'GET': - router.get(path, ...middlewares, handler); + router.get(path, handler); break; case 'PUT': - router.put(path, ...middlewares, handler); + router.put(path, handler); break; case 'PATCH': - router.patch(path, ...middlewares, handler); + router.patch(path, handler); break; case 'DELETE': - router.delete(path, ...middlewares, handler); + router.delete(path, handler); break; default: throw new Error(`Unsupported method detected: ${route}`); diff --git a/src/koa.ts b/src/koa.ts index 7ea7c53..857c447 100644 --- a/src/koa.ts +++ b/src/koa.ts @@ -135,7 +135,6 @@ export const implementSchema = < data, }); }, - [], routeHandler, ); } diff --git a/src/router.test.ts b/src/router.test.ts index 5261bf5..e095671 100644 --- a/src/router.test.ts +++ b/src/router.test.ts @@ -410,11 +410,10 @@ describe('output validation', () => { request: z.object({}), response: z.object({ message: z.string() }), }) - .implement( - `${method} /items`, + .implement(`${method} /items`, () => ({ // @ts-expect-error Intentionally writing incorrect TS here - () => ({ message: 123 }), - ), + message: 123, + })), ); const { status } = await client.request({ @@ -510,105 +509,6 @@ describe('implementations', () => { }); }); -describe('using middleware', () => { - test('type errors are caught when using middleware', () => { - type CustomState = { message: string }; - - setup(() => - OneSchemaRouter.create({ - using: new Router(), - introspection: undefined, - }) - .declare({ - name: 'putItem', - route: 'PUT /items/:id', - request: z.object({ message: z.string() }), - response: z.object({ id: z.string(), message: z.string() }), - }) - .implement( - 'PUT /items/:id', - // @ts-expect-error - async (ctx, next) => { - ctx.state.message = ctx.request.body.message + '-response'; - await next(); - }, - // We're leaving out the id value here, which should cause the TS error. - (ctx) => ({ message: ctx.state.message }), - ) - .implement( - 'PUT /items/:id', - async (ctx, next) => { - ctx.params.id; - - ctx.request.body.message; - - // @ts-expect-error The params should be well-typed. - ctx.params.bogus; - - // @ts-expect-error The body should be well-typed. - ctx.request.body.bogus; - - await next(); - }, - (ctx) => ({ id: 'test-id', message: ctx.state.message }), - ) - .implement( - 'PUT /items/:id', - (ctx, next) => { - // This call implicitly tests that `message` is a string. - ctx.state.message.endsWith(''); - - // @ts-expect-error The state should be well-typed. - ctx.state.bogus; - - return next(); - }, - (ctx) => ({ id: 'test-id', message: ctx.state.message }), - ), - ); - }); - - test('middlewares are actually executed', async () => { - const mock = jest.fn(); - const { typed: client } = setup((router) => - router - .declare({ - name: 'putItem', - route: 'PUT /items/:id', - request: z.object({ message: z.string() }), - response: z.object({ id: z.string(), message: z.string() }), - }) - .implement( - 'PUT /items/:id', - async (ctx, next) => { - mock('middleware 1', ctx.state.message); - ctx.state.message = 'message 1'; - await next(); - }, - (ctx, next) => { - mock('middleware 2', ctx.state.message); - ctx.state.message = 'message 2'; - return next(); - }, - (ctx) => ({ id: ctx.params.id, message: ctx.state.message }), - ), - ); - - const { status, data } = await client.putItem({ - id: 'test-id-bleh', - message: 'test-message', - }); - - expect(status).toStrictEqual(200); - expect(data).toStrictEqual({ id: 'test-id-bleh', message: 'message 2' }); - - expect(mock.mock.calls).toEqual([ - ['middleware 1', undefined], - ['middleware 2', 'message 1'], - ]); - }); -}); - describe('introspection', () => { test('introspecting + generating a client', async () => { const { client } = serve( diff --git a/src/router.ts b/src/router.ts index a06af6f..14639be 100644 --- a/src/router.ts +++ b/src/router.ts @@ -4,10 +4,8 @@ import { fromZodError } from 'zod-validation-error'; import zodToJsonSchema from 'zod-to-json-schema'; import compose = require('koa-compose'); import { - ContextOfEndpoint, EndpointImplementation, implementRoute, - OneSchemaRouterMiddleware, PathParamsOf, } from './koa-utils'; import { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'; @@ -99,24 +97,15 @@ export class OneSchemaRouter< implement( route: Route, - ...middlewares: [ - ...OneSchemaRouterMiddleware< - ContextOfEndpoint, R> - >[], - EndpointImplementation< - Route, - z.output, - z.infer, - R - >, - ] - ): this { + implementation: EndpointImplementation< + Route, + z.output, + z.infer, + R + >, + ) { const endpoint = this.schema[route]; - const mws = middlewares.slice(0, -1) as any[]; - - const implementation = middlewares.at(-1) as any; - implementRoute( route, this.router, @@ -130,8 +119,6 @@ export class OneSchemaRouter< } return res.data; }, - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - mws, async (ctx) => { const result = await implementation(ctx); const res = endpoint.response.safeParse(result);