1
1
// deno-lint-ignore-file
2
- import { Router , serve , Server , rg } from './deps.ts'
2
+ import { Router , serve , Server , rg , pushMiddleware } from './deps.ts'
3
3
import { NextFunction , RHandler as Handler , Middleware , UseMethodParams } from './types.ts'
4
4
import { onErrorHandler , ErrorHandler } from './onError.ts'
5
- import { setImmediate } from 'https://deno.land/std@0.88 .0/node/timers.ts'
5
+ import { setImmediate } from 'https://deno.land/std@0.93 .0/node/timers.ts'
6
6
import type { Request } from './request.ts'
7
7
import type { Response } from './response.ts'
8
8
import { getURLParams , getPathname } from './utils/parseUrl.ts'
9
9
import { extendMiddleware } from './extend.ts'
10
- import * as path from 'https://deno.land/std@0.88 .0/path/mod.ts'
10
+ import * as path from 'https://deno.land/std@0.93 .0/path/mod.ts'
11
11
12
12
const lead = ( x : string ) => ( x . charCodeAt ( 0 ) === 47 ? x : '/' + x )
13
13
14
- const mount = ( fn : App | Handler ) => ( fn instanceof App ? fn . attach : fn )
14
+ const mount = ( fn : any ) => ( fn instanceof App ? fn . attach : fn )
15
15
16
16
declare global {
17
17
namespace tinyhttp {
@@ -140,6 +140,10 @@ export class App<
140
140
applyExtensions ?: ( req : Req , res : Res , next : NextFunction ) => void
141
141
attach : ( req : Req ) => void
142
142
143
+ mountpath = '/'
144
+
145
+ apps : Record < string , App > = { }
146
+
143
147
#eventHandler?: FetchEventListenerObject
144
148
145
149
constructor ( options : AppConstructor < Req , Res > = { } ) {
@@ -215,27 +219,52 @@ export class App<
215
219
use ( ...args : UseMethodParams < Req , Res , App > ) {
216
220
const base = args [ 0 ]
217
221
218
- const fns = args . slice ( 1 )
222
+ const fns = args . slice ( 1 ) . flat ( )
223
+
224
+ if ( base instanceof App ) {
225
+ // Set App parent to current App
226
+ // @ts -ignore
227
+ base . parent = this
228
+
229
+ // Mount on root
230
+ base . mountpath = '/'
231
+
232
+ this . apps [ '/' ] = base
233
+ }
234
+
235
+ const path = typeof base === 'string' ? base : '/'
236
+
237
+ let regex : { keys : string [ ] ; pattern : RegExp }
238
+
239
+ for ( const fn of fns ) {
240
+ if ( fn instanceof App ) {
241
+ regex = rg ( path , true )
242
+
243
+ fn . mountpath = path
244
+
245
+ this . apps [ path ] = fn
246
+
247
+ // @ts -ignore
248
+ fn . parent = this
249
+ }
250
+ }
219
251
220
252
if ( base === '/' ) {
221
- for ( const fn of fns . flat ( ) ) super . use ( base , mount ( fn as Handler ) )
253
+ for ( const fn of fns ) super . use ( base , mount ( fn as Handler ) )
222
254
} else if ( typeof base === 'function' || base instanceof App ) {
223
- super . use ( '/' , [ base , ...fns ] . map ( mount as any ) )
224
- } else if ( fns . some ( ( fn ) => fn instanceof App ) ) {
225
- super . use (
226
- base ,
227
- fns . flatMap ( ( fn ) => {
228
- if ( fn instanceof App ) {
229
- fn = fn as App
230
- fn . mountpath = typeof base === 'string' ? base : '/'
231
-
232
- fn . parent = ( this as unknown ) as App
233
- }
234
-
235
- return mount ( fn as App )
236
- } )
237
- )
238
- } else super . use ( ...args )
255
+ super . use ( '/' , [ base , ...fns ] . map ( mount ) )
256
+ } else if ( Array . isArray ( base ) ) {
257
+ super . use ( '/' , [ ...base , ...fns ] . map ( mount ) )
258
+ } else {
259
+ pushMiddleware ( this . middleware ) ( {
260
+ path : base as string ,
261
+ // @ts -ignore
262
+ regex,
263
+ type : 'mw' ,
264
+ handler : mount ( fns [ 0 ] as Handler ) ,
265
+ handlers : fns . slice ( 1 ) . map ( mount )
266
+ } )
267
+ }
239
268
240
269
return this // chainable
241
270
}
@@ -244,7 +273,7 @@ export class App<
244
273
if ( ! m . path ) m . path = '/'
245
274
m . regex = m . type === 'mw' ? rg ( m . path , true ) : rg ( m . path )
246
275
247
- return ( m . method ? m . method === method : true ) && m . regex . pattern . test ( url )
276
+ return ( m . method ? m . method === method : true ) && m . regex ? .pattern . test ( url )
248
277
} )
249
278
}
250
279
/**
0 commit comments