Skip to content

Commit b3fde9b

Browse files
authored
fix: new nest.js handlers returning promise to interceptors (#515)
1 parent 1212e3f commit b3fde9b

3 files changed

Lines changed: 72 additions & 2 deletions

File tree

.changeset/ninety-coins-hunt.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@ts-rest/nest': patch
3+
---
4+
5+
Fix Nest.js interceptor returninng promise when using new Nest.js handlers

libs/ts-rest/nest/src/lib/ts-rest-nest-handler.spec.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,15 @@ import { z } from 'zod';
99
import {
1010
ArgumentsHost,
1111
Body,
12+
CallHandler,
1213
Catch,
1314
Controller,
1415
ExceptionFilter,
16+
ExecutionContext,
1517
Get,
1618
HttpException,
19+
Injectable,
20+
NestInterceptor,
1721
Post,
1822
UploadedFile,
1923
UseInterceptors,
@@ -25,6 +29,7 @@ import path = require('path');
2529
import { FileInterceptor } from '@nestjs/platform-express';
2630
import { FastifyAdapter } from '@nestjs/platform-fastify';
2731
import { Response } from 'express';
32+
import { map, Observable } from 'rxjs';
2833

2934
export type Equal<a, b> = (<T>() => T extends a ? 1 : 2) extends <
3035
T,
@@ -467,6 +472,66 @@ describe('ts-rest-nest-handler', () => {
467472
expect(response.body).toEqual({ message: 'ok' });
468473
});
469474
});
475+
476+
it('should be able to intercept', async () => {
477+
const c = initContract();
478+
479+
const contract = c.router({
480+
getRequest: {
481+
path: '/',
482+
method: 'GET',
483+
responses: {
484+
200: z.object({
485+
message: z.string(),
486+
}),
487+
},
488+
},
489+
});
490+
491+
@Injectable()
492+
class TestInterceptor implements NestInterceptor {
493+
intercept(
494+
context: ExecutionContext,
495+
next: CallHandler,
496+
): Observable<any> {
497+
return next.handle().pipe(
498+
map((data) => ({
499+
message: 'intercepted',
500+
oldMessage: data.message,
501+
})),
502+
);
503+
}
504+
}
505+
506+
@Controller()
507+
class SingleHandlerTestController {
508+
@TsRestHandler(contract)
509+
@UseInterceptors(TestInterceptor)
510+
async postRequest() {
511+
return tsRestHandler(contract, {
512+
getRequest: async () => ({
513+
status: 200,
514+
body: { message: 'ok' },
515+
}),
516+
});
517+
}
518+
}
519+
520+
const moduleRef = await Test.createTestingModule({
521+
controllers: [SingleHandlerTestController],
522+
}).compile();
523+
524+
const app = moduleRef.createNestApplication();
525+
await app.init();
526+
527+
const response = await supertest(app.getHttpServer()).get('/').send();
528+
529+
expect(response.status).toBe(200);
530+
expect(response.body).toEqual({
531+
message: 'intercepted',
532+
oldMessage: 'ok',
533+
});
534+
});
470535
});
471536

472537
describe('single-handler api', () => {

libs/ts-rest/nest/src/lib/ts-rest-nest-handler.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Reflector } from '@nestjs/core';
2-
import { map, Observable } from 'rxjs';
2+
import { mergeMap, Observable } from 'rxjs';
33
import type { Request, Response } from 'express-serve-static-core';
44
import type { FastifyReply, FastifyRequest } from 'fastify';
55
import {
@@ -341,7 +341,7 @@ export class TsRestHandlerInterceptor implements NestInterceptor {
341341
}
342342

343343
return next.handle().pipe(
344-
map(async (impl) => {
344+
mergeMap(async (impl) => {
345345
let result = null;
346346
try {
347347
const res = {

0 commit comments

Comments
 (0)