'use strict' const { groupRestore, nestedRestore } = require('./modifiers') module.exports = restorer function restorer ({ secret, wcLen }) { return function compileRestore () { if (this.restore) return const paths = Object.keys(secret) .filter((path) => secret[path].precensored === false) const resetters = resetTmpl(secret, paths) const hasWildcards = wcLen > 0 const state = hasWildcards ? { secret, groupRestore, nestedRestore } : { secret } /* eslint-disable-next-line */ this.restore = Function( 'o', restoreTmpl(resetters, paths, hasWildcards) ).bind(state) } } /** * Mutates the original object to be censored by restoring its original values * prior to censoring. * * @param {object} secret Compiled object describing which target fields should * be censored and the field states. * @param {string[]} paths The list of paths to censor as provided at * initialization time. * * @returns {string} String of JavaScript to be used by `Function()`. The * string compiles to the function that does the work in the description. */ function resetTmpl (secret, paths) { return paths.map((path) => { const { circle, escPath, leadingBracket } = secret[path] const delim = leadingBracket ? '' : '.' const reset = circle ? `o.${circle} = secret[${escPath}].val` : `o${delim}${path} = secret[${escPath}].val` const clear = `secret[${escPath}].val = undefined` return ` if (secret[${escPath}].val !== undefined) { try { ${reset} } catch (e) {} ${clear} } ` }).join('') } function restoreTmpl (resetters, paths, hasWildcards) { const dynamicReset = hasWildcards === true ? ` const keys = Object.keys(secret) const len = keys.length for (var i = ${paths.length}; i < len; i++) { const k = keys[i] const o = secret[k] if (o.flat === true) this.groupRestore(o) else this.nestedRestore(o) secret[k] = null } ` : '' return ` const secret = this.secret ${resetters} ${dynamicReset} return o ` }