You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
171 lines
4.5 KiB
171 lines
4.5 KiB
3 years ago
|
'use strict'
|
||
|
|
||
|
module.exports = {
|
||
|
groupRedact,
|
||
|
groupRestore,
|
||
|
nestedRedact,
|
||
|
nestedRestore
|
||
|
}
|
||
|
|
||
|
function groupRestore ({ keys, values, target }) {
|
||
|
if (target == null) return
|
||
|
const length = keys.length
|
||
|
for (var i = 0; i < length; i++) {
|
||
|
const k = keys[i]
|
||
|
target[k] = values[i]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function groupRedact (o, path, censor, isCensorFct, censorFctTakesPath) {
|
||
|
const target = get(o, path)
|
||
|
if (target == null) return { keys: null, values: null, target: null, flat: true }
|
||
|
const keys = Object.keys(target)
|
||
|
const keysLength = keys.length
|
||
|
const pathLength = path.length
|
||
|
const pathWithKey = censorFctTakesPath ? [...path] : undefined
|
||
|
const values = new Array(keysLength)
|
||
|
|
||
|
for (var i = 0; i < keysLength; i++) {
|
||
|
const key = keys[i]
|
||
|
values[i] = target[key]
|
||
|
|
||
|
if (censorFctTakesPath) {
|
||
|
pathWithKey[pathLength] = key
|
||
|
target[key] = censor(target[key], pathWithKey)
|
||
|
} else if (isCensorFct) {
|
||
|
target[key] = censor(target[key])
|
||
|
} else {
|
||
|
target[key] = censor
|
||
|
}
|
||
|
}
|
||
|
return { keys, values, target, flat: true }
|
||
|
}
|
||
|
|
||
|
function nestedRestore (arr) {
|
||
|
const length = arr.length
|
||
|
for (var i = 0; i < length; i++) {
|
||
|
const { key, target, value } = arr[i]
|
||
|
if (has(target, key)) {
|
||
|
target[key] = value
|
||
|
}
|
||
|
/* istanbul ignore else */
|
||
|
if (typeof target === 'object') {
|
||
|
const targetKeys = Object.keys(target)
|
||
|
for (var j = 0; j < targetKeys.length; j++) {
|
||
|
const tKey = targetKeys[j]
|
||
|
const subTarget = target[tKey]
|
||
|
if (has(subTarget, key)) {
|
||
|
subTarget[key] = value
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function nestedRedact (store, o, path, ns, censor, isCensorFct, censorFctTakesPath) {
|
||
|
const target = get(o, path)
|
||
|
if (target == null) return
|
||
|
const keys = Object.keys(target)
|
||
|
const keysLength = keys.length
|
||
|
for (var i = 0; i < keysLength; i++) {
|
||
|
const key = keys[i]
|
||
|
const { value, parent, exists } =
|
||
|
specialSet(target, key, path, ns, censor, isCensorFct, censorFctTakesPath)
|
||
|
|
||
|
if (exists === true && parent !== null) {
|
||
|
store.push({ key: ns[ns.length - 1], target: parent, value })
|
||
|
}
|
||
|
}
|
||
|
return store
|
||
|
}
|
||
|
|
||
|
function has (obj, prop) {
|
||
|
return obj !== undefined && obj !== null
|
||
|
? ('hasOwn' in Object ? Object.hasOwn(obj, prop) : Object.prototype.hasOwnProperty.call(obj, prop))
|
||
|
: false
|
||
|
}
|
||
|
|
||
|
function specialSet (o, k, path, afterPath, censor, isCensorFct, censorFctTakesPath) {
|
||
|
const afterPathLen = afterPath.length
|
||
|
const lastPathIndex = afterPathLen - 1
|
||
|
const originalKey = k
|
||
|
var i = -1
|
||
|
var n
|
||
|
var nv
|
||
|
var ov
|
||
|
var oov = null
|
||
|
var exists = true
|
||
|
var wc = null
|
||
|
ov = n = o[k]
|
||
|
if (typeof n !== 'object') return { value: null, parent: null, exists }
|
||
|
while (n != null && ++i < afterPathLen) {
|
||
|
k = afterPath[i]
|
||
|
oov = ov
|
||
|
if (k !== '*' && !wc && !(typeof n === 'object' && k in n)) {
|
||
|
exists = false
|
||
|
break
|
||
|
}
|
||
|
if (k === '*') {
|
||
|
wc = k
|
||
|
if (i !== lastPathIndex) {
|
||
|
continue
|
||
|
}
|
||
|
}
|
||
|
if (wc) {
|
||
|
const wcKeys = Object.keys(n)
|
||
|
for (var j = 0; j < wcKeys.length; j++) {
|
||
|
const wck = wcKeys[j]
|
||
|
const wcov = n[wck]
|
||
|
const kIsWc = k === '*'
|
||
|
if (kIsWc || (typeof wcov === 'object' && wcov !== null && k in wcov)) {
|
||
|
if (kIsWc) {
|
||
|
ov = wcov
|
||
|
} else {
|
||
|
ov = wcov[k]
|
||
|
}
|
||
|
nv = (i !== lastPathIndex)
|
||
|
? ov
|
||
|
: (isCensorFct
|
||
|
? (censorFctTakesPath ? censor(ov, [...path, originalKey, ...afterPath]) : censor(ov))
|
||
|
: censor)
|
||
|
if (kIsWc) {
|
||
|
n[wck] = nv
|
||
|
} else {
|
||
|
if (wcov[k] === nv) {
|
||
|
exists = false
|
||
|
} else {
|
||
|
wcov[k] = (nv === undefined && censor !== undefined) || (has(wcov, k) && nv === ov) ? wcov[k] : nv
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
wc = null
|
||
|
} else {
|
||
|
ov = n[k]
|
||
|
nv = (i !== lastPathIndex)
|
||
|
? ov
|
||
|
: (isCensorFct
|
||
|
? (censorFctTakesPath ? censor(ov, [...path, originalKey, ...afterPath]) : censor(ov))
|
||
|
: censor)
|
||
|
n[k] = (has(n, k) && nv === ov) || (nv === undefined && censor !== undefined) ? n[k] : nv
|
||
|
n = n[k]
|
||
|
}
|
||
|
if (typeof n !== 'object') break
|
||
|
// prevent circular structure, see https://github.com/pinojs/pino/issues/1513
|
||
|
if (ov === oov) {
|
||
|
exists = false
|
||
|
}
|
||
|
}
|
||
|
return { value: ov, parent: oov, exists }
|
||
|
}
|
||
|
|
||
|
function get (o, p) {
|
||
|
var i = -1
|
||
|
var l = p.length
|
||
|
var n = o
|
||
|
while (n != null && ++i < l) {
|
||
|
n = n[p[i]]
|
||
|
}
|
||
|
return n
|
||
|
}
|