-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcontext.ts
99 lines (88 loc) · 2.63 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
// Copyright 2022 the oak authors. All rights reserved.
/**
* Contains the class {@linkcode Context} which provides context for the request
* and response to the request handler.
*
* @module
*/
import { type SecureCookieMap } from "./deps.ts";
import { type Deserializer } from "./types.d.ts";
interface ContextOptions<BodyType, Params extends Record<string, string>> {
cookies: SecureCookieMap;
deserializer?: Deserializer<BodyType, Params>;
params?: Params;
request: Request;
}
/** An object that provides context for the associated request and response.
* This is passed as the first argument to every route handler. */
export class Context<
BodyType = unknown,
Params extends Record<string, string> = Record<string, string>,
> {
#body?: BodyType;
#bodySet = false;
#cookies: SecureCookieMap;
#deserializer?: Deserializer<BodyType, Params>;
#params: Params;
#request: Request;
#requestUrl?: URL;
/** The instance of {@linkcode Cookies} that allows reading and setting of
* cookies on the request and response. */
get cookies(): SecureCookieMap {
return this.#cookies;
}
/** Any {@linkcode Params} that have been parsed out of the URL requested
* based on the URL pattern string provided to the `Route`. */
get params(): Params {
return this.#params;
}
/** The original {@linkcode Request} associated with this request. */
get request(): Request {
return this.#request;
}
/** Any search parameters associated with the request. */
get searchParams(): Record<string, string> {
if (!this.#requestUrl) {
this.#requestUrl = new URL(this.#request.url);
}
return Object.fromEntries(this.#requestUrl.searchParams.entries());
}
constructor(
{ request, params, deserializer, cookies }: ContextOptions<
BodyType,
Params
>,
) {
this.#request = request;
this.#params = params ?? {} as Params;
this.#deserializer = deserializer;
this.#cookies = cookies;
}
async body(): Promise<BodyType | undefined> {
if (this.#bodySet) {
return this.#body;
}
this.#bodySet = true;
if (!this.#request.bodyUsed) {
if (this.#deserializer) {
const bodyString = await this.#request.text();
this.#body = await this.#deserializer.parse(
bodyString,
this.#params,
this.#request,
);
} else {
try {
this.#body = await this.#request.json();
} catch {
this.#body = undefined;
}
}
}
return this.#body;
}
/** Returns the request URL as a parsed {@linkcode URL} object. */
url(): URL {
return new URL(this.#request.url);
}
}