File tree Expand file tree Collapse file tree
libs/ts-rest/core/src/lib Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1+ ---
2+ ' @ts-rest/core ' : minor
3+ ---
4+
5+ feat: ` @ts-rest/core ` : Add support for ` x-www-form-urlencoded ` content-type to core client
Original file line number Diff line number Diff line change @@ -61,6 +61,15 @@ const postsRouter = c.router({
6161 authorId : z . string ( ) ,
6262 } ) ,
6363 } ,
64+ createPostXForm : {
65+ method : 'POST' ,
66+ path : '/posts' ,
67+ responses : {
68+ 200 : c . response < Post > ( ) ,
69+ } ,
70+ body : z . string ( ) ,
71+ contentType : 'application/x-www-form-urlencoded'
72+ } ,
6473 mutationWithQuery : {
6574 method : 'POST' ,
6675 path : '/posts' ,
@@ -325,7 +334,7 @@ describe('client', () => {
325334 published : true ,
326335 filter : { title : 'test' } ,
327336 } ,
328-
337+
329338 } ) ;
330339
331340 expect ( result . body ) . toStrictEqual ( value ) ;
@@ -436,6 +445,32 @@ describe('client', () => {
436445 expect ( result . headers . get ( 'Content-Type' ) ) . toBe ( 'application/json' ) ;
437446 } ) ;
438447
448+ it ( 'w/ body and content-type header' , async ( ) => {
449+ const value = "key=value" ;
450+ fetchMock . postOnce (
451+ {
452+ url : 'https://api.com/posts' ,
453+ headers : {
454+ "content-type" : "application/x-www-form-urlencoded"
455+ }
456+ } ,
457+ {
458+ body : value ,
459+ status : 200 ,
460+ headers : {
461+ "content-type" : "application/x-www-form-urlencoded"
462+ }
463+ }
464+ ) ;
465+
466+ const result = await client . posts . createPostXForm ( {
467+ body : "key=value" ,
468+ } ) ;
469+
470+ expect ( result . status ) . toBe ( 200 ) ;
471+ expect ( result . headers . get ( 'Content-Type' ) ) . toBe ( 'application/x-www-form-urlencoded' ) ;
472+ } ) ;
473+
439474 it ( 'w/ query params' , async ( ) => {
440475 fetchMock . postOnce (
441476 {
Original file line number Diff line number Diff line change @@ -221,6 +221,27 @@ export const fetchApi = ({
221221 } ) ;
222222 }
223223
224+ if ( route . method !== 'GET' && route . contentType === 'application/x-www-form-urlencoded' ) {
225+ const headers = {
226+ ...combinedHeaders ,
227+ 'content-type' : 'application/x-www-form-urlencoded' ,
228+ }
229+ return apiFetcher ( {
230+ route,
231+ path,
232+ method : route . method ,
233+ credentials : clientArgs . credentials ,
234+ headers,
235+ body : body instanceof FormData ? body : createFormData ( body ) ,
236+ rawBody : body ,
237+ rawQuery : query ,
238+ contentType : 'application/x-www-form-urlencoded' ,
239+ signal,
240+ next,
241+ ...extraInputArgs ,
242+ } ) ;
243+ }
244+
224245 const includeContentTypeHeader =
225246 route . method !== 'GET' && body !== null && body !== undefined ;
226247
Original file line number Diff line number Diff line change @@ -54,7 +54,7 @@ export type AppRouteQuery = AppRouteCommon & {
5454 */
5555export type AppRouteMutation = AppRouteCommon & {
5656 method : 'POST' | 'DELETE' | 'PUT' | 'PATCH' ;
57- contentType ?: 'application/json' | 'multipart/form-data' ;
57+ contentType ?: 'application/json' | 'multipart/form-data' | 'application/x-www-form-urlencoded' ;
5858 body : ContractAnyType ;
5959} ;
6060
You can’t perform that action at this time.
0 commit comments