fix: [nestjs integration] fastify HTTP adapter detection now works correctly for response headers (#938)

* fix: [nestjs integration] fastify HTTP adapter detection now works correctly for response headers

- fixed a bug where Fastify responses were incorrectly processed as Express due to overlapping method names.
- introduced type guards to differentiate between Express and Fastify response objects.
- bumping @trigger.dev/nestjs patch version to 2.3.19

* fix TS type check build error
This commit is contained in:
Eugene Yaroslavtsev
2024-03-22 23:41:21 +09:00
committed by GitHub
parent a49b659701
commit cd8f6b9af0
2 changed files with 43 additions and 9 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"@trigger.dev/nestjs": patch
---
fix: [nestjs integration] fastify HTTP adapter detection now works correctly for response headers
+38 -9
View File
@@ -16,7 +16,7 @@ import {
} from "@nestjs/common"; } from "@nestjs/common";
import { Headers as StandardHeaders, Request as StandardRequest } from "@remix-run/web-fetch"; import { Headers as StandardHeaders, Request as StandardRequest } from "@remix-run/web-fetch";
import { TriggerClient, TriggerClientOptions } from "@trigger.dev/sdk"; import { TriggerClient, TriggerClientOptions } from "@trigger.dev/sdk";
import type { Response } from "express"; import type { Response as ExpressResponse } from "express";
import type { FastifyReply } from "fastify"; import type { FastifyReply } from "fastify";
const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN, OPTIONS_TYPE, ASYNC_OPTIONS_TYPE } = const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN, OPTIONS_TYPE, ASYNC_OPTIONS_TYPE } =
@@ -192,15 +192,24 @@ function createControllerByPath(customProvider: InjectionToken, path: string) {
throw new NotFoundException({ error: "Not found" }); throw new NotFoundException({ error: "Not found" });
} }
if (typeof res.status === "function") { /**
// express * NestJS users mostly use either Express or Fastify, but they have
(res as Response).status(response.status); * different response object APIs, so we need to figure out which one
(res as Response).set(response.headers); * is being used and set the status code and headers accordingly.
} else if (typeof res.code === "function") { */
// fastify if (isExpressResponse(res)) {
(res as FastifyReply).code(response.status); res.status(response.status);
if (response.headers) { if (response.headers) {
(res as FastifyReply).headers(response.headers); // Merges the headers, so no need to iterate over them
res.set(response.headers);
}
} else if (isFastifyReply(res)) {
res.code(response.status);
if (response.headers) {
// Same merge behaviour as Express
res.headers(response.headers);
} }
} else { } else {
throw new InternalServerErrorException( throw new InternalServerErrorException(
@@ -214,3 +223,23 @@ function createControllerByPath(customProvider: InjectionToken, path: string) {
return TriggerDevController; return TriggerDevController;
} }
/**
* Type guard for Express with unique checks
*/
function isExpressResponse(res: unknown): res is ExpressResponse {
return (
typeof (res as ExpressResponse)?.status === "function" &&
typeof (res as ExpressResponse)?.render === "function"
);
}
/**
* Type guard for Fastify with unique checks
*/
function isFastifyReply(res: unknown): res is FastifyReply {
return (
typeof (res as FastifyReply)?.code === "function" &&
typeof (res as FastifyReply)?.headers === "function"
);
}