UNPKG

@intuitionrobotics/thunderstorm

Version:
109 lines 4 kB
import { Logger } from "@intuitionrobotics/ts-common"; import { Stream } from "stream"; import {} from "http"; // noinspection TypeScriptPreferShortImport import {} from "../../../shared/types.js"; import { ApiException } from "../../exceptions.js"; import {} from "../../utils/types.js"; const logger = new Logger("ApiResponse"); // Process-wide debug flag (formerly `ServerApi.isDebug`): gates verbose error // output. Set from Storm config (Storm.build); read by HttpServer, the terminal // error handler, and ApiResponse's error helpers. export const apiDebug = { enabled: false }; // The `ServerApi` class — and `ServerApi_Get`/`ServerApi_Post`/`ServerApi_Proxy`/ // `ServerApi_Redirect` — were removed. Endpoints are now `handler(fn)` (see // handler.ts; `redirectHandler` for redirects). `ApiResponse` stays as a thin, // res-backed response helper: it's the shape legacy `ServerApi_Middleware`s // receive, and `headerSink(res)` hands them a real instance. export class ApiResponse { res; consumed = false; constructor(res) { this.res = res; } isConsumed() { return this.consumed; } consume() { if (this.consumed) { logger.logError("This API was already satisfied!!", new Error()); return; } this.consumed = true; } stream(responseCode, stream, headers) { this.consume(); this.printHeaders(headers); this.res.set(headers); this.res.writeHead(responseCode); stream.pipe(this.res, { end: false }); stream.on('end', () => { this.res.end(); }); } printHeaders(headers) { if (!headers) return logger.logVerbose(` -- No response headers`); logger.logVerbose(` -- Response with headers: `, headers); } printResponse(response) { if (!response) return logger.logVerbose(` -- No response body`); logger.logVerbose(` -- Response:`, response); } code(responseCode, headers) { this.printHeaders(headers); this.end(responseCode, "", headers); } text(responseCode, response, _headers) { const headers = (_headers || {}); headers["content-type"] = "text/plain"; this.end(responseCode, response, headers); } html(responseCode, response, _headers) { const headers = (_headers || {}); headers["content-type"] = "text/html"; this.end(responseCode, response, headers); } json(responseCode, response, _headers) { this._json(responseCode, response, _headers); } _json(responseCode, response, _headers) { const headers = (_headers || {}); headers["content-type"] = "application/json"; this.end(responseCode, response, headers); } end(responseCode, response, headers) { this.consume(); this.printHeaders(headers); this.printResponse(response); this.res.set(headers); this.res.writeHead(responseCode); this.res.end(typeof response !== "string" ? JSON.stringify(response, null, 2) : response); } setHeaders(headers) { this.res.header(headers); } setHeader(headerKey, value) { this.res.header(headerKey, value); } getHeader(headerKey) { return this.res.get(headerKey); } redirect(responseCode, url) { this.consume(); this.res.redirect(responseCode, url); } exception(exception, headers) { const responseBody = exception.responseBody; if (!apiDebug.enabled) delete responseBody.debugMessage; this._json(exception.responseCode, responseBody, headers); } serverError(error, headers) { const stack = error.cause ? error.cause.stack : error.stack; const message = (error.cause ? error.cause.message : error.message) || ""; this.text(500, apiDebug.enabled && stack ? stack : message, headers); } } //# sourceMappingURL=server-api.js.map