summaryrefslogtreecommitdiff
path: root/u/server
diff options
context:
space:
mode:
authorElizabeth Hunt <me@liz.coffee>2025-06-20 14:53:38 -0700
committerElizabeth Hunt <me@liz.coffee>2025-06-20 14:53:38 -0700
commitd4791f3d357634daf506fb8f91cc5332a794c421 (patch)
tree1bb01d2d4d8fa74d83bb6f99f2c8aa4146ca2d11 /u/server
parentd7e8d31c94cd713a2f4cf799e20e993acc69e361 (diff)
downloadci-d4791f3d357634daf506fb8f91cc5332a794c421.tar.gz
ci-d4791f3d357634daf506fb8f91cc5332a794c421.zip
Move to nodejs
Diffstat (limited to 'u/server')
-rw-r--r--u/server/activity/fourohfour.ts37
-rw-r--r--u/server/activity/health.ts108
-rw-r--r--u/server/activity/index.ts8
-rw-r--r--u/server/activity/mod.ts13
-rw-r--r--u/server/filter/index.ts34
-rw-r--r--u/server/filter/json.ts92
-rw-r--r--u/server/filter/method.ts67
-rw-r--r--u/server/filter/mod.ts35
-rw-r--r--u/server/index.ts7
-rw-r--r--u/server/mod.ts7
-rw-r--r--u/server/request.ts74
-rw-r--r--u/server/response.ts139
12 files changed, 291 insertions, 330 deletions
diff --git a/u/server/activity/fourohfour.ts b/u/server/activity/fourohfour.ts
index 33cfe5f..cd90ba0 100644
--- a/u/server/activity/fourohfour.ts
+++ b/u/server/activity/fourohfour.ts
@@ -1,29 +1,28 @@
import {
- type IActivity,
- type ITraceable,
- JsonResponse,
- type PenguenoRequest,
- type ServerTrace,
-} from "@emprespresso/pengueno";
+ type IActivity,
+ type ITraceable,
+ JsonResponse,
+ type PenguenoRequest,
+ type ServerTrace,
+} from '@emprespresso/pengueno';
const messages = [
- "D: meow-t found! your api call ran away!",
- "404-bidden! but like...in a cute way >:3 !",
- ":< your data went on a paw-sible vacation!",
- "uwu~ not found, but found our hearts instead!",
+ 'D: meow-t found! your api call ran away!',
+ '404-bidden! but like...in a cute way >:3 !',
+ ':< your data went on a paw-sible vacation!',
+ 'uwu~ not found, but found our hearts instead!',
];
-const randomFourOhFour = () =>
- messages[Math.floor(Math.random() * messages.length)];
+const randomFourOhFour = () => messages[Math.floor(Math.random() * messages.length)]!;
export interface IFourOhFourActivity {
- fourOhFour: IActivity;
+ fourOhFour: IActivity;
}
export class FourOhFourActivityImpl implements IFourOhFourActivity {
- public fourOhFour(req: ITraceable<PenguenoRequest, ServerTrace>) {
- return req
- .move(new JsonResponse(req, randomFourOhFour(), { status: 404 }))
- .map((resp) => Promise.resolve(resp.get()))
- .get();
- }
+ public fourOhFour(req: ITraceable<PenguenoRequest, ServerTrace>) {
+ return req
+ .move(new JsonResponse(req, randomFourOhFour(), { status: 404 }))
+ .map((resp) => Promise.resolve(resp.get()))
+ .get();
+ }
}
diff --git a/u/server/activity/health.ts b/u/server/activity/health.ts
index 95dfa97..b3ae559 100644
--- a/u/server/activity/health.ts
+++ b/u/server/activity/health.ts
@@ -1,71 +1,67 @@
import {
- type IActivity,
- type IEither,
- type ITraceable,
- JsonResponse,
- LogLevel,
- type Mapper,
- Metric,
- type PenguenoRequest,
- type ServerTrace,
- TraceUtil,
-} from "@emprespresso/pengueno";
+ type IActivity,
+ type IEither,
+ IMetric,
+ type ITraceable,
+ JsonResponse,
+ LogLevel,
+ type Mapper,
+ Metric,
+ type PenguenoRequest,
+ type ServerTrace,
+ TraceUtil,
+} from '@emprespresso/pengueno';
export enum HealthCheckInput {
- CHECK,
+ CHECK,
}
export enum HealthCheckOutput {
- YAASSSLAYQUEEN,
+ YAASSSLAYQUEEN,
}
export interface IHealthCheckActivity {
- checkHealth: IActivity;
+ checkHealth: IActivity;
}
-const healthCheckMetric = Metric.fromName("Health");
+const healthCheckMetric: IMetric = Metric.fromName('Health');
export interface HealthChecker
- extends Mapper<
- ITraceable<HealthCheckInput, ServerTrace>,
- Promise<IEither<Error, HealthCheckOutput>>
- > {}
+ extends Mapper<ITraceable<HealthCheckInput, ServerTrace>, Promise<IEither<Error, HealthCheckOutput>>> {}
export class HealthCheckActivityImpl implements IHealthCheckActivity {
- constructor(private readonly check: HealthChecker) {}
+ constructor(private readonly check: HealthChecker) {}
- public checkHealth(req: ITraceable<PenguenoRequest, ServerTrace>) {
- return req
- .bimap(TraceUtil.withFunctionTrace(this.checkHealth))
- .bimap(TraceUtil.withMetricTrace(healthCheckMetric))
- .flatMap((r) =>
- r.move(HealthCheckInput.CHECK).map((input) => this.check(input)),
- )
- .peek(
- TraceUtil.promiseify((h) =>
- h.get().fold(({ isLeft, value }) => {
- if (!isLeft) {
- h.trace.trace(healthCheckMetric.success);
- return;
- }
- h.trace.trace(healthCheckMetric.failure);
- h.trace.addTrace(LogLevel.ERROR).trace(value);
- }),
- ),
- )
- .map(
- TraceUtil.promiseify((h) =>
- h
- .get()
- .mapBoth(
- () => "oh no, i need to eat more vegetables (。•́︿•̀。)...",
- () => "think im healthy!! (✿˘◡˘) ready to do work~",
+ public checkHealth(req: ITraceable<PenguenoRequest, ServerTrace>) {
+ return req
+ .bimap(TraceUtil.withFunctionTrace(this.checkHealth))
+ .bimap(TraceUtil.withMetricTrace(healthCheckMetric))
+ .flatMap((r) => r.move(HealthCheckInput.CHECK).map((input) => this.check(input)))
+ .peek(
+ TraceUtil.promiseify((h) =>
+ h.get().fold(({ isLeft, value }) => {
+ if (!isLeft) {
+ h.trace.trace(healthCheckMetric.success);
+ return;
+ }
+ h.trace.trace(healthCheckMetric.failure);
+ h.trace.addTrace(LogLevel.ERROR).trace(value);
+ }),
+ ),
)
- .fold(
- ({ isLeft, value: message }) =>
- new JsonResponse(req, message, {
- status: isLeft ? 500 : 200,
- }),
- ),
- ),
- )
- .get();
- }
+ .map(
+ TraceUtil.promiseify((h) =>
+ h
+ .get()
+ .mapBoth(
+ () => 'oh no, i need to eat more vegetables (。•́︿•̀。)...',
+ () => 'think im healthy!! (✿˘◡˘) ready to do work~',
+ )
+ .fold(
+ ({ isLeft, value: message }) =>
+ new JsonResponse(req, message, {
+ status: isLeft ? 500 : 200,
+ }),
+ ),
+ ),
+ )
+ .get();
+ }
}
diff --git a/u/server/activity/index.ts b/u/server/activity/index.ts
new file mode 100644
index 0000000..fa0a6b2
--- /dev/null
+++ b/u/server/activity/index.ts
@@ -0,0 +1,8 @@
+import type { ITraceable, PenguenoRequest, PenguenoResponse, ServerTrace } from '@emprespresso/pengueno';
+
+export interface IActivity {
+ (req: ITraceable<PenguenoRequest, ServerTrace>): Promise<PenguenoResponse>;
+}
+
+export * from './health.js';
+export * from './fourohfour.js';
diff --git a/u/server/activity/mod.ts b/u/server/activity/mod.ts
deleted file mode 100644
index 82d8ec4..0000000
--- a/u/server/activity/mod.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import type {
- ITraceable,
- PenguenoRequest,
- PenguenoResponse,
- ServerTrace,
-} from "@emprespresso/pengueno";
-
-export interface IActivity {
- (req: ITraceable<PenguenoRequest, ServerTrace>): Promise<PenguenoResponse>;
-}
-
-export * from "./health.ts";
-export * from "./fourohfour.ts";
diff --git a/u/server/filter/index.ts b/u/server/filter/index.ts
new file mode 100644
index 0000000..62a584d
--- /dev/null
+++ b/u/server/filter/index.ts
@@ -0,0 +1,34 @@
+import {
+ type IEither,
+ type ITraceable,
+ LogLevel,
+ type PenguenoRequest,
+ type ServerTrace,
+} from '@emprespresso/pengueno';
+
+export enum ErrorSource {
+ USER = LogLevel.WARN,
+ SYSTEM = LogLevel.ERROR,
+}
+
+export class PenguenoError extends Error {
+ public readonly source: ErrorSource;
+ constructor(
+ override readonly message: string,
+ public readonly status: number,
+ ) {
+ super(message);
+ this.source = Math.floor(status / 100) === 4 ? ErrorSource.USER : ErrorSource.SYSTEM;
+ }
+}
+
+export interface RequestFilter<
+ T,
+ Err extends PenguenoError = PenguenoError,
+ RIn = ITraceable<PenguenoRequest, ServerTrace>,
+> {
+ (req: RIn): Promise<IEither<Err, T>>;
+}
+
+export * from './method.js';
+export * from './json.js';
diff --git a/u/server/filter/json.ts b/u/server/filter/json.ts
index 145d1be..527d483 100644
--- a/u/server/filter/json.ts
+++ b/u/server/filter/json.ts
@@ -1,54 +1,50 @@
import {
- Either,
- type IEither,
- type ITraceable,
- LogLevel,
- Metric,
- PenguenoError,
- type PenguenoRequest,
- type RequestFilter,
- type ServerTrace,
- TraceUtil,
-} from "@emprespresso/pengueno";
+ Either,
+ type IEither,
+ type ITraceable,
+ LogLevel,
+ Metric,
+ PenguenoError,
+ type PenguenoRequest,
+ type RequestFilter,
+ type ServerTrace,
+ TraceUtil,
+} from '@emprespresso/pengueno';
export interface JsonTransformer<R, ParsedJson = unknown> {
- (json: ITraceable<ParsedJson, ServerTrace>): IEither<PenguenoError, R>;
+ (json: ITraceable<ParsedJson, ServerTrace>): IEither<PenguenoError, R>;
}
-const ParseJsonMetric = Metric.fromName("JsonParse");
+const ParseJsonMetric = Metric.fromName('JsonParse');
export const jsonModel =
- <MessageT>(
- jsonTransformer: JsonTransformer<MessageT>,
- ): RequestFilter<MessageT> =>
- (r: ITraceable<PenguenoRequest, ServerTrace>) =>
- r
- .bimap(TraceUtil.withFunctionTrace(jsonModel))
- .bimap(TraceUtil.withMetricTrace(ParseJsonMetric))
- .map((j) =>
- Either.fromFailableAsync<Error, MessageT>(() => j.get().json()).then(
- (either) =>
- either.mapLeft((errReason) => {
- j.trace.addTrace(LogLevel.WARN).trace(errReason);
- return new PenguenoError(
- "seems to be invalid JSON (>//<) can you fix?",
- 400,
- );
- }),
- ),
- )
- .peek(
- TraceUtil.promiseify((traceableEither) =>
- traceableEither.get().fold(({ isLeft }) =>
- traceableEither.trace.trace(ParseJsonMetric[isLeft ? "failure" : "success"])
- ),
- ),
- )
- .map(
- TraceUtil.promiseify((traceableEitherJson) =>
- traceableEitherJson
- .get()
- .mapRight((j) => traceableEitherJson.move(j))
- .flatMap(jsonTransformer),
- ),
- )
- .get();
+ <MessageT>(jsonTransformer: JsonTransformer<MessageT>): RequestFilter<MessageT> =>
+ (r: ITraceable<PenguenoRequest, ServerTrace>) =>
+ r
+ .bimap(TraceUtil.withFunctionTrace(jsonModel))
+ .bimap(TraceUtil.withMetricTrace(ParseJsonMetric))
+ .map((j) =>
+ Either.fromFailableAsync<Error, MessageT>(<Promise<MessageT>>j.get().json()).then((either) =>
+ either.mapLeft((errReason) => {
+ j.trace.addTrace(LogLevel.WARN).trace(errReason);
+ return new PenguenoError('seems to be invalid JSON (>//<) can you fix?', 400);
+ }),
+ ),
+ )
+ .peek(
+ TraceUtil.promiseify((traceableEither) =>
+ traceableEither
+ .get()
+ .fold(({ isLeft }) =>
+ traceableEither.trace.trace(ParseJsonMetric[isLeft ? 'failure' : 'success']),
+ ),
+ ),
+ )
+ .map(
+ TraceUtil.promiseify((traceableEitherJson) =>
+ traceableEitherJson
+ .get()
+ .mapRight((j) => traceableEitherJson.move(j))
+ .flatMap(jsonTransformer),
+ ),
+ )
+ .get();
diff --git a/u/server/filter/method.ts b/u/server/filter/method.ts
index 9901c6f..5ca5716 100644
--- a/u/server/filter/method.ts
+++ b/u/server/filter/method.ts
@@ -1,43 +1,32 @@
import {
- Either,
- type ITraceable,
- LogLevel,
- PenguenoError,
- type PenguenoRequest,
- type RequestFilter,
- type ServerTrace,
- TraceUtil,
-} from "@emprespresso/pengueno";
+ Either,
+ type ITraceable,
+ LogLevel,
+ PenguenoError,
+ type PenguenoRequest,
+ type RequestFilter,
+ type ServerTrace,
+ TraceUtil,
+} from '@emprespresso/pengueno';
-type HttpMethod =
- | "POST"
- | "GET"
- | "HEAD"
- | "PUT"
- | "DELETE"
- | "CONNECT"
- | "OPTIONS"
- | "TRACE"
- | "PATCH";
+type HttpMethod = 'POST' | 'GET' | 'HEAD' | 'PUT' | 'DELETE' | 'CONNECT' | 'OPTIONS' | 'TRACE' | 'PATCH';
export const requireMethod =
- (methods: Array<HttpMethod>): RequestFilter<HttpMethod> =>
- (req: ITraceable<PenguenoRequest, ServerTrace>) =>
- req
- .bimap(TraceUtil.withFunctionTrace(requireMethod))
- .move(Promise.resolve(req.get()))
- .map(
- TraceUtil.promiseify((t) => {
- const { method: _method } = t.get();
- const method = <HttpMethod>_method;
- if (!methods.includes(method)) {
- const msg = "that's not how you pet me (⋟﹏⋞)~";
- t.trace.addTrace(LogLevel.WARN).trace(msg);
- return Either.left<PenguenoError, HttpMethod>(
- new PenguenoError(msg, 405),
- );
- }
- return Either.right<PenguenoError, HttpMethod>(method);
- }),
- )
- .get();
+ (methods: Array<HttpMethod>): RequestFilter<HttpMethod> =>
+ (req: ITraceable<PenguenoRequest, ServerTrace>) =>
+ req
+ .bimap(TraceUtil.withFunctionTrace(requireMethod))
+ .move(Promise.resolve(req.get()))
+ .map(
+ TraceUtil.promiseify((t) => {
+ const { method: _method } = t.get();
+ const method = <HttpMethod>_method;
+ if (!methods.includes(method)) {
+ const msg = "that's not how you pet me (⋟﹏⋞)~";
+ t.trace.addTrace(LogLevel.WARN).trace(msg);
+ return Either.left<PenguenoError, HttpMethod>(new PenguenoError(msg, 405));
+ }
+ return Either.right<PenguenoError, HttpMethod>(method);
+ }),
+ )
+ .get();
diff --git a/u/server/filter/mod.ts b/u/server/filter/mod.ts
deleted file mode 100644
index 0e0a4cb..0000000
--- a/u/server/filter/mod.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import {
- type IEither,
- type ITraceable,
- LogLevel,
- type PenguenoRequest,
- type ServerTrace,
-} from "@emprespresso/pengueno";
-
-export enum ErrorSource {
- USER = LogLevel.WARN,
- SYSTEM = LogLevel.ERROR,
-}
-
-export class PenguenoError extends Error {
- public readonly source: ErrorSource;
- constructor(
- override readonly message: string,
- public readonly status: number,
- ) {
- super(message);
- this.source =
- Math.floor(status / 100) === 4 ? ErrorSource.USER : ErrorSource.SYSTEM;
- }
-}
-
-export interface RequestFilter<
- T,
- Err extends PenguenoError = PenguenoError,
- RIn = ITraceable<PenguenoRequest, ServerTrace>,
-> {
- (req: RIn): Promise<IEither<Err, T>>;
-}
-
-export * from "./method.ts";
-export * from "./json.ts";
diff --git a/u/server/index.ts b/u/server/index.ts
new file mode 100644
index 0000000..17cbbdf
--- /dev/null
+++ b/u/server/index.ts
@@ -0,0 +1,7 @@
+import type { LogMetricTraceSupplier } from '@emprespresso/pengueno';
+export type ServerTrace = LogMetricTraceSupplier;
+
+export * from './activity/index.js';
+export * from './filter/index.js';
+export * from './response.js';
+export * from './request.js';
diff --git a/u/server/mod.ts b/u/server/mod.ts
deleted file mode 100644
index 866b5f9..0000000
--- a/u/server/mod.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import type { LogMetricTraceSupplier } from "@emprespresso/pengueno";
-export type ServerTrace = LogMetricTraceSupplier;
-
-export * from "./activity/mod.ts";
-export * from "./filter/mod.ts";
-export * from "./response.ts";
-export * from "./request.ts";
diff --git a/u/server/request.ts b/u/server/request.ts
index 72e812a..10610f1 100644
--- a/u/server/request.ts
+++ b/u/server/request.ts
@@ -1,49 +1,39 @@
-import { LogMetricTraceable, LogTraceable } from "@emprespresso/pengueno";
-import { TraceUtil } from "../trace/util.ts";
+import { TraceUtil, LogMetricTraceable, LogTraceable } from '@emprespresso/pengueno';
-const greetings = [
- "hewwo :D",
- "hiya cutie",
- "boop!",
- "sending virtual hugs!",
- "stay pawsitive",
-];
-const penguenoGreeting = () =>
- greetings[Math.floor(Math.random() * greetings.length)];
+const greetings = ['hewwo :D', 'hiya cutie', 'boop!', 'sending virtual hugs!', 'stay pawsitive'];
+const penguenoGreeting = () => greetings[Math.floor(Math.random() * greetings.length)];
export class PenguenoRequest extends Request {
- private constructor(
- _input: Request,
- public readonly id: string,
- public readonly at: Date,
- ) {
- super(_input);
- }
+ private constructor(
+ _input: Request,
+ public readonly id: string,
+ public readonly at: Date,
+ ) {
+ super(_input);
+ }
- public baseResponseHeaders(): Record<string, string> {
- const ServerRequestTime = this.at.getTime();
- const ServerResponseTime = Date.now();
- const DeltaTime = ServerResponseTime - ServerRequestTime;
- const RequestId = this.id;
+ public baseResponseHeaders(): Record<string, string> {
+ const ServerRequestTime = this.at.getTime();
+ const ServerResponseTime = Date.now();
+ const DeltaTime = ServerResponseTime - ServerRequestTime;
+ const RequestId = this.id;
- return Object.entries({
- RequestId,
- ServerRequestTime,
- ServerResponseTime,
- DeltaTime,
- Hai: penguenoGreeting(),
- }).reduce((acc, [key, val]) => ({ ...acc, [key]: val.toString() }), {});
- }
+ return Object.entries({
+ RequestId,
+ ServerRequestTime,
+ ServerResponseTime,
+ DeltaTime,
+ Hai: penguenoGreeting(),
+ }).reduce((acc, [key, val]) => ({ ...acc, [key]: val!.toString() }), {});
+ }
- public static from(request: Request): LogMetricTraceable<PenguenoRequest> {
- const id = crypto.randomUUID();
- const url = new URL(request.url);
- const { pathname } = url;
- const logTraceable = LogTraceable.of(
- new PenguenoRequest(request, id, new Date()),
- ).bimap(
- TraceUtil.withTrace(`RequestId = ${id}, Method = ${request.method}, Path = ${pathname}`),
- );
- return LogMetricTraceable.ofLogTraceable(logTraceable);
- }
+ public static from(request: Request): LogMetricTraceable<PenguenoRequest> {
+ const id = crypto.randomUUID();
+ const url = new URL(request.url);
+ const { pathname } = url;
+ const logTraceable = LogTraceable.of(new PenguenoRequest(request, id, new Date())).bimap(
+ TraceUtil.withTrace(`RequestId = ${id}, Method = ${request.method}, Path = ${pathname}`),
+ );
+ return LogMetricTraceable.ofLogTraceable(logTraceable);
+ }
}
diff --git a/u/server/response.ts b/u/server/response.ts
index 629dbb5..18d70b5 100644
--- a/u/server/response.ts
+++ b/u/server/response.ts
@@ -1,86 +1,83 @@
import {
- type IEither,
- isEither,
- type ITraceable,
- Metric,
- type PenguenoRequest,
- type ServerTrace,
-} from "@emprespresso/pengueno";
+ type IEither,
+ isEither,
+ type ITraceable,
+ Metric,
+ type PenguenoRequest,
+ type ServerTrace,
+} from '@emprespresso/pengueno';
+export type BodyInit =
+ | ArrayBuffer
+ | AsyncIterable<Uint8Array>
+ | Blob
+ | FormData
+ | Iterable<Uint8Array>
+ | NodeJS.ArrayBufferView
+ | URLSearchParams
+ | null
+ | string;
export type ResponseBody = object | string;
-export type TResponseInit = ResponseInit & {
- status: number;
- headers?: Record<string, string>;
+export type TResponseInit = Omit<ResponseInit, 'headers'> & {
+ status: number;
+ headers?: Record<string, string>;
};
-const getResponse = (
- req: PenguenoRequest,
- opts: TResponseInit,
-): TResponseInit => {
- return {
- ...opts,
- headers: {
- ...req.baseResponseHeaders(),
- ...opts?.headers,
- "Content-Type":
- (opts?.headers?.["Content-Type"] ?? "text/plain") + "; charset=utf-8",
- },
- };
+const getResponse = (req: PenguenoRequest, opts: TResponseInit): ResponseInit => {
+ const baseHeaders = req.baseResponseHeaders();
+ const optHeaders = opts.headers || {};
+
+ return {
+ ...opts,
+ headers: {
+ ...baseHeaders,
+ ...optHeaders,
+ 'Content-Type': (optHeaders['Content-Type'] ?? 'text/plain') + '; charset=utf-8',
+ } as Record<string, string>,
+ };
};
-const ResponseCodeMetrics = [0, 1, 2, 3, 4, 5].map((x) =>
- Metric.fromName(`response.${x}xx`),
-);
-export const getResponseMetric = (status: number) => {
- const index = Math.floor(status / 100);
- return ResponseCodeMetrics[index] ?? ResponseCodeMetrics[5];
+const ResponseCodeMetrics = [0, 1, 2, 3, 4, 5].map((x) => Metric.fromName(`response.${x}xx`));
+export const getResponseMetrics = (status: number) => {
+ const index = Math.floor(status / 100);
+ return ResponseCodeMetrics.map((metric, i) => metric.count.withValue(i === index ? 1.0 : 0.0));
};
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);
- }
+ constructor(req: ITraceable<PenguenoRequest, ServerTrace>, msg: BodyInit, opts: TResponseInit) {
+ const responseOpts = getResponse(req.get(), opts);
+ for (const metric of getResponseMetrics(opts.status)) {
+ req.trace.trace(metric);
+ }
+ super(msg, responseOpts);
+ }
}
export class JsonResponse extends PenguenoResponse {
- constructor(
- req: ITraceable<PenguenoRequest, ServerTrace>,
- e: BodyInit | IEither<ResponseBody, ResponseBody>,
- opts: TResponseInit,
- ) {
- const optsWithJsonContentType = {
- ...opts,
- headers: {
- ...opts?.headers,
- "Content-Type": "application/json",
- },
- };
- if (isEither<ResponseBody, ResponseBody>(e)) {
- super(
- req,
- JSON.stringify(
- e.fold(({ isLeft, value }) =>
- isLeft ? { error: value } : { ok: value },
- ),
- ),
- optsWithJsonContentType,
- );
- return;
+ constructor(
+ req: ITraceable<PenguenoRequest, ServerTrace>,
+ e: BodyInit | IEither<ResponseBody, ResponseBody>,
+ opts: TResponseInit,
+ ) {
+ const optsWithJsonContentType: TResponseInit = {
+ ...opts,
+ headers: {
+ ...opts.headers,
+ 'Content-Type': 'application/json',
+ },
+ };
+ if (isEither<ResponseBody, ResponseBody>(e)) {
+ super(
+ req,
+ JSON.stringify(e.fold(({ isLeft, value }) => (isLeft ? { error: value } : { ok: value }))),
+ optsWithJsonContentType,
+ );
+ return;
+ }
+ super(
+ req,
+ JSON.stringify(Math.floor(opts.status / 100) > 4 ? { error: e } : { ok: e }),
+ optsWithJsonContentType,
+ );
}
- super(
- req,
- JSON.stringify(
- Math.floor(opts.status / 100) > 4 ? { error: e } : { ok: e },
- ),
- optsWithJsonContentType,
- );
- }
}