summaryrefslogtreecommitdiff
path: root/u/server/filter
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/filter
parentd7e8d31c94cd713a2f4cf799e20e993acc69e361 (diff)
downloadci-d4791f3d357634daf506fb8f91cc5332a794c421.tar.gz
ci-d4791f3d357634daf506fb8f91cc5332a794c421.zip
Move to nodejs
Diffstat (limited to 'u/server/filter')
-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
4 files changed, 106 insertions, 122 deletions
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";