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

Commit b3c6266

Browse files
author
v1rtl
committed
add missing res.redirect to res interface, more tests
1 parent 6d5098d commit b3c6266

File tree

9 files changed

+81
-27
lines changed

9 files changed

+81
-27
lines changed

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.26",
8-
"files": [
9-
"./*.ts",
10-
"./utils/*.ts",
11-
"./extensions/**/*.ts",
12-
"README.md"
13-
],
7+
"version": "0.0.27",
8+
"files": ["./*.ts", "./utils/*.ts", "./extensions/**/*.ts", "README.md"],
149
"checkFormat": false,
1510
"checkTests": false,
1611
"checkInstallation": false,

extend.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ import {
3434
attachment,
3535
download,
3636
setCookie,
37-
clearCookie
37+
clearCookie,
38+
redirect
3839
} from './extensions/res/mod.ts'
3940
import { getQueryParams } from './utils/parseUrl.ts'
4041
import { Response } from './response.ts'
@@ -101,6 +102,7 @@ export const extendMiddleware = <
101102
res.append = append<Res>(res)
102103
res.render = renderTemplate<RenderOptions, Res>(res, app)
103104
res.links = setLinksHeader<Res>(res)
105+
res.redirect = redirect<Req, Res, NextFunction>(req, res, next)
104106
res.type = setContentType<Res>(res)
105107
res.format = formatResponse<Req, Res>(req, res, next)
106108
res.vary = setVaryHeader<Res>(res)

extensions/res/mod.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ export * from './format.ts'
55
export * from './download.ts'
66
export * from './cookie.ts'
77
export * from './headers.ts'
8+
export * from './redirect.ts'

extensions/res/redirect.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,15 @@ export const redirect = <
3535
}
3636
})
3737

38-
res.headers?.set('Content-Length', body.length.toString())
39-
40-
res.status = status
41-
42-
if (req.method === 'HEAD') req.respond({})
43-
else req.respond({ body })
38+
res.headers.set('Content-Length', body.length.toString())
39+
40+
if (req.method === 'HEAD') req.respond({ status })
41+
else
42+
req.respond({
43+
body,
44+
status,
45+
...res
46+
})
4447

4548
return res
4649
}

extensions/res/send/sendStatus.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { status } from 'https://deno.land/x/status/status.ts'
55
export const sendStatus = <Request extends Req = Req, Response extends Res = Res>(req: Request, res: Response) => (
66
statusCode: number
77
): Response => {
8-
const body = status(statusCode)
8+
const body = status.pretty(statusCode)
99

1010
res.status = statusCode
1111

response.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,6 @@ export interface Response<O = any> extends ServerResponse, tinyhttp.Response {
3636
cookie(name: string, value: string | Record<string, unknown>, options?: Omit<Cookie, 'name' | 'value'>): Response
3737
clearCookie(name: string): Response
3838
jsonp(obj: any): Response
39+
40+
redirect(url: string, status?: number): Response
3941
}

tests/modules/res.test.ts

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { describe, it, run } from 'https://deno.land/x/wizard/mod.ts'
22
import { InitAppAndTest } from '../util.ts'
3-
import { setHeader } from '../../extensions/res/mod.ts'
3+
import { setHeader, getResponseHeader, setVaryHeader, redirect } from '../../extensions/res/mod.ts'
44

55
describe('res.set(field, val)', () => {
66
it('should set a string header with a string value', async () => {
@@ -48,4 +48,53 @@ describe('res.set(field, val)', () => {
4848
})
4949
})
5050

51+
describe('res.get(field)', () => {
52+
it('should get a header with a specified field', async () => {
53+
const { fetch } = InitAppAndTest((_, res) => {
54+
setHeader(res)('hello', 'World')
55+
res.end(getResponseHeader(res)('hello'))
56+
})
57+
58+
await fetch.get('/').expect('World')
59+
})
60+
})
61+
62+
describe('res.vary(field)', () => {
63+
it('should set a "Vary" header properly', async () => {
64+
const { fetch } = InitAppAndTest((_, res) => {
65+
setVaryHeader(res)('User-Agent').end()
66+
})
67+
68+
await fetch.get('/').expect('Vary', 'User-Agent')
69+
})
70+
})
71+
72+
describe('res.redirect(url, status)', () => {
73+
it('should set 302 status and message about redirecting', async () => {
74+
const { fetch } = InitAppAndTest((req, res) => {
75+
redirect(req, res, () => {})('/abc')
76+
})
77+
78+
await fetch.get('/').expect('Location', '/abc').expect(302 /* 'Redirecting to' */)
79+
})
80+
81+
it('should send an HTML link to redirect to', async () => {
82+
const { fetch } = InitAppAndTest((req, res) => {
83+
if (req.url === '/abc') {
84+
req.respond({
85+
status: 200,
86+
body: 'Hello World'
87+
})
88+
} else {
89+
redirect(req, res, () => {})('/abc')
90+
}
91+
})
92+
93+
await fetch
94+
.get('/')
95+
.set('Accept', 'text/html')
96+
.expect(302 /* '<p>Found. Redirecting to <a href="/abc">/abc</a></p>' */)
97+
})
98+
})
99+
51100
run()

tests/modules/send.test.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { describe, it, run } from 'https://deno.land/x/wizard/mod.ts'
22
import { InitAppAndTest } from '../util.ts'
3-
import { send, json } from '../../extensions/res/send/mod.ts'
3+
import { send, json, sendStatus } from '../../extensions/res/send/mod.ts'
44

55
describe('json(body)', () => {
66
it('should send a json-stringified reply when an object is passed', async () => {
@@ -91,4 +91,12 @@ describe('send(body)', () => {
9191
}) */
9292
})
9393

94+
describe('sendStatus(status)', () => {
95+
it(`should send "I'm a teapot" when argument is 418`, async () => {
96+
const { fetch } = InitAppAndTest((req, res) => sendStatus(req, res)(418))
97+
98+
await fetch.get('/').expect(418, 'Im A Teapot')
99+
})
100+
})
101+
94102
run()

tests/util.ts

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
11
import { getFreePort } from 'https://deno.land/x/free_port@v1.2.0/mod.ts'
22
import { superdeno } from 'https://deno.land/x/superdeno@3.0.0/mod.ts'
3-
import { App, Handler, AppConstructor, Request, Response, Method } from '../mod.ts'
3+
import { App, Handler, AppConstructor, Request, Response } from '../mod.ts'
44

5-
function random(min: number, max: number): number {
6-
return Math.round(Math.random() * (max - min)) + min
7-
}
5+
const random = (min: number, max: number): number => Math.round(Math.random() * (max - min)) + min
86

9-
export const randomPort = async () => {
10-
return await getFreePort(random(2048, 8064))
11-
}
7+
export const randomPort = async () => await getFreePort(random(2048, 8064))
128

139
export const BindToSuperDeno = <Req extends Request, Res extends Response>(app: App<unknown, Req, Res>) => {
14-
const fetch = superdeno(app.attach)
15-
16-
return fetch
10+
return superdeno(app.attach)
1711
}
1812

1913
export const InitAppAndTest = (

0 commit comments

Comments
 (0)