-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontext.ts
123 lines (114 loc) · 2.99 KB
/
context.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import {
getCookies,
getSetCookies,
setCookie,
deleteCookie,
Cookie,
STATUS_CODE,
STATUS_TEXT,
StatusCode,
StatusText,
contentType,
} from './deps.ts';
type ContentType = Parameters<typeof contentType>[0];
const CONTENT_TYPE = 'content-type';
export class Context {
readonly URL;
readonly cookies;
constructor(
readonly request: Request,
readonly info: Deno.ServeHandlerInfo | Deno.ServeUnixHandlerInfo
) {
const { url, headers } = request;
this.URL = new URL(url);
this.cookies = new Map(Object.entries(getCookies(headers)));
}
#status?: StatusCode;
get status() {
return this.response.status as StatusCode;
}
set status(status) {
this.#status = status;
}
#statusText?: StatusText;
get statusText() {
return this.response.statusText as StatusText;
}
set statusText(statusText) {
this.#statusText = statusText;
}
headers = new Headers();
get setCookies() {
return getSetCookies(this.headers);
}
set cookie(cookie: Cookie) {
setCookie(this.headers, cookie);
}
deleteCookie(name: string) {
deleteCookie(this.headers, name);
}
get contentType() {
return this.headers.get(CONTENT_TYPE) as ContentType;
}
set contentType(type) {
this.headers.set(CONTENT_TYPE, contentType(type) ?? type);
}
deleteContentType() {
this.headers.delete(CONTENT_TYPE);
}
body: unknown;
#response?: Response;
get response() {
return this.#response ?? this.#render();
}
set response(response) {
this.#response = response;
}
#render() {
let type: ContentType | undefined;
let body: BodyInit | null | undefined;
if (typeof this.body === 'undefined' || this.body === null) {
body = this.body;
} else if (this.body instanceof Deno.FsFile) {
type = 'application/octet-stream';
body = this.body.readable;
} else if (
this.body instanceof Blob ||
this.body instanceof ArrayBuffer ||
ArrayBuffer.isView(this.body) ||
this.body instanceof ReadableStream
) {
type = 'application/octet-stream';
body = this.body;
} else if (typeof this.body === 'string') {
type = 'text/plain';
body = this.body;
} else if (this.body instanceof FormData) {
type = 'multipart/form-data';
body = this.body;
} else if (this.body instanceof URLSearchParams) {
type = 'application/x-www-form-urlencoded';
body = this.body;
} else {
type = 'application/json';
body = JSON.stringify(this.body);
}
if (type && !this.contentType) this.contentType = type;
const status =
this.#status ??
(typeof body === 'undefined' || body === null
? STATUS_CODE.NotFound
: STATUS_CODE.OK);
const statusText = this.#statusText ?? STATUS_TEXT[status];
return new Response(body, {
status,
statusText,
headers: this.headers,
});
}
upgrade() {
const { response, socket } = Deno.upgradeWebSocket(this.request);
this.#response = response;
return socket;
}
}