summaryrefslogtreecommitdiff
path: root/u/server
diff options
context:
space:
mode:
authorElizabeth Hunt <lizhunt@amazon.com>2025-05-14 18:02:34 -0700
committerElizabeth Hunt <lizhunt@amazon.com>2025-05-14 18:03:15 -0700
commit3a3fb9c8ab0c798a278f76d40de216fa96f6e2c4 (patch)
treebb44512bccceee43c57372a4ae325b5b70a6e192 /u/server
parentf316b4a015b5b2e2988b250b3c34bbb7f9994709 (diff)
downloadci-3a3fb9c8ab0c798a278f76d40de216fa96f6e2c4.tar.gz
ci-3a3fb9c8ab0c798a278f76d40de216fa96f6e2c4.zip
moar
Diffstat (limited to 'u/server')
-rw-r--r--u/server/activity/health.ts39
-rw-r--r--u/server/activity/mod.ts8
-rw-r--r--u/server/filter/json.ts32
-rw-r--r--u/server/filter/method.ts37
-rw-r--r--u/server/filter/mod.ts13
-rw-r--r--u/server/mod.ts1
6 files changed, 130 insertions, 0 deletions
diff --git a/u/server/activity/health.ts b/u/server/activity/health.ts
new file mode 100644
index 0000000..bf1f52c
--- /dev/null
+++ b/u/server/activity/health.ts
@@ -0,0 +1,39 @@
+import {
+ Either,
+ getRequiredEnv,
+ getStdout,
+ type ITraceable,
+ LogLevel,
+ type Mapper,
+ TraceUtil,
+} from "@emprespresso/pengueno";
+
+type HealthCheckInput = "healthy?";
+type HealthCheckOutput = "healthy!";
+
+const HealthCheckActivity = <Trace>(
+ check: Mapper<
+ ITraceable<HealthCheckInput, Trace>,
+ Promise<Either<Error, HealthCheckOutput>>
+ >,
+) =>
+(req: ITraceable<Request, Trace>) =>
+ req.bimap(TraceUtil.withFunctionTrace(HealthCheckActivity))
+ .flatMap((r) => r.move(<HealthCheckInput> "healthy?"))
+ .map(check)
+ .map(TraceUtil.promiseify(({ item: health, trace }) => {
+ health.mapBoth((e) => {
+ trace.addTrace(LogLevel.ERROR).trace(`${e}`);
+ return new Response(
+ "oh no, i need to eat more vegetables (。•́︿•̀。)...\n",
+ { status: 500 },
+ );
+ }, (_healthy) => {
+ const msg = `think im healthy!! (✿˘◡˘) ready to do work~`;
+ trace.trace(msg);
+ return new Response(
+ msg + "\n",
+ { status: 200 },
+ );
+ });
+ }));
diff --git a/u/server/activity/mod.ts b/u/server/activity/mod.ts
new file mode 100644
index 0000000..6908c26
--- /dev/null
+++ b/u/server/activity/mod.ts
@@ -0,0 +1,8 @@
+import type { RequestFilter } from "@emprespresso/pengueno";
+
+export class r200 extends Response {
+ public override readonly status = 200;
+}
+
+export interface IActivity<Trace> extends RequestFilter<r200, Trace> {
+}
diff --git a/u/server/filter/json.ts b/u/server/filter/json.ts
new file mode 100644
index 0000000..3f11915
--- /dev/null
+++ b/u/server/filter/json.ts
@@ -0,0 +1,32 @@
+import {
+ Either,
+ type IEither,
+ type ITraceable,
+ LogLevel,
+ type RequestFilter,
+ TraceUtil,
+} from "@emprespresso/pengueno";
+
+type JsonTransformer<JsonT, R> = (
+ json: ITraceable<JsonT>,
+) => IEither<Error, R>;
+export const json = <BodyT, Trace, JsonT = unknown>(
+ jsonTransformer: JsonTransformer<JsonT, BodyT>,
+): RequestFilter<BodyT, Trace> =>
+(r: ITraceable<Request, Trace>) =>
+ r.bimap(TraceUtil.withFunctionTrace(json))
+ .map(({ item: request }) => Either.fromFailableAsync(request.json()))
+ .map(
+ TraceUtil.promiseify(({ item: eitherJson, trace }) =>
+ eitherJson.mapLeft((errReason) => {
+ trace.addTrace(LogLevel.WARN).trace(`${errReason}`);
+ const err = "seems to be invalid JSON (>//<) can you fix?";
+ return new Error(err);
+ })
+ .flatMap(jsonTransformer)
+ .mapLeft((err) => {
+ trace.addTrace(LogLevel.WARN).trace(`${err}`);
+ return new Response(err.message, { status: 400 });
+ })
+ ),
+ ).item;
diff --git a/u/server/filter/method.ts b/u/server/filter/method.ts
new file mode 100644
index 0000000..2bf45a0
--- /dev/null
+++ b/u/server/filter/method.ts
@@ -0,0 +1,37 @@
+import {
+ Either,
+ type ITraceable,
+ LogLevel,
+ type RequestFilter,
+ TraceUtil,
+} from "@emprespresso/pengueno";
+
+type HttpMethod =
+ | "POST"
+ | "GET"
+ | "HEAD"
+ | "PUT"
+ | "DELETE"
+ | "CONNECT"
+ | "OPTIONS"
+ | "TRACE"
+ | "PATCH";
+
+export const requireMethod =
+ <Trace>(methods: Array<HttpMethod>): RequestFilter<HttpMethod, Trace> =>
+ (req: ITraceable<Request, Trace>) =>
+ req.bimap(TraceUtil.withFunctionTrace(requireMethod))
+ .map(({ item }) => Promise.resolve(item))
+ .map(TraceUtil.promiseify(({ item: request, trace }) => {
+ const { method: _method } = request;
+ const method = <HttpMethod> _method;
+ if (!methods.includes(method)) {
+ const msg = "that's not how you pet me (⋟﹏⋞)~";
+ trace.addTrace(LogLevel.WARN).trace(msg);
+ return Either.left<Response, HttpMethod>(
+ new Response(msg + "\n", { status: 405 }),
+ );
+ }
+
+ return Either.right<Response, HttpMethod>(method);
+ })).item;
diff --git a/u/server/filter/mod.ts b/u/server/filter/mod.ts
new file mode 100644
index 0000000..3256d35
--- /dev/null
+++ b/u/server/filter/mod.ts
@@ -0,0 +1,13 @@
+import type { IEither, ITraceable } from "@emprespresso/pengueno";
+
+export interface RequestFilter<
+ T,
+ Trace,
+ RIn = ITraceable<Request, Trace>,
+ Err = Response,
+> {
+ (req: RIn): Promise<IEither<Err, T>>;
+}
+
+export * from "./method.ts";
+export * from "./json.ts";
diff --git a/u/server/mod.ts b/u/server/mod.ts
index e69de29..556771d 100644
--- a/u/server/mod.ts
+++ b/u/server/mod.ts
@@ -0,0 +1 @@
+export * from "./filter/mod.ts";