1+ import type http from 'http'
12import { withoutTrailingSlash } from 'ufo'
2- import { lazyHandle , promisifyHandle } from './handle '
3- import { toEventHandler , createEvent } from './event'
3+ import { defineLazyHandler } from './handler '
4+ import { toEventHandler , createEvent , isEventHandler } from './event'
45import { createError , sendError } from './error'
56import { send , sendStream , isStream , MIMES } from './utils'
6- import type { IncomingMessage , ServerResponse } from './types/node'
7- import type { Handle , LazyHandle , Middleware , PHandle } from './handle'
8- import type { H3EventHandler } from './event'
7+ import type { Handler , LazyHandler , Middleware , PromisifiedHandler } from './types'
8+ import type { EventHandler , CompatibilityEvent } from './event'
99
1010export interface Layer {
1111 route : string
1212 match ?: Matcher
13- handler : H3EventHandler
13+ handler : EventHandler
1414}
1515
1616export type Stack = Layer [ ]
1717
1818export interface InputLayer {
1919 route ?: string
2020 match ?: Matcher
21- handle : Handle | LazyHandle
21+ handler : Handler | LazyHandler
2222 lazy ?: boolean
23+ /**
24+ * @deprecated
25+ */
2326 promisify ?: boolean
2427}
2528
2629export type InputStack = InputLayer [ ]
2730
28- export type Matcher = ( url : string , req ?: IncomingMessage ) => boolean
31+ export type Matcher = ( url : string , event ?: CompatibilityEvent ) => boolean
32+
33+ export type RequestHandler = EventHandler | Handler | Middleware
2934
3035export interface AppUse {
31- ( route : string | string [ ] , handle : Middleware | Middleware [ ] , options ?: Partial < InputLayer > ) : App
32- ( route : string | string [ ] , handle : Handle | Handle [ ] , options ?: Partial < InputLayer > ) : App
33- ( handle : Middleware | Middleware [ ] , options ?: Partial < InputLayer > ) : App
34- ( handle : Handle | Handle [ ] , options ?: Partial < InputLayer > ) : App
36+ ( route : string | string [ ] , handler : RequestHandler | RequestHandler [ ] , options ?: Partial < InputLayer > ) : App
37+ ( handler : RequestHandler | Handler [ ] , options ?: Partial < InputLayer > ) : App
3538 ( options : InputLayer ) : App
3639}
3740
38- export interface App {
39- ( req : IncomingMessage , res : ServerResponse ) : Promise < any >
41+ export type ApPromisifiedHandlerr = ( req : http . IncomingMessage , res : http . ServerResponse ) => Promise < any >
42+
43+ export interface App extends ApPromisifiedHandlerr {
4044 stack : Stack
41- _handle : PHandle
45+ _handler : PromisifiedHandler
4246 use : AppUse
4347}
4448
4549export interface AppOptions {
4650 debug ?: boolean
47- onError ?: ( error : Error , req : IncomingMessage , res : ServerResponse ) => any
51+ onError ?: ( error : Error , event : CompatibilityEvent ) => any
4852}
4953
5054export function createApp ( options : AppOptions = { } ) : App {
5155 const stack : Stack = [ ]
5256
53- const _handle = createHandle ( stack , options )
57+ const _handler = createHandler ( stack , options )
5458
55- // @ts -ignore
56- const app : Partial < App > = function ( req : IncomingMessage , res : ServerResponse ) {
57- return _handle ( req , res ) . catch ( ( error : Error ) => {
59+ const app : App = function ( req , res ) {
60+ const event = createEvent ( req , res )
61+ return _handler ( event ) . catch ( ( error : Error ) => {
5862 if ( options . onError ) {
59- return options . onError ( error , req , res )
63+ return options . onError ( error , event )
6064 }
61- return sendError ( res , error , ! ! options . debug )
65+ return sendError ( event , error , ! ! options . debug )
6266 } )
63- }
67+ } as App
6468
6569 app . stack = stack
66- app . _handle = _handle
70+ app . _handler = _handler
6771
6872 // @ts -ignore
6973 app . use = ( arg1 , arg2 , arg3 ) => use ( app as App , arg1 , arg2 , arg3 )
@@ -73,81 +77,79 @@ export function createApp (options: AppOptions = {}): App {
7377
7478export function use (
7579 app : App ,
76- arg1 : string | Handle | InputLayer | InputLayer [ ] ,
77- arg2 ?: Handle | Partial < InputLayer > | Handle [ ] | Middleware | Middleware [ ] ,
80+ arg1 : string | Handler | InputLayer | InputLayer [ ] ,
81+ arg2 ?: Handler | Partial < InputLayer > | Handler [ ] | Middleware | Middleware [ ] ,
7882 arg3 ?: Partial < InputLayer >
7983) {
8084 if ( Array . isArray ( arg1 ) ) {
8185 arg1 . forEach ( i => use ( app , i , arg2 , arg3 ) )
8286 } else if ( Array . isArray ( arg2 ) ) {
8387 arg2 . forEach ( i => use ( app , arg1 , i , arg3 ) )
8488 } else if ( typeof arg1 === 'string' ) {
85- app . stack . push ( normalizeLayer ( { ...arg3 , route : arg1 , handle : arg2 as Handle } ) )
89+ app . stack . push ( normalizeLayer ( { ...arg3 , route : arg1 , handler : arg2 as Handler } ) )
8690 } else if ( typeof arg1 === 'function' ) {
87- app . stack . push ( normalizeLayer ( { ...arg2 , route : '/' , handle : arg1 as Handle } ) )
91+ app . stack . push ( normalizeLayer ( { ...arg2 , route : '/' , handler : arg1 as Handler } ) )
8892 } else {
8993 app . stack . push ( normalizeLayer ( { ...arg1 } ) )
9094 }
9195 return app
9296}
9397
94- export function createHandle ( stack : Stack , options : AppOptions ) : PHandle {
98+ export function createHandler ( stack : Stack , options : AppOptions ) {
9599 const spacing = options . debug ? 2 : undefined
96- return async function handle ( req : IncomingMessage , res : ServerResponse ) {
97- const event = createEvent ( req , res )
100+ return async function handle ( event : CompatibilityEvent ) {
101+ event . req . originalUrl = event . req . originalUrl || event . req . url || '/'
98102
99- // @ts -ignore express/connect compatibility
100- req . originalUrl = req . originalUrl || req . url || '/'
101- const reqUrl = req . url || '/'
103+ const reqUrl = event . req . url || '/'
102104 for ( const layer of stack ) {
103105 if ( layer . route . length > 1 ) {
104106 if ( ! reqUrl . startsWith ( layer . route ) ) {
105107 continue
106108 }
107- req . url = reqUrl . slice ( layer . route . length ) || '/'
109+ event . req . url = reqUrl . slice ( layer . route . length ) || '/'
108110 } else {
109- req . url = reqUrl
111+ event . req . url = reqUrl
110112 }
111- if ( layer . match && ! layer . match ( req . url as string , req ) ) {
113+ if ( layer . match && ! layer . match ( event . req . url as string , event ) ) {
112114 continue
113115 }
114116 const val = await layer . handler ( event )
115- if ( res . writableEnded ) {
117+ if ( event . res . writableEnded ) {
116118 return
117119 }
118120 const type = typeof val
119121 if ( type === 'string' ) {
120- return send ( res , val , MIMES . html )
122+ return send ( event , val , MIMES . html )
121123 } else if ( isStream ( val ) ) {
122- return sendStream ( res , val )
124+ return sendStream ( event , val )
123125 } else if ( type === 'object' || type === 'boolean' || type === 'number' /* IS_JSON */ ) {
124126 if ( val && ( val as Buffer ) . buffer ) {
125- return send ( res , val )
127+ return send ( event , val )
126128 } else if ( val instanceof Error ) {
127129 throw createError ( val )
128130 } else {
129- return send ( res , JSON . stringify ( val , null , spacing ) , MIMES . json )
131+ return send ( event , JSON . stringify ( val , null , spacing ) , MIMES . json )
130132 }
131133 }
132134 }
133- if ( ! res . writableEnded ) {
135+ if ( ! event . res . writableEnded ) {
134136 throw createError ( { statusCode : 404 , statusMessage : 'Not Found' } )
135137 }
136138 }
137139}
138140
139141function normalizeLayer ( input : InputLayer ) {
140- if ( input . promisify === undefined ) {
141- input . promisify = input . handle . length > 2 /* req, res, next */
142+ let handler = input . handler
143+ if ( ! isEventHandler ( handler ) ) {
144+ if ( input . lazy ) {
145+ handler = defineLazyHandler ( handler as LazyHandler )
146+ }
147+ handler = toEventHandler ( handler )
142148 }
143149
144- const handle = input . lazy
145- ? lazyHandle ( input . handle as LazyHandle , input . promisify )
146- : ( input . promisify ? promisifyHandle ( input . handle ) : input . handle )
147-
148150 return {
149151 route : withoutTrailingSlash ( input . route ) ,
150152 match : input . match ,
151- handler : toEventHandler ( handle )
152- }
153+ handler
154+ } as Layer
153155}
0 commit comments