import type { HeaderValue } from "../types.ts";import { Status, contentType, extname, STATUS_TEXT } from "../deps.ts";import { Pair } from "./Pair.ts";import { ResponseHeaders } from "./ResponseHeaders.ts";
export class Response{ public get WRITABLE (): boolean { return this.pair.WRITABLE; } #filePath?: string; #content: string = "" as string; #statusCode: Status = Status.OK; public readonly headers: ResponseHeaders = new ResponseHeaders(this); public get statusCode (): Status { return this.#statusCode; } public set statusCode (code: Status) { if (!this.pair.WRITABLE) throw new Error(Pair.NOT_WRITABLE); this.#statusCode = code; } public get content (): string { return this.#content; } public set content (chunk: string) { if (!this.pair.WRITABLE) throw new Error(Pair.NOT_WRITABLE); this.#content = chunk; } public constructor (private readonly pair: Pair) { } public status (code: Status): this { if (!this.pair.WRITABLE) throw new Error(Pair.NOT_WRITABLE); this.statusCode = code; return this; } public write (chunk?: string): this { if (!this.pair.WRITABLE) throw new Error(Pair.NOT_WRITABLE); if (chunk) this.content += chunk; return this; } public file (path: string): this { this.#filePath = path; return this; } public async json (data: any): Promise<this> { if (!this.pair.WRITABLE) throw new Error(Pair.NOT_WRITABLE); this.headers.set("Content-Type", "application/json; charset=utf-8"); return await this.end(JSON.stringify(data)); } public type (type: string): this { this.headers.set("Content-Type", type); return this; } public async end (body?: string): Promise<this> { if (!this.pair.WRITABLE) throw new Error(Pair.NOT_WRITABLE); this.pair.ENDING = true; if (body) this.#content += body; const headers = this.headers.toHeadersObject(); if (this.#filePath) { this.#content = await Deno.readTextFile(this.#filePath); headers.set("Content-Type", contentType(extname(this.#filePath)) || "text/plain; charset=utf-8"); } let err: Error | null = null; try { headers.set("Content-Length", this.#content.length.toString()); headers.set("X-Powered-By", "Texa"); if (!this.content && this.statusCode >= 400) this.#content = STATUS_TEXT.has(this.statusCode) ? `${this.statusCode} - ${STATUS_TEXT.get(this.statusCode)}` : ""; await this.pair._request.respond({ body: this.#content, headers: headers, status: this.#statusCode }); } catch (error) { err = error; } this.pair.ENDED = true; this.pair.ENDING = false; if (err) throw err; return this; } public get (key: string): HeaderValue | void { return this.headers.get(key); } public set (key: string, value: HeaderValue): this { this.headers.set(key, value); return this; } public has (key: string): boolean { return this.headers.has(key); } public delete (key: string): this { this.headers.delete(key); return this; } }