Skip to content

Commit 8a3e0a2

Browse files
fix(nest): honor routed request during input decoding (#1922)
`ImplementInterceptor` currently decodes procedure input from the initial `standardRequest`, even when a routing interceptor passes a replacement request to `StandardHandler`. This prevents request wrappers such as `RequestLimitHandlerPlugin` from taking effect during Nest input decoding. ## Fixes - Decode procedure input from the request passed to `resolveProcedure` after routing interceptors have run. - Restore `RequestLimitHandlerPlugin` enforcement for `@orpc/nest` without changing the public API. - Keep the existing Nest route parameter extraction behavior unchanged. ## Testing - Added an integration regression test for both Express and Fastify adapters. - Before the fix, both cases returned `200` for a request above the configured limit. - After the fix, both cases return `413 PAYLOAD_TOO_LARGE`. - `pnpm exec vitest run packages/nest/src/implement.test.ts` — 90 tests passed. - `pnpm lint` - `pnpm type:check` - `pnpm docs:validate` Fixes #1921 --------- Co-authored-by: Dinh Le <dinwwwh@gmail.com>
1 parent cc68d42 commit 8a3e0a2

2 files changed

Lines changed: 47 additions & 2 deletions

File tree

packages/nest/src/implement.test.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { Test } from '@nestjs/testing'
1111
import { meta, oc } from '@orpc/contract'
1212
import { openapi } from '@orpc/openapi'
1313
import { implement, ORPCError, os, Procedure } from '@orpc/server'
14+
import { RequestLimitHandlerPlugin } from '@orpc/server/plugins'
1415
import { getOrBind } from '@orpc/shared'
1516
import { catchError, tap } from 'rxjs'
1617
import supertest from 'supertest'
@@ -1473,4 +1474,48 @@ describe('compatibility', () => {
14731474

14741475
await app.close()
14751476
})
1477+
1478+
describe('handler plugins from ORPCModule take effect during input decoding', () => {
1479+
const contract = oc
1480+
.meta(openapi({ method: 'POST', path: '/request-limit' }))
1481+
.input(z.object({ value: z.string() }))
1482+
1483+
@Controller()
1484+
class ImplController {
1485+
@Implement(contract)
1486+
requestLimit() {
1487+
return implement(contract).handler(({ input }) => input.value)
1488+
}
1489+
}
1490+
1491+
describe.each([
1492+
['express adapter', undefined],
1493+
['fastify adapter', new FastifyAdapter()],
1494+
] as const)('with %s', async (_, adapter) => {
1495+
const moduleRef = await Test.createTestingModule({
1496+
controllers: [ImplController],
1497+
imports: [
1498+
ORPCModule.forRoot({
1499+
plugins: [new RequestLimitHandlerPlugin({ maxBodySize: 10 })],
1500+
}),
1501+
],
1502+
}).compile()
1503+
1504+
const app = moduleRef.createNestApplication(adapter as any)
1505+
await app.init()
1506+
1507+
if (adapter) {
1508+
await app.getHttpAdapter().getInstance().ready()
1509+
}
1510+
1511+
it('rejects a request whose content length exceeds the limit', async () => {
1512+
const res = await supertest(app.getHttpServer())
1513+
.post('/request-limit')
1514+
.send({ value: 'over limit' })
1515+
1516+
expect(res.statusCode).toEqual(413)
1517+
expect(res.body).toMatchObject({ code: 'PAYLOAD_TOO_LARGE' })
1518+
})
1519+
})
1520+
})
14761521
})

packages/nest/src/implement.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,13 +194,13 @@ export class ImplementInterceptor implements NestInterceptor {
194194
const standardRequest = this.toNestStandardLazyRequest(req, res)
195195

196196
const handler = new StandardHandler({
197-
resolveProcedure: () => Promise.resolve({
197+
resolveProcedure: request => Promise.resolve({
198198
path: getPathMeta(procedure) ?? [],
199199
procedure,
200200
decodeInput: () => this.codec.decodeInput({
201201
procedure,
202202
params: toORPCOpenAPIParams(procedure, standardRequest.params),
203-
}, standardRequest),
203+
}, request),
204204
}),
205205
encodeError: this.codec.encodeError.bind(this.codec),
206206
encodeOutput: this.codec.encodeOutput.bind(this.codec),

0 commit comments

Comments
 (0)