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

Commit 808d303

Browse files
author
v1rtl
committed
fix annoying issue with type_is pkg
1 parent d53c183 commit 808d303

27 files changed

+277
-270
lines changed

app.ts

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,34 @@ import * as path from 'https://deno.land/std/path/mod.ts'
1212

1313
const lead = (x: string) => (x.charCodeAt(0) === 47 ? x : '/' + x)
1414

15+
declare global {
16+
namespace tinyhttp {
17+
// These open interfaces may be extended in an application-specific manner via declaration merging.
18+
interface Request {}
19+
interface Response {}
20+
interface Application {}
21+
}
22+
}
23+
24+
export const renderTemplate = <O = any, Res extends Response = Response>(res: Res, app: App) => (
25+
file: string,
26+
data?: Record<string, any>,
27+
options?: TemplateEngineOptions<O>
28+
): Response => {
29+
app.render(
30+
file,
31+
data,
32+
(err: unknown, html: unknown) => {
33+
if (err) throw err
34+
35+
res.send(html)
36+
},
37+
options
38+
)
39+
40+
return res
41+
}
42+
1543
/**
1644
* Execute handler with passed `req` and `res`. Catches errors and resolves async handlers.
1745
* @param h
@@ -75,10 +103,12 @@ export type TemplateEngineOptions<O = any> = Partial<{
75103
* ```
76104
*/
77105
export class App<
78-
RenderOptions = any,
79-
Req extends Request = Request,
80-
Res extends Response<RenderOptions> = Response<RenderOptions>
81-
> extends Router<App, Req, Res> {
106+
RenderOptions = any,
107+
Req extends Request = Request,
108+
Res extends Response<RenderOptions> = Response<RenderOptions>
109+
>
110+
extends Router<App, Req, Res>
111+
implements tinyhttp.Application {
82112
middleware: Middleware<Req>[] = []
83113
locals: Record<string, string> = {}
84114
noMatchHandler: Handler

deps.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export { default as ipaddr, IPv4, IPv6 } from 'https://esm.sh/ipaddr.js'
2+
import { default as parseRange, Options } from 'https://esm.sh/range-parser@1.2.1'
3+
export { parseRange }
4+
export type { Options as ParseRangeOptions }
5+
export { escapeHtml } from 'https://deno.land/x/escape_html@1.0.0/mod.ts'
6+
export { vary } from 'https://deno.land/x/vary@1.0.0/mod.ts'
7+
export { isIP } from 'https://deno.land/x/isIP@1.0.0/mod.ts'
8+
export { Accepts } from 'https://deno.land/x/accepts@2.1.0/mod.ts'
9+
export { encodeUrl } from 'https://deno.land/x/encodeurl@1.0.0/mod.ts'
10+
export { charset, contentType, lookup } from 'https://deno.land/x/media_types@v2.6.1/mod.ts'
11+
12+
export type { ServerRequest as Req, Response as Res } from 'https://deno.land/std@0.88.0/http/server.ts'
File renamed without changes.

extend.ts

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
import { NextFunction } from 'https://esm.sh/@tinyhttp/router'
2-
import { App } from './app.ts'
2+
import { App, renderTemplate } from './app.ts'
33
import { Request } from './request.ts'
44
import {
55
getRequestHeader,
6-
getFreshOrStale,
6+
/* getFreshOrStale, */
77
getAccepts,
88
getAcceptsCharsets,
99
getAcceptsEncodings,
1010
getAcceptsLanguages,
11-
getRangeFromHeader,
1211
checkIfXMLHttpRequest,
13-
reqIs,
1412
getHostname,
1513
getIP,
1614
getIPs,
1715
getProtocol,
1816
getSubdomains
17+
/* reqIs */
1918
} from './extensions/req/mod.ts'
2019
import {
2120
send,
@@ -37,7 +36,7 @@ import {
3736
clearCookie
3837
} from './extensions/res/mod.ts'
3938
import { getQueryParams } from './utils/parseUrl.ts'
40-
import { Response, renderTemplate } from './response.ts'
39+
import { Response } from './response.ts'
4140

4241
export const extendMiddleware = <
4342
RenderOptions = unknown,
@@ -62,27 +61,27 @@ export const extendMiddleware = <
6261

6362
req.get = getRequestHeader(req)
6463

65-
if (settings?.freshnessTesting) {
66-
req.fresh = getFreshOrStale(req, res)
64+
/* if (settings?.freshnessTesting) {
65+
req.fresh = getFreshOrStale<Req, Res>(req, res)
6766
req.stale = !req.fresh
68-
}
67+
} */
6968

70-
req.accepts = getAccepts(req)
71-
req.acceptsCharsets = getAcceptsCharsets(req)
72-
req.acceptsEncodings = getAcceptsEncodings(req)
73-
req.acceptsLanguages = getAcceptsLanguages(req)
69+
req.accepts = getAccepts<Req>(req)
70+
req.acceptsCharsets = getAcceptsCharsets<Req>(req)
71+
req.acceptsEncodings = getAcceptsEncodings<Req>(req)
72+
req.acceptsLanguages = getAcceptsLanguages<Req>(req)
7473

75-
req.range = getRangeFromHeader(req)
74+
// req.range = getRangeFromHeader(req)
7675
req.xhr = checkIfXMLHttpRequest(req)
77-
req.is = reqIs(req)
76+
// req.is = reqIs(req)
7877

7978
if (settings?.networkExtensions) {
80-
req.protocol = getProtocol(req)
79+
req.protocol = getProtocol<Req>(req)
8180
req.secure = req.protocol === 'https'
82-
req.hostname = getHostname(req)
83-
req.subdomains = getSubdomains(req, settings.subdomainOffset)
84-
req.ip = getIP(req)
85-
req.ips = getIPs(req)
81+
req.hostname = getHostname<Req>(req)
82+
req.subdomains = getSubdomains<Req>(req, settings.subdomainOffset)
83+
req.ip = getIP<Req>(req)
84+
req.ips = getIPs<Req>(req)
8685
}
8786

8887
// Response extensions
@@ -91,7 +90,7 @@ export const extendMiddleware = <
9190
res.send = send<Req, Res>(req, res)
9291
res.sendFile = sendFile<Req, Res>(req, res)
9392
res.sendStatus = sendStatus(req, res)
94-
res.json = json<Res>(res)
93+
res.json = json<Req, Res>(req, res)
9594
res.setHeader = setHeader<Res>(res)
9695
res.set = setHeader<Res>(res)
9796
res.location = setLocationHeader<Req, Res>(req, res)

extensions/req/accepts.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
import { Accepts } from 'https://deno.land/x/accepts@2.1.0/mod.ts'
2-
import { Request } from '../../request.ts'
1+
import { Accepts } from '../../deps.ts'
2+
import { Req } from '../../deps.ts'
33

4-
export const getAccepts = (req: Request) => (...types: string[]) => new Accepts(req.headers).types(types)
4+
export const getAccepts = <Request extends Req = Req>(req: Request) => (...types: string[]) =>
5+
new Accepts(req.headers).types(types)
56

6-
export const getAcceptsEncodings = (req: Request) => (...encodings: string[]) =>
7+
export const getAcceptsEncodings = <Request extends Req = Req>(req: Request) => (...encodings: string[]) =>
78
new Accepts(req.headers).encodings(encodings)
89

9-
export const getAcceptsCharsets = (req: Request) => (...charsets: string[]) =>
10+
export const getAcceptsCharsets = <Request extends Req = Req>(req: Request) => (...charsets: string[]) =>
1011
new Accepts(req.headers).charsets(charsets)
1112

12-
export const getAcceptsLanguages = (req: Request) => (...languages: string[]) =>
13+
export const getAcceptsLanguages = <Request extends Req = Req>(req: Request) => (...languages: string[]) =>
1314
new Accepts(req.headers).languages(languages)

extensions/req/headers.ts

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,30 @@
1-
import { Request } from '../../request.ts'
2-
import { Response } from '../../response.ts'
3-
import parseRange, { Options } from 'https://esm.sh/range-parser'
1+
import { Req, Res, parseRange, ParseRangeOptions } from '../../deps.ts'
42
import fresh from 'https://deno.land/x/fresh@v1.0.0/mod.ts'
5-
import { is } from 'https://deno.land/x/type_is@1.0.2/mod.ts'
3+
import { is } from 'https://deno.land/x/type_is@1.0.1/mod.ts'
64

7-
export const getRequestHeader = (req: Request) => (header: string): string | string[] | null => {
5+
export const getRequestHeader = <Request extends Req = Req>(req: Request) => (header: string) => {
86
const lc = header.toLowerCase()
97

108
switch (lc) {
119
case 'referer':
1210
case 'referrer':
13-
return req.headers.get('referrer') || req.headers.get('referer')
11+
return (req.headers.get('referrer') as string) || (req.headers.get('referer') as string)
1412
default:
15-
return req.headers.get(lc)
13+
return req.headers.get(lc) as string
1614
}
1715
}
18-
export const getRangeFromHeader = (req: Request) => (size: number, options?: Options) => {
19-
const range = getRequestHeader(req)('Range') as string
16+
export const getRangeFromHeader = <Request extends Req = Req>(req: Request) => (
17+
size: number,
18+
options?: ParseRangeOptions
19+
) => {
20+
const range = getRequestHeader(req)('Range')
2021

2122
if (!range) return
2223

2324
return parseRange(size, range, options)
2425
}
2526

26-
export const getFreshOrStale = (req: Request, res: Response) => {
27+
export const getFreshOrStale = <Request extends Req = Req, Response extends Res = Res>(req: Request, res: Response) => {
2728
const method = req.method
2829
const status = res.status || 200
2930

@@ -44,6 +45,8 @@ export const getFreshOrStale = (req: Request, res: Response) => {
4445
return false
4546
}
4647

47-
export const checkIfXMLHttpRequest = (req: Request) => req.headers.get('X-Requested-With') === 'XMLHttpRequest'
48+
export const checkIfXMLHttpRequest = <Request extends Req = Req>(req: Request) =>
49+
req.headers?.get('X-Requested-With') === 'XMLHttpRequest'
4850

49-
export const reqIs = (req: Request) => (...types: string[]) => is(req.headers.get('content-type') as string, types)
51+
export const reqIs = <Request extends Req = Req>(req: Request) => (...types: string[]) =>
52+
is(req.headers?.get('content-type') as string, types)

extensions/req/security.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { isIP } from 'https://deno.land/x/isIP@1.0.0/mod.ts'
2-
import { Request } from '../../request.ts'
1+
import { isIP } from '../../deps.ts'
2+
import { Req } from '../../deps.ts'
3+
import { Protocol } from '../../types.ts'
34
import { compile, proxyaddr, all } from '../../utils/proxyAddr.ts'
4-
import { Protocol } from '../../request.ts'
55

6-
export const trustRemoteAddress = (req: Request) => {
6+
export const trustRemoteAddress = <Request extends Req = Req>(req: Request) => {
77
const val = (req.conn.remoteAddr as Deno.NetAddr).hostname
88

99
if (typeof val === 'function') return val
@@ -17,10 +17,10 @@ export const trustRemoteAddress = (req: Request) => {
1717
return compile(val)
1818
}
1919

20-
export const getProtocol = (req: Request): Protocol => {
20+
export const getProtocol = <Request extends Req = Req>(req: Request): Protocol => {
2121
const proto = req.proto.includes('https') ? 'https' : 'http'
2222

23-
const header = (req.get('X-Forwarded-Proto') as string) ?? proto
23+
const header = (req.headers.get('X-Forwarded-Proto') as string) ?? proto
2424
const index = header.indexOf(',')
2525

2626
if (!trustRemoteAddress(req)) return proto
@@ -31,11 +31,11 @@ export const getProtocol = (req: Request): Protocol => {
3131
return (index !== -1 ? header.substring(0, index).trim() : header.trim()) as Protocol
3232
}
3333

34-
export const getHostname = (req: Request): string | undefined => {
35-
let host: string = req.get('X-Forwarded-Host') as string
34+
export const getHostname = <Request extends Req = Req>(req: Request): string | undefined => {
35+
let host: string = req.headers.get('X-Forwarded-Host') as string
3636

3737
if (!host || !trustRemoteAddress(req)) {
38-
host = (req.get('Host') as string) || (req.conn.remoteAddr as Deno.NetAddr).hostname
38+
host = (req.headers.get('Host') as string) || (req.conn.remoteAddr as Deno.NetAddr).hostname
3939
}
4040

4141
if (!host) return
@@ -45,11 +45,13 @@ export const getHostname = (req: Request): string | undefined => {
4545

4646
return index !== -1 ? host.substring(0, index) : host
4747
}
48-
export const getIP = (req: Request): string | undefined => proxyaddr(req, trustRemoteAddress(req))?.replace(/^.*:/, '') // striping the redundant prefix addeded by OS to IPv4 address
48+
export const getIP = <Request extends Req = Req>(req: Request): string | undefined =>
49+
proxyaddr(req, trustRemoteAddress(req))?.replace(/^.*:/, '') // striping the redundant prefix addeded by OS to IPv4 address
4950

50-
export const getIPs = (req: Request): string[] | undefined => all(req, trustRemoteAddress(req))
51+
export const getIPs = <Request extends Req = Req>(req: Request): string[] | undefined =>
52+
all(req, trustRemoteAddress(req))
5153

52-
export const getSubdomains = (req: Request, subdomainOffset = 2): string[] => {
54+
export const getSubdomains = <Request extends Req = Req>(req: Request, subdomainOffset = 2): string[] => {
5355
const hostname = getHostname(req)
5456

5557
if (!hostname) return []

extensions/res/append.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Response as Res } from '../../response.ts'
1+
import { Res } from '../../deps.ts'
22
import { setHeader, getResponseHeader } from './headers.ts'
33

44
export const append = <Response extends Res = Res>(res: Response) => (

extensions/res/cookie.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { Request as Req } from '../../request.ts'
2-
import { Response as Res } from '../../response.ts'
1+
import { Req, Res } from '../../deps.ts'
32
import * as cookie from 'https://deno.land/std@0.88.0/http/cookie.ts'
43

54
export const setCookie = <Request extends Req = Req, Response extends Res = Res>(req: Request, res: Response) => (

extensions/res/download.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ import { contentDisposition } from 'https://esm.sh/@tinyhttp/content-disposition
22
import { SendFileOptions, sendFile } from './sendFile.ts'
33
import { resolve, extname } from 'https://deno.land/std@0.88.0/path/mod.ts'
44
import { setContentType, setHeader } from './headers.ts'
5-
import { Request as Req } from '../../request.ts'
6-
import { Response as Res } from '../../response.ts'
5+
import { Req, Res } from '../../deps.ts'
76

87
export type DownloadOptions = SendFileOptions &
98
Partial<{

0 commit comments

Comments
 (0)