@@ -7,14 +7,16 @@ import {
77 ClientInferRequest ,
88 ClientInferResponses ,
99 PartialClientInferRequest ,
10+ NextClientArgs ,
11+ Frameworks
1012} from './infer-types' ;
1113
1214type RecursiveProxyObj < T extends AppRouter , TClientArgs extends ClientArgs > = {
1315 [ TKey in keyof T ] : T [ TKey ] extends AppRoute
14- ? AppRouteFunction < T [ TKey ] , TClientArgs >
15- : T [ TKey ] extends AppRouter
16- ? RecursiveProxyObj < T [ TKey ] , TClientArgs >
17- : never ;
16+ ? AppRouteFunction < T [ TKey ] , TClientArgs >
17+ : T [ TKey ] extends AppRouter
18+ ? RecursiveProxyObj < T [ TKey ] , TClientArgs >
19+ : never ;
1820} ;
1921
2022/**
@@ -59,6 +61,12 @@ export type ApiFetcherArgs = {
5961 contentType : AppRouteMutation [ 'contentType' ] ;
6062 credentials ?: RequestCredentials ;
6163 signal ?: AbortSignal ;
64+ cache ?: RequestCache ;
65+ /**
66+ * Only to be used by `@ts-rest/next`.
67+ * You can obtain a Nextjs Client by calling `initNextClient`
68+ */
69+ next ?: NextClientArgs [ 'next' ] | undefined ;
6270} ;
6371
6472export type ApiFetcher = ( args : ApiFetcherArgs ) => Promise < {
@@ -81,14 +89,20 @@ export const tsRestFetchApi: ApiFetcher = async ({
8189 body,
8290 credentials,
8391 signal,
92+ cache,
93+ next
8494} ) => {
8595 const result = await fetch ( path , {
8696 method,
8797 headers,
8898 body,
8999 credentials,
90100 signal,
91- } ) ;
101+ cache,
102+ next
103+ // we must type cast here because the typescript types for RequestInit
104+ // do not include properties like "next" for Frameworks (like Nextjs)
105+ } as RequestInit ) ;
92106 const contentType = result . headers . get ( 'content-type' ) ;
93107
94108 if ( contentType ?. includes ( "application/" ) && contentType ?. includes ( 'json' ) ) {
@@ -143,6 +157,7 @@ export const fetchApi = ({
143157 extraInputArgs,
144158 headers,
145159 signal,
160+ next
146161} : {
147162 path : string ;
148163 clientArgs : ClientArgs ;
@@ -152,6 +167,12 @@ export const fetchApi = ({
152167 extraInputArgs : Record < string , unknown > ;
153168 headers : Record < string , string | undefined > ;
154169 signal ?: AbortSignal ;
170+ // ---- Framework specific ----
171+ /**
172+ * only to be used by @ts-rest/next
173+ * You can obtain a Nextjs Client by calling `initNextClient`
174+ */
175+ next ?: NextClientArgs [ 'next' ] | undefined ;
155176} ) => {
156177 const apiFetcher = clientArgs . api || tsRestFetchApi ;
157178
@@ -179,6 +200,7 @@ export const fetchApi = ({
179200 rawQuery : query ,
180201 contentType : 'multipart/form-data' ,
181202 signal,
203+ next,
182204 ...extraInputArgs ,
183205 } ) ;
184206 }
@@ -198,6 +220,7 @@ export const fetchApi = ({
198220 rawQuery : query ,
199221 contentType : route . method !== 'GET' ? 'application/json' : undefined ,
200222 signal,
223+ next,
201224 ...extraInputArgs ,
202225 } ) ;
203226} ;
@@ -220,16 +243,21 @@ export const getCompleteUrl = (
220243 return `${ baseUrl } ${ path } ${ queryComponent } ` ;
221244} ;
222245
223- export const getRouteQuery = < TAppRoute extends AppRoute > (
246+ export const getRouteQuery = < TAppRoute extends AppRoute , Framework extends Frameworks = 'none' > (
224247 route : TAppRoute ,
225- clientArgs : InitClientArgs
248+ clientArgs : InitClientArgs ,
226249) => {
227250 const knownResponseStatuses = Object . keys ( route . responses ) ;
228251 return async (
229- inputArgs ?: ClientInferRequest < AppRouteMutation , ClientArgs >
252+ inputArgs ?: Framework extends 'nextjs' ?
253+ ClientInferRequest < AppRouteMutation , ClientArgs , 'nextjs' >
254+ : ClientInferRequest < AppRouteMutation , ClientArgs >
230255 ) => {
231- const { query, params, body, headers, extraHeaders, ...extraInputArgs } =
232- inputArgs || { } ;
256+ const { query, params, body, headers, extraHeaders, next, ...extraInputArgs } =
257+ // ---- Merge all framework Request infer types ----
258+ inputArgs as ClientInferRequest < AppRouteMutation , ClientArgs , 'nextjs' > &
259+ ClientInferRequest < AppRouteMutation , ClientArgs >
260+ || { } ;
233261
234262 const completeUrl = getCompleteUrl (
235263 query ,
@@ -246,6 +274,7 @@ export const getRouteQuery = <TAppRoute extends AppRoute>(
246274 body,
247275 query,
248276 extraInputArgs,
277+ next,
249278 headers : {
250279 ...extraHeaders ,
251280 ...headers ,
@@ -287,7 +316,7 @@ export const initClient = <
287316 return Object . fromEntries (
288317 Object . entries ( router ) . map ( ( [ key , subRouter ] ) => {
289318 if ( isAppRoute ( subRouter ) ) {
290- return [ key , getRouteQuery ( subRouter , args ) ] ;
319+ return [ key , getRouteQuery < typeof subRouter > ( subRouter , args ) ] ;
291320 } else {
292321 return [ key , initClient ( subRouter , args ) ] ;
293322 }
0 commit comments