diff --git a/src/__tests__/try.spec.ts b/src/__tests__/try.spec.ts new file mode 100644 index 0000000..7e17042 --- /dev/null +++ b/src/__tests__/try.spec.ts @@ -0,0 +1,23 @@ +import { PIITry, unwrap } from "../index" +import { identity } from "../result" + +describe("PIITry", () => { + it("should wrap results in PII", async () => { + const result = await PIITry(() => "TEST_STRING") + const success = result.fold(identity, () => void 0) + expect(unwrap(success)).toBe("TEST_STRING") + }) + + it("should wrap exceptions in PII", async () => { + const result = await PIITry(() => { + throw new Error("Error message") + }) + + const errorMessage = result.fold( + () => "never", + e => unwrap(e).message, + ) + + expect(errorMessage).toBe("Error message") + }) +}) diff --git a/src/index.ts b/src/index.ts index f5814a4..3804d7c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1 +1,2 @@ export * from "./pii" +export * from "./result" diff --git a/src/result.ts b/src/result.ts new file mode 100644 index 0000000..3920045 --- /dev/null +++ b/src/result.ts @@ -0,0 +1,33 @@ +import { PII } from "./pii" + +export const identity = (x: X): X => x + +export class Ok { + constructor(private value: S) {} + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + fold(ok: (value: S) => R, _err: (err: E) => R): R { + return ok(this.value) + } +} + +export class Err { + constructor(private err: E) {} + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + fold(_ok: (value: S) => R, err: (err: E) => R): R { + return err(this.err) + } +} + +export type Result = Ok | Err + +export async function PIITry( + fn: () => S | Promise, +): Promise, PII>> { + try { + return new Ok(PII(await fn())) + } catch (e) { + return new Err(PII(e)) + } +}