1
- // Ported to Deno from Next.js source
2
- // https://github.com/vercel/next.js/blob/7280c3ced186bb9a7ae3d7012613ef93f20b0fa9/packages/next/shared/lib/router/utils/prepare-destination.ts
3
- import { Key , match } from 'https://deno.land/x/[email protected] /index.ts'
4
- import { getCookies } from 'https://deno.land/[email protected] /http/cookie.ts'
1
+ /**
2
+ * Various router utils ported to Deno from Next.js source
3
+ * https://github.com/vercel/next.js/blob/7280c3ced186bb9a7ae3d7012613ef93f20b0fa9/packages/next/shared/lib/router/utils/
4
+ * Licence: https://github.com/vercel/next.js/blob/7280c3ced186bb9a7ae3d7012613ef93f20b0fa9/license.md
5
+ *
6
+ * Some types have been re-implemented to be more compatible with Deno or avoid chains of dependent files
7
+ */
8
+
9
+ // Deno imports
10
+ import type { Key } from 'https://deno.land/x/[email protected] /index.ts'
5
11
6
12
import { compile , pathToRegexp } from 'https://deno.land/x/[email protected] /index.ts'
13
+ import { getCookies } from 'https://deno.land/[email protected] /http/cookie.ts'
7
14
8
- // regexp is based on https://github.com/sindresorhus/escape-string-regexp
9
- const reHasRegExp = / [ | \\ { } ( ) [ \] ^ $ + * ? . - ] /
10
- const reReplaceRegExp = / [ | \\ { } ( ) [ \] ^ $ + * ? . - ] / g
15
+ // Inlined/re-implemented types
11
16
12
17
export interface ParsedUrlQuery {
13
18
[ key : string ] : string | string [ ]
14
19
}
15
20
16
21
export interface Params {
22
+ // Yeah, best we get
23
+ // deno-lint-ignore no-explicit-any
17
24
[ param : string ] : any
18
25
}
19
26
@@ -35,6 +42,7 @@ export type Rewrite = {
35
42
basePath ?: false
36
43
locale ?: false
37
44
has ?: RouteHas [ ]
45
+ regex : string
38
46
}
39
47
40
48
export type Header = {
@@ -43,6 +51,7 @@ export type Header = {
43
51
locale ?: false
44
52
headers : Array < { key : string ; value : string } >
45
53
has ?: RouteHas [ ]
54
+ regex : string
46
55
}
47
56
export type Redirect = {
48
57
source : string
@@ -52,8 +61,14 @@ export type Redirect = {
52
61
has ?: RouteHas [ ]
53
62
statusCode ?: number
54
63
permanent ?: boolean
64
+ regex : string
55
65
}
56
66
67
+ // escape-regexp.ts
68
+ // regexp is based on https://github.com/sindresorhus/escape-string-regexp
69
+ const reHasRegExp = / [ | \\ { } ( ) [ \] ^ $ + * ? . - ] /
70
+ const reReplaceRegExp = / [ | \\ { } ( ) [ \] ^ $ + * ? . - ] / g
71
+
57
72
export function escapeStringRegexp ( str : string ) {
58
73
// see also: https://github.com/lodash/lodash/blob/2da024c3b4f9947a48517639de7560457cd4ec6c/escapeRegExp.js#L23
59
74
if ( reHasRegExp . test ( str ) ) {
@@ -62,6 +77,7 @@ export function escapeStringRegexp(str: string) {
62
77
return str
63
78
}
64
79
80
+ // querystring.ts
65
81
export function searchParamsToUrlQuery ( searchParams : URLSearchParams ) : ParsedUrlQuery {
66
82
const query : ParsedUrlQuery = { }
67
83
searchParams . forEach ( ( value , key ) => {
@@ -76,6 +92,7 @@ export function searchParamsToUrlQuery(searchParams: URLSearchParams): ParsedUrl
76
92
return query
77
93
}
78
94
95
+ // parse-url.ts
79
96
interface ParsedUrl {
80
97
hash : string
81
98
hostname ?: string | null
@@ -101,6 +118,7 @@ export function parseUrl(url: string): ParsedUrl {
101
118
}
102
119
}
103
120
121
+ // prepare-destination.ts
104
122
// Changed to use WHATWG Fetch Request instead of IncomingMessage
105
123
export function matchHas ( req : Pick < Request , 'headers' | 'url' > , has : RouteHas [ ] , query : Params ) : false | Params {
106
124
const params : Params = { }
@@ -109,22 +127,19 @@ export function matchHas(req: Pick<Request, 'headers' | 'url'>, has: RouteHas[],
109
127
const allMatch = has . every ( ( hasItem ) => {
110
128
let value : undefined | string | null
111
129
let key = hasItem . key
112
- if ( ! key ) {
113
- return true
114
- }
115
130
116
131
switch ( hasItem . type ) {
117
132
case 'header' : {
118
- key = key . toLowerCase ( )
133
+ key = hasItem . key . toLowerCase ( )
119
134
value = req . headers . get ( key )
120
135
break
121
136
}
122
137
case 'cookie' : {
123
- value = cookies [ key ]
138
+ value = cookies [ hasItem . key ]
124
139
break
125
140
}
126
141
case 'query' : {
127
- value = query [ key ]
142
+ value = query [ hasItem . key ]
128
143
break
129
144
}
130
145
case 'host' : {
@@ -135,12 +150,13 @@ export function matchHas(req: Pick<Request, 'headers' | 'url'>, has: RouteHas[],
135
150
break
136
151
}
137
152
}
138
- if ( ! hasItem . value && value ) {
153
+ if ( ! hasItem . value && value && key ) {
139
154
params [ getSafeParamName ( key ) ] = value
140
155
return true
141
156
} else if ( value ) {
142
157
const matcher = new RegExp ( `^${ hasItem . value } $` )
143
158
const matches = Array . isArray ( value ) ? value . slice ( - 1 ) [ 0 ] . match ( matcher ) : value . match ( matcher )
159
+
144
160
if ( matches ) {
145
161
if ( Array . isArray ( matches ) ) {
146
162
if ( matches . groups ) {
@@ -205,8 +221,6 @@ export function prepareDestination(args: {
205
221
escapedDestination = escapeSegment ( escapedDestination , param )
206
222
}
207
223
208
- console . log ( { escapedDestination, params : args . params } )
209
-
210
224
const parsedDestination : ParsedUrl = parseUrl ( escapedDestination )
211
225
const destQuery = parsedDestination . query
212
226
const destPath = unescapeSegments ( `${ parsedDestination . pathname ! } ${ parsedDestination . hash || '' } ` )
@@ -319,3 +333,11 @@ function escapeSegment(str: string, segmentName: string) {
319
333
function unescapeSegments ( str : string ) {
320
334
return str . replace ( / _ _ E S C _ C O L O N _ / gi, ':' )
321
335
}
336
+
337
+ // is-dynamic.ts
338
+ // Identify /[param]/ in route string
339
+ const TEST_ROUTE = / \/ \[ [ ^ / ] + ?\] (? = \/ | $ ) /
340
+
341
+ export function isDynamicRoute ( route : string ) : boolean {
342
+ return TEST_ROUTE . test ( route )
343
+ }
0 commit comments