@@ -5,7 +5,7 @@ import { Readable } from "node:stream";
5
5
import { BuildId , HtmlPages , NextConfig } from "config/index.js" ;
6
6
import type { IncomingMessage } from "http/index.js" ;
7
7
import { OpenNextNodeResponse } from "http/openNextResponse.js" ;
8
- import { parseHeaders } from "http/util.js" ;
8
+ import { getQueryFromIterator , parseHeaders } from "http/util.js" ;
9
9
import type {
10
10
FunctionsConfigManifest ,
11
11
MiddlewareManifest ,
@@ -38,13 +38,11 @@ export function isExternal(url?: string, host?: string) {
38
38
export function convertFromQueryString ( query : string ) {
39
39
if ( query === "" ) return { } ;
40
40
const queryParts = query . split ( "&" ) ;
41
- return queryParts . reduce (
42
- ( acc , part ) => {
43
- const [ key , value ] = part . split ( "=" ) ;
44
- acc [ key ] = value ;
45
- return acc ;
46
- } ,
47
- { } as Record < string , string > ,
41
+ return getQueryFromIterator (
42
+ queryParts . map ( ( p ) => {
43
+ const [ key , value ] = p . split ( "=" ) ;
44
+ return [ key , value ] as const ;
45
+ } ) ,
48
46
) ;
49
47
}
50
48
@@ -122,23 +120,20 @@ export function convertRes(res: OpenNextNodeResponse): InternalResult {
122
120
* Make sure that multi-value query parameters are transformed to
123
121
* ?key=value1&key=value2&... so that Next converts those parameters
124
122
* to an array when reading the query parameters
123
+ * query should be properly encoded before using this function
125
124
* @__PURE__
126
125
*/
127
126
export function convertToQueryString ( query : Record < string , string | string [ ] > ) {
128
- // URLSearchParams is a representation of the PARSED query.
129
- // So we must decode the value before appending it to the URLSearchParams.
130
- // https://stackoverflow.com/a/45516812
131
- const urlQuery = new URLSearchParams ( ) ;
127
+ const queryStrings : string [ ] = [ ] ;
132
128
Object . entries ( query ) . forEach ( ( [ key , value ] ) => {
133
129
if ( Array . isArray ( value ) ) {
134
- value . forEach ( ( entry ) => urlQuery . append ( key , decodeURIComponent ( entry ) ) ) ;
130
+ value . forEach ( ( entry ) => queryStrings . push ( ` ${ key } = ${ entry } ` ) ) ;
135
131
} else {
136
- urlQuery . append ( key , decodeURIComponent ( value ) ) ;
132
+ queryStrings . push ( ` ${ key } = ${ value } ` ) ;
137
133
}
138
134
} ) ;
139
- const queryString = urlQuery . toString ( ) ;
140
135
141
- return queryString ? `?${ queryString } ` : "" ;
136
+ return queryStrings . length > 0 ? `?${ queryStrings . join ( "&" ) } ` : "" ;
142
137
}
143
138
144
139
/**
@@ -182,11 +177,15 @@ export function getMiddlewareMatch(
182
177
*
183
178
* @__PURE__
184
179
*/
185
- export function escapeRegex ( str : string ) {
186
- return str
180
+ export function escapeRegex (
181
+ str : string ,
182
+ { isPath } : { isPath ?: boolean } = { } ,
183
+ ) {
184
+ const result = str
187
185
. replaceAll ( "(.)" , "_µ1_" )
188
186
. replaceAll ( "(..)" , "_µ2_" )
189
187
. replaceAll ( "(...)" , "_µ3_" ) ;
188
+ return isPath ? result : result . replaceAll ( "+" , "_µ4_" ) ;
190
189
}
191
190
192
191
/**
@@ -197,7 +196,8 @@ export function unescapeRegex(str: string) {
197
196
return str
198
197
. replaceAll ( "_µ1_" , "(.)" )
199
198
. replaceAll ( "_µ2_" , "(..)" )
200
- . replaceAll ( "_µ3_" , "(...)" ) ;
199
+ . replaceAll ( "_µ3_" , "(...)" )
200
+ . replaceAll ( "_µ4_" , "+" ) ;
201
201
}
202
202
203
203
/**
0 commit comments