@@ -7,11 +7,11 @@ export interface PII<T> {
7
7
}
8
8
9
9
// eslint-disable-next-line @typescript-eslint/no-explicit-any
10
- const isPIIType = < T > ( val : any ) : val is PII < T > =>
10
+ export const isPII = < T > ( val : any ) : val is PII < T > =>
11
11
isRecord ( val ) && val . __brand === "PII"
12
12
13
13
export const PII = < T > ( val : T , msg = "REDACTED" ) : PII < T > =>
14
- isPIIType < T > ( val )
14
+ isPII < T > ( val )
15
15
? val
16
16
: ( {
17
17
__brand : "PII" ,
@@ -24,7 +24,7 @@ export function unwrap<T>(item: PII<T>): Exclude<T, PII<any>>
24
24
export function unwrap < T > ( item : T ) : Exclude < T , PII < any > >
25
25
export function unwrap < T > ( item : T | PII < T > ) : Exclude < T , PII < any > > {
26
26
// eslint-disable-next-line @typescript-eslint/no-explicit-any
27
- return isPIIType ( item )
27
+ return isPII ( item )
28
28
? ( item as any ) [
29
29
"__fire_me_if_you_see_me_accessing_this_property_outside_pii_ts"
30
30
]
@@ -135,20 +135,20 @@ export const visitPII = <A, T>(
135
135
}
136
136
137
137
export const containsPII = ( input : unknown ) : boolean =>
138
- isPIIType ( input )
138
+ isPII ( input )
139
139
? true
140
140
: visitPII ( input , {
141
141
record : o => Object . values ( o ) . some ( containsPII ) ,
142
142
map : m =>
143
143
Array . from ( m ) . some ( ( [ k , v ] ) => containsPII ( k ) || containsPII ( v ) ) ,
144
144
array : a => a . some ( containsPII ) ,
145
145
set : s => Array . from ( s ) . some ( containsPII ) ,
146
- primitive : p => isPIIType ( p ) ,
147
- object : p => isPIIType ( p ) ,
146
+ primitive : p => isPII ( p ) ,
147
+ object : p => isPII ( p ) ,
148
148
} )
149
149
150
150
export const unwrapObject = ( input : unknown ) : unknown =>
151
- visitPII ( isPIIType ( input ) ? unwrap ( input ) : input , {
151
+ visitPII ( isPII ( input ) ? unwrap ( input ) : input , {
152
152
record : o =>
153
153
Object . keys ( o ) . reduce ( ( sum , key ) => {
154
154
sum [ key ] = unwrapObject ( o [ key ] )
@@ -165,7 +165,7 @@ export const unwrapObject = (input: unknown): unknown =>
165
165
} )
166
166
167
167
export const redact = ( redactor : ( data : any ) => any , input : unknown ) : unknown =>
168
- visitPII ( isPIIType ( input ) ? redactor ( input ) : input , {
168
+ visitPII ( isPII ( input ) ? redactor ( input ) : input , {
169
169
record : o =>
170
170
Object . keys ( o ) . reduce ( ( sum , key ) => {
171
171
sum [ key ] = redact ( redactor , o [ key ] )
@@ -183,3 +183,30 @@ export const redact = (redactor: (data: any) => any, input: unknown): unknown =>
183
183
primitive : p => p ,
184
184
object : p => p ,
185
185
} )
186
+
187
+ export const detect = (
188
+ detector : ( data : any ) => boolean ,
189
+ input : unknown ,
190
+ ) : unknown =>
191
+ isPII ( input )
192
+ ? input
193
+ : detector ( input )
194
+ ? PII ( input )
195
+ : visitPII ( input , {
196
+ record : o =>
197
+ Object . keys ( o ) . reduce ( ( sum , key ) => {
198
+ sum [ key ] = detect ( detector , o [ key ] )
199
+ return sum
200
+ } , { } as Record < string , unknown > ) ,
201
+ map : m =>
202
+ new Map (
203
+ Array . from ( m ) . map ( ( [ k , v ] ) => [
204
+ detect ( detector , k ) ,
205
+ detect ( detector , v ) ,
206
+ ] ) ,
207
+ ) ,
208
+ array : a => a . map ( x => detect ( detector , x ) ) ,
209
+ set : s => new Set ( Array . from ( s ) . map ( x => detect ( detector , x ) ) ) ,
210
+ primitive : p => p ,
211
+ object : p => p ,
212
+ } )
0 commit comments