@@ -148,7 +148,7 @@ const parseResultFromResponse = async (response: Response, jsonSerializer: JsonS
148
148
149
149
const createFetcher = ( method :'GET' | 'POST' ) => async ( params :Input ) => {
150
150
const headers = new Headers ( params . headers )
151
- let queryParams = ``
151
+ let searchParams : URLSearchParams | null = null
152
152
let body = undefined
153
153
154
154
if ( ! headers . has ( ACCEPT_HEADER ) ) {
@@ -162,13 +162,14 @@ const createFetcher = (method: 'GET' | 'POST') => async (params: Input) => {
162
162
headers . set ( CONTENT_TYPE_HEADER , CONTENT_TYPE_JSON )
163
163
}
164
164
} else {
165
- queryParams = buildQueryParams ( params )
165
+ searchParams = buildQueryParams ( params )
166
166
}
167
167
168
168
const init :RequestInit = { method, headers, body, ...params . fetchOptions }
169
169
170
- let urlResolved = params . url
170
+ let url = new URL ( params . url )
171
171
let initResolved = init
172
+
172
173
if ( params . middleware ) {
173
174
const result = await Promise . resolve (
174
175
params . middleware ( {
@@ -179,14 +180,18 @@ const createFetcher = (method: 'GET' | 'POST') => async (params: Input) => {
179
180
} ) ,
180
181
)
181
182
const { url :urlNew , ...initNew } = result
182
- urlResolved = urlNew
183
+ url = new URL ( urlNew )
183
184
initResolved = initNew
184
185
}
185
- if ( queryParams ) {
186
- urlResolved = `${ urlResolved } ?${ queryParams } `
186
+
187
+ if ( searchParams ) {
188
+ searchParams . forEach ( ( value , name ) => {
189
+ url . searchParams . append ( name , value )
190
+ } )
187
191
}
192
+
188
193
const $fetch = params . fetch ?? fetch
189
- return await $fetch ( urlResolved , initResolved )
194
+ return await $fetch ( url , initResolved )
190
195
}
191
196
192
197
const buildBody = ( params :Input ) => {
@@ -206,26 +211,30 @@ const buildBody = (params: Input) => {
206
211
}
207
212
}
208
213
209
- const buildQueryParams = ( params :Input ) :string => {
214
+ const buildQueryParams = ( params :Input ) :URLSearchParams => {
210
215
const $jsonSerializer = params . fetchOptions . jsonSerializer ?? defaultJsonSerializer
216
+ const searchParams = new URLSearchParams ( )
217
+
211
218
if ( params . request . _tag === `Single` ) {
212
- const search : string [ ] = [ `query= ${ encodeURIComponent ( cleanQuery ( params . request . document . expression ) ) } ` ]
219
+ searchParams . append ( `query` , cleanQuery ( params . request . document . expression ) )
213
220
if ( params . request . variables ) {
214
- search . push ( `variables= ${ encodeURIComponent ( $ jsonSerializer. stringify ( params . request . variables ) ) } ` )
221
+ searchParams . append ( `variables` , $ jsonSerializer. stringify ( params . request . variables ) )
215
222
}
216
223
if ( params . request . document . operationName ) {
217
- search . push ( `operationName= ${ encodeURIComponent ( params . request . document . operationName ) } ` )
224
+ searchParams . append ( `operationName` , params . request . document . operationName )
218
225
}
219
- return search . join ( `&` )
226
+ return searchParams
220
227
} else if ( params . request . _tag === `Batch` ) {
221
228
const variablesSerialized = params . request . variables ?. map ( ( v ) => $jsonSerializer . stringify ( v ) ) ?? [ ]
222
229
const queriesCleaned = params . request . query . map ( cleanQuery )
223
230
const payload = zip ( queriesCleaned , variablesSerialized ) . map ( ( [ query , variables ] ) => ( {
224
231
query,
225
232
variables,
226
233
} ) )
227
- return `query= ${ encodeURIComponent ( $ jsonSerializer. stringify ( payload ) ) } `
234
+ searchParams . append ( `query` , $ jsonSerializer. stringify ( payload ) )
228
235
} else {
229
236
throw casesExhausted ( params . request )
230
237
}
238
+
239
+ return searchParams
231
240
}