import { Either, type IEither, type ITraceable, LogLevel, Metric, PenguenoError, type PenguenoRequest, type RequestFilter, type ServerTrace, TraceUtil, } from '@emprespresso/pengueno'; export interface JsonTransformer { (json: ITraceable): IEither; } const ParseJsonMetric = Metric.fromName('JsonParse').asResult(); export const jsonModel = (jsonTransformer: JsonTransformer): RequestFilter => (r: ITraceable) => r .flatMap(TraceUtil.withFunctionTrace(jsonModel)) .flatMap(TraceUtil.withMetricTrace(ParseJsonMetric)) .map((j) => Either.fromFailableAsync(>j.get().req.json()).then((either) => either.mapLeft((errReason) => { j.trace.traceScope(LogLevel.WARN).trace(errReason); return new PenguenoError('seems to be invalid JSON (>//<) can you fix?', 400); }), ), ) .flatMapAsync(TraceUtil.promiseify(TraceUtil.traceResultingEither(ParseJsonMetric))) .map( TraceUtil.promiseify((traceableEitherJson) => traceableEitherJson .get() .mapRight((j) => traceableEitherJson.move(j)) .flatMap(jsonTransformer), ), ) .get();