Skip to content
This repository has been archived by the owner on Apr 2, 2023. It is now read-only.

Commit

Permalink
fix: merge type and constructor
Browse files Browse the repository at this point in the history
  • Loading branch information
tdreyno committed Mar 5, 2021
1 parent dae51c1 commit d61d279
Show file tree
Hide file tree
Showing 10 changed files with 42 additions and 40 deletions.
2 changes: 1 addition & 1 deletion src/__tests__/containsPII.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import PII, { containsPII } from "../index"
import { PII, containsPII } from "../index"

describe("containsPII", () => {
it("should not find PII", () => {
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/fold.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import PII, { fold, unwrap } from "../index"
import { PII, fold, unwrap } from "../index"

describe("fold", () => {
it("should fold multiple PII", () => {
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/map.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import PII, { map, unwrap } from "../index"
import { PII, map, unwrap } from "../index"

describe("map", () => {
it("should map inside PII", () => {
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/markPII.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import PII, { unwrap } from "../index"
import { PII, unwrap } from "../index"

describe("PII", () => {
it("should not leak into toString", () => {
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/test.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import PII, { test } from "../index"
import { PII, test } from "../index"

describe("test", () => {
it("should test predicate against PII", () => {
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/unwrap.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import PII, { unwrap } from "../index"
import { PII, unwrap } from "../index"

describe("unwrap", () => {
it("upwraps a value", () => {
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/unwrapObject.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import PII, { unwrapObject } from "../index"
import { PII, unwrapObject } from "../index"

describe("unwrapObject", () => {
it("should remove all wrappers", () => {
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/zipWith.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import PII, { zip2With, zip3With, zip4With, unwrap } from "../index"
import { PII, zip2With, zip3With, zip4With, unwrap } from "../index"

describe("zipWith", () => {
it("should zipWith two different types of PII", () => {
Expand Down
1 change: 0 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export * from "./pii"
export { default } from "./pii"
65 changes: 34 additions & 31 deletions src/pii.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
// Class which wraps PII and keeps logging from accessing it.
class PII<T> {
constructor(
private _fire_me_if_you_see_me_accessing_this_property_outside_pii_ts: T,
) { }

toString() {
return "PII<REDACTED>"
}

toJSON() {
return "PII<REDACTED>"
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export interface PII<T> {
toString: () => string
toJSON: () => string
}

function markPII<T, T2 = T extends PII<infer U> ? U : T>(value: T): PII<T2>
function markPII<T>(value: T): PII<T> {
return value instanceof PII ? value : new PII(value)
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const isPIIType = <T>(val: any): val is PII<T> =>
isPojo(val) && val.__brand === "PII"

export const PII = <T>(val: T): PII<T> =>
isPIIType<T>(val)
? val
: ({
__brand: "PII",
__fire_me_if_you_see_me_accessing_this_property_outside_pii_ts: val,
toString: () => "PII<REDACTED>",
toJSON: () => "PII<REDACTED>",
} as PII<T>)

export const unwrap = <A>(item: PII<A>): A =>
item["_fire_me_if_you_see_me_accessing_this_property_outside_pii_ts"]
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(item as any)[
"__fire_me_if_you_see_me_accessing_this_property_outside_pii_ts"
]

export const map = <T, T2>(fn: (item: T) => T2, item: PII<T>): PII<T2> =>
markPII(fn(unwrap(item)))
PII(fn(unwrap(item)))

export const test = <T>(fn: (item: T) => boolean, item: PII<T>): boolean =>
fn(unwrap(item))
Expand All @@ -36,28 +40,28 @@ export const fold = <A, B>(
) => B,
initial: B,
a: Array<PII<A>>,
): PII<B> => markPII(a.map(unwrap).reduce(fn, initial))
): PII<B> => PII(a.map(unwrap).reduce(fn, initial))

export const zip2With = <A, B, C>(
fn: (a: A, b: B) => C,
a: PII<A>,
b: PII<B>,
): PII<C> => markPII(fn(unwrap(a), unwrap(b)))
): PII<C> => PII(fn(unwrap(a), unwrap(b)))

export const zip3With = <A, B, C, D>(
fn: (a: A, b: B, c: C) => D,
a: PII<A>,
b: PII<B>,
c: PII<C>,
): PII<D> => markPII(fn(unwrap(a), unwrap(b), unwrap(c)))
): PII<D> => PII(fn(unwrap(a), unwrap(b), unwrap(c)))

export const zip4With = <A, B, C, D, E>(
fn: (a: A, b: B, c: C, d: D) => E,
a: PII<A>,
b: PII<B>,
c: PII<C>,
d: PII<D>,
): PII<E> => markPII(fn(unwrap(a), unwrap(b), unwrap(c), unwrap(d)))
): PII<E> => PII(fn(unwrap(a), unwrap(b), unwrap(c), unwrap(d)))

const proto = Object.prototype
const gpo = Object.getPrototypeOf
Expand Down Expand Up @@ -87,15 +91,16 @@ const visitPII = <A, T>(
}

export const containsPII = (input: unknown): boolean =>
visitPII(input, {
object: o => Object.values(o).some(containsPII),
array: a => a.some(containsPII),
primitive: p => p instanceof PII,
})
isPIIType(input)
? true
: visitPII(input, {
object: o => Object.values(o).some(containsPII),
array: a => a.some(containsPII),
primitive: p => isPIIType(p),
})

// Does not handle Set or Map for now.
export const unwrapObject = (input: unknown): unknown =>
visitPII(input instanceof PII ? unwrap(input) : input, {
visitPII(isPIIType(input) ? unwrap(input) : input, {
object: o =>
Object.keys(o).reduce((sum, key) => {
sum[key] = unwrapObject(o[key])
Expand All @@ -104,5 +109,3 @@ export const unwrapObject = (input: unknown): unknown =>
array: a => a.map(unwrapObject),
primitive: p => p,
})

export default markPII

0 comments on commit d61d279

Please sign in to comment.