Skip to content

Commit cdf9b7c

Browse files
authored
feat!: opt-in using event format using defineEventHandler (#74)
1 parent 23ee617 commit cdf9b7c

File tree

3 files changed

+69
-13
lines changed

3 files changed

+69
-13
lines changed

src/app.ts

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import { withoutTrailingSlash } from 'ufo'
2-
import type { IncomingMessage, ServerResponse } from './types/node'
32
import { lazyHandle, promisifyHandle } from './handle'
4-
import type { Handle, LazyHandle, Middleware, PHandle } from './handle'
3+
import { toEventHandler, createEvent } from './event'
54
import { createError, sendError } from './error'
65
import { 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'
79

810
export interface Layer {
911
route: string
1012
match?: Matcher
11-
handle: Handle
13+
handler: H3EventHandler
1214
}
1315

1416
export type Stack = Layer[]
@@ -92,6 +94,8 @@ export function use (
9294
export function createHandle (stack: Stack, options: AppOptions): PHandle {
9395
const spacing = options.debug ? 2 : undefined
9496
return async function handle (req: IncomingMessage, res: ServerResponse) {
97+
const event = createEvent(req, res)
98+
9599
// @ts-ignore express/connect compatibility
96100
req.originalUrl = req.originalUrl || req.url || '/'
97101
const reqUrl = req.url || '/'
@@ -107,7 +111,7 @@ export function createHandle (stack: Stack, options: AppOptions): PHandle {
107111
if (layer.match && !layer.match(req.url as string, req)) {
108112
continue
109113
}
110-
const val = await layer.handle(req, res)
114+
const val = await layer.handler(event)
111115
if (res.writableEnded) {
112116
return
113117
}
@@ -117,7 +121,7 @@ export function createHandle (stack: Stack, options: AppOptions): PHandle {
117121
} else if (isStream(val)) {
118122
return sendStream(res, val)
119123
} else if (type === 'object' || type === 'boolean' || type === 'number' /* IS_JSON */) {
120-
if (val && val.buffer) {
124+
if (val && (val as Buffer).buffer) {
121125
return send(res, val)
122126
} else if (val instanceof Error) {
123127
throw createError(val)
@@ -132,15 +136,18 @@ export function createHandle (stack: Stack, options: AppOptions): PHandle {
132136
}
133137
}
134138

135-
function normalizeLayer (layer: InputLayer) {
136-
if (layer.promisify === undefined) {
137-
layer.promisify = layer.handle.length > 2 /* req, res, next */
139+
function normalizeLayer (input: InputLayer) {
140+
if (input.promisify === undefined) {
141+
input.promisify = input.handle.length > 2 /* req, res, next */
138142
}
143+
144+
const handle = input.lazy
145+
? lazyHandle(input.handle as LazyHandle, input.promisify)
146+
: (input.promisify ? promisifyHandle(input.handle) : input.handle)
147+
139148
return {
140-
route: withoutTrailingSlash(layer.route),
141-
match: layer.match,
142-
handle: layer.lazy
143-
? lazyHandle(layer.handle as LazyHandle, layer.promisify)
144-
: (layer.promisify ? promisifyHandle(layer.handle) : layer.handle)
149+
route: withoutTrailingSlash(input.route),
150+
match: input.match,
151+
handler: toEventHandler(handle)
145152
}
146153
}

src/event.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import type { IncomingMessage, ServerResponse } from './types/node'
2+
import type { Handle, Middleware } from './handle'
3+
4+
export interface H3Event {
5+
req: IncomingMessage
6+
res: ServerResponse,
7+
next?: (err?: Error) => void
8+
}
9+
10+
export type _JSONValue<T=string|number|boolean> = T | T[] | Record<string, T>
11+
export type JSONValue = _JSONValue<_JSONValue>
12+
export type H3Response = void | JSONValue | Buffer
13+
14+
export interface H3EventHandler {
15+
__is_handler__?: true
16+
(event: H3Event): H3Response| Promise<H3Response>
17+
}
18+
19+
export function defineEventHandler (handler: H3EventHandler) {
20+
handler.__is_handler__ = true
21+
return handler
22+
}
23+
24+
export function isEventHandler (handler: H3EventHandler | Handle | Middleware): handler is H3EventHandler {
25+
return '__is_handler__' in handler
26+
}
27+
28+
export function toEventHandler (handler: H3EventHandler | Handle | Middleware): H3EventHandler {
29+
if (isEventHandler(handler)) {
30+
return handler
31+
}
32+
if (handler.length > 2) {
33+
return defineEventHandler((event) => {
34+
return (handler as Middleware)(event.req, event.res, event.next!)
35+
})
36+
} else {
37+
return defineEventHandler((event) => {
38+
return (handler as Handle)(event.req, event.res)
39+
})
40+
}
41+
}
42+
43+
export function createEvent (req: IncomingMessage, res: ServerResponse): H3Event {
44+
return {
45+
req,
46+
res
47+
}
48+
}

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export * from './app'
22
export * from './error'
3+
export * from './event'
34
export * from './handle'
45
export * from './utils'
56
export * from './router'

0 commit comments

Comments
 (0)