diff options
Diffstat (limited to 'u/server/response.ts')
-rw-r--r-- | u/server/response.ts | 62 |
1 files changed, 51 insertions, 11 deletions
diff --git a/u/server/response.ts b/u/server/response.ts index 59ca43d..c21819a 100644 --- a/u/server/response.ts +++ b/u/server/response.ts @@ -2,43 +2,83 @@ import { type IEither, isEither, type ITraceable, + Metric, + type PenguenoRequest, + type ServerTrace, } from "@emprespresso/pengueno"; export type ResponseBody = object | string; -export type TResponseInit = ResponseInit & { status: number }; -const withJsonResponseType = (opts: TResponseInit): TResponseInit => { +export type TResponseInit = ResponseInit & { + status: number; + headers?: Record<string, string>; +}; + +const getResponse = ( + req: PenguenoRequest, + opts: TResponseInit, +): TResponseInit => { return { ...opts, headers: { - "Content-Type": "application/json", + ...(req.baseResponseHeaders()), ...(opts?.headers), + "Content-Type": (opts?.headers?.["Content-Type"] ?? "text/plain") + + "; charset=utf-8", }, }; }; -export class JsonResponse extends Response { +const ResponseCodeMetrics = [1, 2, 3, 4, 5].map((x) => + Metric.fromName(`response.${x}xx`) +); +export const getResponseMetric = (status: number) => { + const index = (Math.floor(status / 100)) + 1; + return ResponseCodeMetrics[index] ?? ResponseCodeMetrics[5 - 1]; +}; + +export class PenguenoResponse extends Response { + constructor( + req: ITraceable<PenguenoRequest, ServerTrace>, + msg: BodyInit, + opts: TResponseInit, + ) { + const responseOpts = getResponse(req.get(), opts); + const resMetric = getResponseMetric(opts.status); + req.trace.trace(resMetric.count.withValue(1.0)); + responseOpts.headers; + super(msg, responseOpts); + } +} + +export class JsonResponse extends PenguenoResponse { constructor( - e: ITraceable<IEither<ResponseBody, ResponseBody>>, + req: ITraceable<PenguenoRequest, ServerTrace>, + e: BodyInit | IEither<ResponseBody, ResponseBody>, opts: TResponseInit, ) { - const responseOpts = withJsonResponseType(opts); - const baseBody = { - responseTime: Date.now(), + const optsWithJsonContentType = { + ...opts, + headers: { + ...opts?.headers, + "Content-Type": "application/json", + }, }; if (isEither<ResponseBody, ResponseBody>(e)) { super( + req, JSON.stringify( e.fold((err, ok) => err ? ({ error: err! }) : ({ ok: ok! })), ), - responseOpts, + optsWithJsonContentType, ); return; } super( + req, JSON.stringify( - (Math.floor(responseOpts.status / 100) < 4) ? { ok: e } : { error: e }, + (Math.floor(opts.status / 100) < 4) ? { ok: e } : { error: e }, ), - responseOpts, + optsWithJsonContentType, ); } } |