@intuitionrobotics/thunderstorm
Version:
109 lines • 4 kB
JavaScript
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