@@ -49,7 +49,7 @@ export const createClient = (config: Config = {}): Client => {
49
49
ResolvedRequestOptions
50
50
> ( ) ;
51
51
52
- // Resolve final options, serialized body, network body and URL
52
+ // precompute serialized / network body
53
53
const resolveOptions = async ( options : RequestOptions ) => {
54
54
const opts = {
55
55
..._config ,
@@ -73,28 +73,28 @@ export const createClient = (config: Config = {}): Client => {
73
73
opts . serializedBody = opts . bodySerializer ( opts . body ) ;
74
74
}
75
75
76
- // remove Content-Type header if body is empty to avoid sending invalid requests
76
+ // remove Content-Type if body is empty to avoid invalid requests
77
77
if ( opts . body === undefined || opts . serializedBody === '' ) {
78
78
opts . headers . delete ( 'Content-Type' ) ;
79
79
}
80
80
81
- // If user provides a raw body (no serializer), adjust Content-Type sensibly.
82
- // Avoid overriding explicit user-defined headers; only correct the default JSON header.
81
+ // if a raw body is provided (no serializer), adjust Content-Type only when it
82
+ // equals the default JSON value to better match the concrete body type
83
83
if (
84
84
opts . body !== undefined &&
85
85
opts . bodySerializer === null &&
86
86
( opts . headers . get ( 'Content-Type' ) || '' ) . toLowerCase ( ) ===
87
- 'application/json'
87
+ 'application/json'
88
88
) {
89
89
const b : unknown = opts . body ;
90
90
if ( typeof FormData !== 'undefined' && b instanceof FormData ) {
91
- // Let the runtime set proper boundary
91
+ // let the runtime set the multipart boundary
92
92
opts . headers . delete ( 'Content-Type' ) ;
93
93
} else if (
94
94
typeof URLSearchParams !== 'undefined' &&
95
95
b instanceof URLSearchParams
96
96
) {
97
- // Set standard urlencoded content type with charset
97
+ // standard urlencoded content type (+ charset)
98
98
opts . headers . set (
99
99
'Content-Type' ,
100
100
'application/x-www-form-urlencoded;charset=UTF-8' ,
@@ -104,13 +104,13 @@ export const createClient = (config: Config = {}): Client => {
104
104
if ( t ) {
105
105
opts . headers . set ( 'Content-Type' , t ) ;
106
106
} else {
107
- // No known type for the blob : avoid sending misleading JSON header
107
+ // unknown blob type: avoid sending a misleading JSON header
108
108
opts . headers . delete ( 'Content-Type' ) ;
109
109
}
110
110
}
111
111
}
112
112
113
- // Precompute network body for retries and consistent handling
113
+ // precompute network body (stability for retries and interceptors)
114
114
const networkBody = getValidRequestBody ( opts ) as
115
115
| RequestInit [ 'body' ]
116
116
| null
@@ -121,7 +121,7 @@ export const createClient = (config: Config = {}): Client => {
121
121
return { networkBody, opts, url } ;
122
122
} ;
123
123
124
- // Apply request interceptors to a Request and reflect header/method/signal
124
+ // apply request interceptors and mirror header/method/signal back to opts
125
125
const applyRequestInterceptors = async (
126
126
request : Request ,
127
127
opts : ResolvedRequestOptions ,
@@ -131,18 +131,17 @@ export const createClient = (config: Config = {}): Client => {
131
131
request = await fn ( request , opts ) ;
132
132
}
133
133
}
134
- // Reflect any interceptor changes into opts used for network and downstream
134
+ // reflect interceptor changes into opts used by the network layer
135
135
opts . headers = request . headers ;
136
136
opts . method = request . method as Uppercase < HttpMethod > ;
137
- // Note: we intentionally ignore request.body changes from interceptors to
138
- // avoid turning serialized bodies into streams. Body is sourced solely
139
- // from getValidRequestBody(options) for consistency.
140
- // Attempt to reflect possible signal changes
137
+ // ignore request.body changes to avoid turning serialized bodies into streams
138
+ // body comes only from getValidRequestBody(options)
139
+ // reflect signal if present
141
140
opts . signal = ( request as any ) . signal as AbortSignal | undefined ;
142
141
return request ;
143
142
} ;
144
143
145
- // Build ofetch options with stable retry logic based on body repeatability
144
+ // build ofetch options with stable retry logic based on body repeatability
146
145
const buildNetworkOptions = (
147
146
opts : ResolvedRequestOptions ,
148
147
body : BodyInit | null | undefined ,
@@ -160,13 +159,13 @@ export const createClient = (config: Config = {}): Client => {
160
159
opts,
161
160
url,
162
161
} = await resolveOptions ( options as any ) ;
163
- // Compute response type mapping once
162
+ // map parseAs -> ofetch responseType once per request
164
163
const ofetchResponseType : OfetchResponseType | undefined =
165
164
mapParseAsToResponseType ( opts . parseAs , opts . responseType ) ;
166
165
167
166
const $ofetch = opts . ofetch ?? ofetch ;
168
167
169
- // Always create Request pre- network (align with client-fetch)
168
+ // create Request before network to run middleware consistently
170
169
const networkBody = initialNetworkBody ;
171
170
const requestInit : ReqInit = {
172
171
body : networkBody ,
@@ -180,7 +179,7 @@ export const createClient = (config: Config = {}): Client => {
180
179
request = await applyRequestInterceptors ( request , opts ) ;
181
180
const finalUrl = request . url ;
182
181
183
- // Build ofetch options and perform the request
182
+ // build ofetch options and perform the request (.raw keeps the Response)
184
183
const responseOptions = buildNetworkOptions (
185
184
opts as ResolvedRequestOptions ,
186
185
networkBody ,
@@ -210,7 +209,7 @@ export const createClient = (config: Config = {}): Client => {
210
209
}
211
210
}
212
211
213
- // Ensure error is never undefined after interceptors
212
+ // ensure error is never undefined after interceptors
214
213
finalError = ( finalError as any ) || ( { } as string ) ;
215
214
216
215
if ( opts . throwOnError ) {
@@ -228,7 +227,7 @@ export const createClient = (config: Config = {}): Client => {
228
227
( method : Uppercase < HttpMethod > ) => async ( options : RequestOptions ) => {
229
228
const { networkBody, opts, url } = await resolveOptions ( options ) ;
230
229
const optsForSse : any = { ...opts } ;
231
- delete optsForSse . body ;
230
+ delete optsForSse . body ; // body is provided via serializedBody below
232
231
return createSseClient ( {
233
232
...optsForSse ,
234
233
fetch : opts . fetch ,
0 commit comments