@@ -3,6 +3,8 @@ import { createExpressEndpoints, initServer } from './ts-rest-express';
33import * as supertest from 'supertest' ;
44import * as express from 'express' ;
55import { z } from 'zod' ;
6+ import * as fs from 'node:fs' ;
7+ import path = require( 'path' ) ;
68
79const c = initContract ( ) ;
810const postsRouter = c . router ( {
@@ -174,3 +176,70 @@ describe('ts-rest-express', () => {
174176 ) ;
175177 } ) ;
176178} ) ;
179+
180+ describe ( 'download' , ( ) => {
181+ it ( 'allows download image' , async ( ) => {
182+ const c = initContract ( ) ;
183+
184+ const contract = c . router ( {
185+ getFile : {
186+ method : 'GET' ,
187+ path : `/image` ,
188+ headers : z . object ( {
189+ 'Content-Type' : z . string ( ) . optional ( ) ,
190+ 'Content-disposition' : z . string ( ) . optional ( ) ,
191+ } ) ,
192+ responses : {
193+ 200 : z . unknown ( ) ,
194+ } ,
195+ summary : 'Get an image' ,
196+ } ,
197+ } ) ;
198+
199+ const s = initServer ( ) ;
200+ const originalFilePath = path . join ( __dirname , 'assets/logo.png' ) ;
201+
202+ const router = s . router ( contract , {
203+ getFile : async ( { res } ) => {
204+ res . setHeader ( 'Content-type' , 'image/png' ) ;
205+
206+ return {
207+ status : 200 ,
208+ body : fs . createReadStream ( originalFilePath ) ,
209+ } ;
210+ } ,
211+ } ) ;
212+
213+ const app = express ( ) ;
214+
215+ app . use ( express . json ( ) ) ;
216+ app . use ( express . urlencoded ( { extended : true } ) ) ;
217+
218+ createExpressEndpoints ( contract , router , app , {
219+ responseValidation : true ,
220+ } ) ;
221+
222+ app . use (
223+ (
224+ err : any ,
225+ req : express . Request ,
226+ res : express . Response ,
227+ next : express . NextFunction ,
228+ ) => {
229+ if ( err instanceof ResponseValidationError ) {
230+ res . status ( 500 ) . send ( 'Response validation failed' ) ;
231+ return ;
232+ }
233+
234+ next ( err ) ;
235+ } ,
236+ ) ;
237+
238+ const responseImage = await supertest ( app ) . get ( '/image' ) ;
239+ expect ( responseImage . status ) . toEqual ( 200 ) ;
240+ expect ( responseImage . body . toString ( ) ) . toEqual ( fs . readFileSync ( originalFilePath , { encoding : 'utf-8' } ) ) ;
241+ expect ( responseImage . headers [ 'content-type' ] ) . toEqual (
242+ 'image/png' ,
243+ ) ;
244+ } ) ;
245+ } ) ;
0 commit comments