@@ -5,7 +5,7 @@ import { Readable } from "node:stream";
55import { BuildId , HtmlPages , NextConfig } from "config/index.js" ;
66import type { IncomingMessage } from "http/index.js" ;
77import { OpenNextNodeResponse } from "http/openNextResponse.js" ;
8- import { parseHeaders } from "http/util.js" ;
8+ import { getQueryFromIterator , parseHeaders } from "http/util.js" ;
99import type {
1010 FunctionsConfigManifest ,
1111 MiddlewareManifest ,
@@ -38,13 +38,11 @@ export function isExternal(url?: string, host?: string) {
3838export function convertFromQueryString ( query : string ) {
3939 if ( query === "" ) return { } ;
4040 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+ } ) ,
4846 ) ;
4947}
5048
@@ -122,23 +120,20 @@ export function convertRes(res: OpenNextNodeResponse): InternalResult {
122120 * Make sure that multi-value query parameters are transformed to
123121 * ?key=value1&key=value2&... so that Next converts those parameters
124122 * to an array when reading the query parameters
123+ * query should be properly encoded before using this function
125124 * @__PURE__
126125 */
127126export 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 [ ] = [ ] ;
132128 Object . entries ( query ) . forEach ( ( [ key , value ] ) => {
133129 if ( Array . isArray ( value ) ) {
134- value . forEach ( ( entry ) => urlQuery . append ( key , decodeURIComponent ( entry ) ) ) ;
130+ value . forEach ( ( entry ) => queryStrings . push ( ` ${ key } = ${ entry } ` ) ) ;
135131 } else {
136- urlQuery . append ( key , decodeURIComponent ( value ) ) ;
132+ queryStrings . push ( ` ${ key } = ${ value } ` ) ;
137133 }
138134 } ) ;
139- const queryString = urlQuery . toString ( ) ;
140135
141- return queryString ? `?${ queryString } ` : "" ;
136+ return queryStrings . length > 0 ? `?${ queryStrings . join ( "&" ) } ` : "" ;
142137}
143138
144139/**
@@ -182,11 +177,15 @@ export function getMiddlewareMatch(
182177 *
183178 * @__PURE__
184179 */
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
187185 . replaceAll ( "(.)" , "_µ1_" )
188186 . replaceAll ( "(..)" , "_µ2_" )
189187 . replaceAll ( "(...)" , "_µ3_" ) ;
188+ return isPath ? result : result . replaceAll ( "+" , "_µ4_" ) ;
190189}
191190
192191/**
@@ -197,7 +196,8 @@ export function unescapeRegex(str: string) {
197196 return str
198197 . replaceAll ( "_µ1_" , "(.)" )
199198 . replaceAll ( "_µ2_" , "(..)" )
200- . replaceAll ( "_µ3_" , "(...)" ) ;
199+ . replaceAll ( "_µ3_" , "(...)" )
200+ . replaceAll ( "_µ4_" , "+" ) ;
201201}
202202
203203/**
0 commit comments