@@ -2,12 +2,14 @@ import { Match, match } from 'https://deno.land/x/path_to_regexp@v6.2.1/index.ts
2
2
3
3
import {
4
4
compileNonPath ,
5
+ DynamicRoute ,
5
6
Header ,
6
7
matchHas as nextMatchHas ,
7
8
prepareDestination ,
8
9
Redirect ,
9
10
Rewrite ,
10
11
RouteHas ,
12
+ RoutesManifest ,
11
13
searchParamsToUrlQuery ,
12
14
} from './next-utils.ts'
13
15
@@ -18,17 +20,12 @@ export type Rule = Rewrite | Header | Redirect
18
20
* Converts Next.js's internal parsed URL response to a `URL` object.
19
21
*/
20
22
21
- function preparedDestinationToUrl ( {
22
- newUrl,
23
- destQuery,
24
- parsedDestination,
25
- } : ReturnType < typeof prepareDestination > ) : URL {
23
+ function preparedDestinationToUrl ( { newUrl, parsedDestination } : ReturnType < typeof prepareDestination > ) : URL {
26
24
const transformedUrl = new URL ( newUrl , 'http://n' )
27
25
transformedUrl . hostname = parsedDestination . hostname ?? ''
28
26
transformedUrl . port = parsedDestination . port ?? ''
29
27
transformedUrl . protocol = parsedDestination . protocol ?? ''
30
-
31
- for ( const [ name , value ] of Object . entries ( destQuery ) ) {
28
+ for ( const [ name , value ] of Object . entries ( parsedDestination . query ) ) {
32
29
transformedUrl . searchParams . set ( name , String ( value ) )
33
30
}
34
31
return transformedUrl
@@ -212,11 +209,11 @@ export function applyRewrites({
212
209
request,
213
210
rules,
214
211
staticRoutes,
215
- checkStaticRoutes,
212
+ checkStaticRoutes = false ,
216
213
} : {
217
214
request : Request
218
215
rules : Rewrite [ ]
219
- checkStaticRoutes : boolean
216
+ checkStaticRoutes ? : boolean
220
217
staticRoutes ?: Set < string >
221
218
} ) : Request | false {
222
219
let result : Request | false = false
@@ -230,18 +227,101 @@ export function applyRewrites({
230
227
const rewritten = applyRewriteRule ( { request, rule } )
231
228
if ( rewritten ) {
232
229
result = rewritten
230
+ if ( ! checkStaticRoutes ) {
231
+ continue
232
+ }
233
+ const { pathname } = new URL ( rewritten . url )
233
234
// If a static route is matched, then we exit early
234
- if ( checkStaticRoutes && staticRoutes ! . has ( new URL ( result . url ) . pathname ) ) {
235
+ if ( staticRoutes ! . has ( pathname ) || pathname . startsWith ( '/_next/static/' ) ) {
236
+ result . headers . set ( 'x-matched-path' , pathname )
235
237
return result
236
238
}
237
239
}
238
240
}
239
241
return result
240
242
}
241
243
242
- export function matchesStaticRoute ( route : string , staticRoutes : Set < string > , staticFiles : Set < string > ) : boolean {
243
- if ( staticFiles . has ( route ) ) {
244
- return true
244
+ export function matchDynamicRoute ( request : Request , routes : DynamicRoute [ ] ) : string | false {
245
+ const { pathname } = new URL ( request . url )
246
+ const match = routes . find ( ( route ) => {
247
+ return new RegExp ( route . regex ) . test ( pathname )
248
+ } )
249
+ if ( match ) {
250
+ return match . page
251
+ }
252
+ return false
253
+ }
254
+
255
+ /**
256
+ * Run the rules that run before middleware
257
+ */
258
+ export function runPreMiddleware ( request : Request , manifest : RoutesManifest ) : Request | Response {
259
+ const output : Request = applyHeaders ( request , manifest . headers )
260
+ const redirect = applyRedirects ( output , manifest . redirects )
261
+ if ( redirect ) {
262
+ return Response . redirect ( redirect . url , redirect . status )
245
263
}
246
- return staticRoutes . has ( route . endsWith ( '/' ) ? route . slice ( 0 , - 1 ) : route )
264
+ return output
265
+ }
266
+
267
+ /**
268
+ * Run the rules that run after middleware
269
+ */
270
+ export function runPostMiddleware (
271
+ request : Request ,
272
+ manifest : RoutesManifest ,
273
+ staticRoutes : Set < string > ,
274
+ skipBeforeFiles = false ,
275
+ ) : Request | Response {
276
+ // Everyone gets the beforeFiles rewrites, unless we're re-running after matching fallback
277
+ let result = skipBeforeFiles
278
+ ? request
279
+ : applyRewrites ( {
280
+ request,
281
+ rules : manifest . rewrites . beforeFiles ,
282
+ } ) || request
283
+
284
+ // Check if it matches a static route or file
285
+ const { pathname } = new URL ( result . url )
286
+ if ( staticRoutes . has ( pathname ) || pathname . startsWith ( '/_next/static/' ) ) {
287
+ result . headers . set ( 'x-matched-path' , pathname )
288
+ return result
289
+ }
290
+
291
+ // afterFiles rewrites also check if it matches a static file after every match
292
+ const afterRewrite = applyRewrites ( {
293
+ request : result ,
294
+ rules : manifest . rewrites . afterFiles ,
295
+ checkStaticRoutes : true ,
296
+ staticRoutes,
297
+ } )
298
+
299
+ if ( afterRewrite ) {
300
+ result = afterRewrite
301
+ // If we match a rewrite, we check if it matches a static route or file
302
+ // If it does, we return right away
303
+ if ( afterRewrite . headers . has ( 'x-matched-path' ) ) {
304
+ return afterRewrite
305
+ }
306
+ }
307
+
308
+ // Now we check dynamic routes, so we can
309
+ const dynamicRoute = matchDynamicRoute ( result , manifest . dynamicRoutes )
310
+ if ( dynamicRoute ) {
311
+ result . headers . set ( 'x-matched-path' , dynamicRoute )
312
+ return result
313
+ }
314
+
315
+ // Finally, check for fallback rewrites
316
+ const fallbackRewrite = applyRewrites ( {
317
+ request : result ,
318
+ rules : manifest . rewrites . fallback ,
319
+ } )
320
+
321
+ // If the fallback matched, we go right back to checking for static routes
322
+ if ( fallbackRewrite ) {
323
+ return runPostMiddleware ( fallbackRewrite , manifest , staticRoutes , true )
324
+ }
325
+ // 404
326
+ return result
247
327
}
0 commit comments