Skip to content
File

Blob: src/worker/http.ts

typescript38 lines
1export class HttpError extends Error {
2 readonly status: number;
3 readonly code: string;
4 readonly detail?: Record<string, unknown>;
5 
6 constructor(status: number, code: string, message: string, detail?: Record<string, unknown>) {
7 super(message);
8 this.name = "HttpError";
9 this.status = status;
10 this.code = code;
11 this.detail = detail;
12 }
13 
14 toResponse(): Response {
15 return new Response(JSON.stringify({ error: this.code, message: this.message, ...(this.detail ?? {}) }), {
16 status: this.status,
17 headers: { "content-type": "application/json" },
18 });
19 }
20}
21 
22// JSON response carrying a one-time secret (invite URL, OAuth client
23// secret, rotated client secret). POST responses are not cached by
24// default, but explicit `no-store` removes the chance that a browser
25// extension, dev tool, intermediary, or edge cache retains the value
26// after the user closes the tab. `private` is defense-in-depth for
27// caches that ignore `no-store` but honor `private`. Pragma is
28// duplicated for HTTP/1.0 and strict legacy proxies.
29export const secretJsonResponse = (payload: unknown, status = 200): Response =>
30 new Response(JSON.stringify(payload), {
31 status,
32 headers: {
33 "content-type": "application/json",
34 "cache-control": "no-store, private, max-age=0",
35 pragma: "no-cache",
36 },
37 });