diff options
Diffstat (limited to 'u/server/response/pengueno.ts')
-rw-r--r-- | u/server/response/pengueno.ts | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/u/server/response/pengueno.ts b/u/server/response/pengueno.ts new file mode 100644 index 0000000..5a953db --- /dev/null +++ b/u/server/response/pengueno.ts @@ -0,0 +1,59 @@ +import { + BaseResponse, + Body, + HttpStatusCodes, + ITraceable, + Metric, + Optional, + PenguenoRequest, + ResponseOpts, + ServerTrace, +} from '@emprespresso/pengueno'; + +const getHeaders = (req: PenguenoRequest, extraHeaders: Record<string, string>) => { + const optHeaders = { + ...req.getResponseHeaders(), + ...extraHeaders, + }; + optHeaders['Content-Type'] = (optHeaders['Content-Type'] ?? 'text/plain') + '; charset=utf-8'; + return optHeaders; +}; + +const ResponseCodeMetrics = [0, 1, 2, 3, 4, 5].map((x) => Metric.fromName(`response.${x}xx`).asResult()); +export const getResponseMetrics = (status: number, elapsedMs?: number) => { + const index = Math.floor(status / 100); + return ResponseCodeMetrics.flatMap((metric, i) => + Optional.from(i) + .filter((i) => i === index) + .map(() => [metric.count.withValue(1.0)]) + .flatMap((metricValues) => + Optional.from(elapsedMs) + .map((ms) => metricValues.concat(metric.time.withValue(ms))) + .orSome(() => metricValues), + ) + .orSome(() => [metric.count.withValue(0.0)]) + .get(), + ); +}; + +export class PenguenoResponse implements BaseResponse { + public readonly statusText: string; + public readonly status: number; + public readonly headers: Record<string, string>; + + constructor( + req: ITraceable<PenguenoRequest, ServerTrace>, + private readonly _body: Body, + opts: ResponseOpts, + ) { + this.headers = getHeaders(req.get(), opts?.headers ?? {}); + this.status = opts.status; + this.statusText = opts.statusText ?? HttpStatusCodes[this.status]!; + + req.trace.trace(getResponseMetrics(opts.status, req.get().elapsedTimeMs())); + } + + public body() { + return this._body; + } +} |