summaryrefslogtreecommitdiff
path: root/u/server/response.ts
diff options
context:
space:
mode:
Diffstat (limited to 'u/server/response.ts')
-rw-r--r--u/server/response.ts62
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,
);
}
}