Skip to content
This repository was archived by the owner on Jul 31, 2025. It is now read-only.

Commit 59d8d51

Browse files
author
v1rtl
committed
add attach fn, res.locals, more tests
1 parent cb10e4b commit 59d8d51

File tree

7 files changed

+75
-22
lines changed

7 files changed

+75
-22
lines changed

app.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import { Router, serve, Server, rg } from './deps.ts'
33
import { NextFunction, RHandler as Handler, Middleware, UseMethodParams } from './types.ts'
44
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.88.0/node/timers.ts'
66
import type { Request } from './request.ts'
77
import type { Response } from './response.ts'
88
import { getURLParams, getPathname } from './utils/parseUrl.ts'
@@ -125,13 +125,15 @@ export class App<
125125
settings: AppSettings & Record<string, any>
126126
engines: Record<string, TemplateFunc<RenderOptions>> = {}
127127
applyExtensions?: (req: Req, res: Res, next: NextFunction) => void
128+
attach: (req: Req) => void
128129

129130
constructor(options: AppConstructor<Req, Res> = {}) {
130131
super()
131132
this.onError = options?.onError || onErrorHandler
132133
this.noMatchHandler = options?.noMatchHandler || this.onError.bind(null, { code: 404 })
133134
this.settings = options.settings || { xPoweredBy: true }
134135
this.applyExtensions = options?.applyExtensions
136+
this.attach = (req) => setImmediate(this.handler.bind(this, req, undefined), req)
135137
}
136138

137139
set(setting: string, value: any) {
@@ -298,7 +300,7 @@ export class App<
298300
cb?.()
299301

300302
for await (const req of server) {
301-
this.handler(req as any)
303+
this.attach(req as any)
302304
}
303305
return server
304306
}

egg.json

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,8 @@
44
"entry": "./app.ts",
55
"description": "0-legacy, tiny & fast web framework as a replacement of Express",
66
"homepage": "https://github.com/talentlessguy/tinyhttp-deno",
7-
"version": "0.0.17",
8-
"files": [
9-
"./*.ts",
10-
"./utils/*.ts",
11-
"./extensions/**/*.ts",
12-
"README.md"
13-
],
7+
"version": "0.0.18",
8+
"files": ["./*.ts", "./utils/*.ts", "./extensions/**/*.ts", "README.md"],
149
"checkFormat": false,
1510
"checkTests": false,
1611
"checkInstallation": false,

extend.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ export const extendMiddleware = <
4848
) => (req: Req, res: Res, next: NextFunction) => {
4949
const { settings } = app
5050

51+
res.locals = res.locals || Object.create(null)
52+
5153
// Request extensions
5254
if (settings?.bindAppToReqRes) {
5355
req.app = app

response.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export interface Response<O = any> extends ServerResponse, tinyhttp.Response {
2929
type(type: string): Response
3030
format(obj: FormatProps): Response
3131
vary(field: string): Response
32-
locals?: Record<string, any>
32+
locals: Record<string, any>
3333
download(path: string, filename: string, options?: DownloadOptions, cb?: (err?: any) => void): Response
3434
attachment(filename?: string): Response
3535

robo.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
test:
2-
exec: deno test --allow-net --no-check --location http://127.0.1 ./tests -q
2+
exec: deno test --allow-net --no-check --location http://127.0.1
33
summary: run tests

tests/core/app.test.ts

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { describe, it, expect, run } from 'https://deno.land/x/wizard@0.1.0/mod.ts'
2-
import { App } from '../../mod.ts'
2+
import { App } from '../../app.ts'
33
import { BindToSuperDeno, InitAppAndTest } from '../util.ts'
44

55
describe('Testing App', () => {
@@ -22,18 +22,24 @@ describe('Testing App', () => {
2222

2323
expect(app.locals.hello).toBe('world')
2424
})
25-
/* it('Custom noMatchHandler works', async () => {
26-
const { fetch } = InitAppAndTest(() => {}, undefined, {
27-
noMatchHandler: (req) => {
28-
req.respond({
29-
status: 404,
30-
body: `Oopsie! Page ${req.url} is lost.`
31-
})
25+
it('Custom noMatchHandler works', async () => {
26+
const { fetch } = InitAppAndTest(
27+
(_req, _res, next) => {
28+
next()
29+
},
30+
undefined,
31+
{
32+
noMatchHandler: (req) => {
33+
req.respond({
34+
status: 404,
35+
body: `Oopsie! Page ${req.url} is lost.`
36+
})
37+
}
3238
}
33-
})
39+
)
3440

3541
await fetch.get('/').expect(404, 'Oopsie! Page / is lost.')
36-
}) */
42+
})
3743
it('Custom onError works', async () => {
3844
const app = new App({
3945
onError: (err, req) => {
@@ -50,6 +56,54 @@ describe('Testing App', () => {
5056

5157
await fetch.get('/').expect(500, 'Ouch, you hurt me on / page.')
5258
})
59+
it('req and res inherit properties from previous middlewares', async () => {
60+
const app = new App()
61+
62+
app
63+
.use((_req, res, next) => {
64+
res.locals.hello = 'world'
65+
66+
next()
67+
})
68+
.get('/', (_, res) => {
69+
res.send(res.locals)
70+
})
71+
72+
const fetch = BindToSuperDeno(app)
73+
74+
await fetch.get('/').expect(200, '{\n "hello": "world"\n}')
75+
})
76+
})
77+
78+
describe('Testing App routing', () => {
79+
it('should respond on matched route', async () => {
80+
const { fetch } = InitAppAndTest((_req, res) => void res.send('Hello world'), '/route')
81+
82+
await fetch.get('/route').expect(200, 'Hello world')
83+
})
84+
it('should match wares containing base path', async () => {
85+
const app = new App()
86+
87+
app.use('/abc', (_req, res) => void res.send('Hello world'))
88+
89+
const fetch = BindToSuperDeno(app)
90+
91+
await fetch.get('/abc/def').expect(200, 'Hello world')
92+
})
93+
it('"*" should catch all undefined routes', async () => {
94+
const app = new App()
95+
96+
app
97+
.get('/route', (_req, res) => void res.send('A different route'))
98+
.all('*', (_req, res) => void res.send('Hello world'))
99+
100+
const fetch = BindToSuperDeno(app)
101+
102+
await fetch.get('/test').expect(200, 'Hello world')
103+
})
104+
it('should throw 404 on no routes', async () => {
105+
await BindToSuperDeno(new App()).get('/').expect(404)
106+
})
53107
})
54108

55109
run()

tests/util.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export const randomPort = async () => {
1111
}
1212

1313
export const BindToSuperDeno = <Req extends Request, Res extends Response>(app: App<unknown, Req, Res>) => {
14-
const fetch = superdeno(app.handler.bind(app))
14+
const fetch = superdeno(app.attach)
1515

1616
return fetch
1717
}

0 commit comments

Comments
 (0)