Buckets:
| const Redact = require('@pinojs/redact') | |
| const { redactFmtSym, wildcardFirstSym } = require('./symbols') | |
| // Custom rx regex equivalent to fast-redact's rx | |
| const rx = /[^.[\]]+|\[([^[\]]*?)\]/g | |
| const CENSOR = '[Redacted]' | |
| const strict = false // TODO should this be configurable? | |
| function redaction (opts, serialize) { | |
| const { paths, censor, remove } = handle(opts) | |
| const shape = paths.reduce((o, str) => { | |
| rx.lastIndex = 0 | |
| const first = rx.exec(str) | |
| const next = rx.exec(str) | |
| // ns is the top-level path segment, brackets + quoting removed. | |
| let ns = first[1] !== undefined | |
| ? first[1].replace(/^(?:"|'|`)(.*)(?:"|'|`)$/, '$1') | |
| : first[0] | |
| if (ns === '*') { | |
| ns = wildcardFirstSym | |
| } | |
| // top level key: | |
| if (next === null) { | |
| o[ns] = null | |
| return o | |
| } | |
| // path with at least two segments: | |
| // if ns is already redacted at the top level, ignore lower level redactions | |
| if (o[ns] === null) { | |
| return o | |
| } | |
| const { index } = next | |
| const nextPath = `${str.substr(index, str.length - 1)}` | |
| o[ns] = o[ns] || [] | |
| // shape is a mix of paths beginning with literal values and wildcard | |
| // paths [ "a.b.c", "*.b.z" ] should reduce to a shape of | |
| // { "a": [ "b.c", "b.z" ], *: [ "b.z" ] } | |
| // note: "b.z" is in both "a" and * arrays because "a" matches the wildcard. | |
| // (* entry has wildcardFirstSym as key) | |
| if (ns !== wildcardFirstSym && o[ns].length === 0) { | |
| // first time ns's get all '*' redactions so far | |
| o[ns].push(...(o[wildcardFirstSym] || [])) | |
| } | |
| if (ns === wildcardFirstSym) { | |
| // new * path gets added to all previously registered literal ns's. | |
| Object.keys(o).forEach(function (k) { | |
| if (o[k]) { | |
| o[k].push(nextPath) | |
| } | |
| }) | |
| } | |
| o[ns].push(nextPath) | |
| return o | |
| }, {}) | |
| // the redactor assigned to the format symbol key | |
| // provides top level redaction for instances where | |
| // an object is interpolated into the msg string | |
| const result = { | |
| [redactFmtSym]: Redact({ paths, censor, serialize, strict, remove }) | |
| } | |
| const topCensor = (...args) => { | |
| return typeof censor === 'function' ? serialize(censor(...args)) : serialize(censor) | |
| } | |
| return [...Object.keys(shape), ...Object.getOwnPropertySymbols(shape)].reduce((o, k) => { | |
| // top level key: | |
| if (shape[k] === null) { | |
| o[k] = (value) => topCensor(value, [k]) | |
| } else { | |
| const wrappedCensor = typeof censor === 'function' | |
| ? (value, path) => { | |
| return censor(value, [k, ...path]) | |
| } | |
| : censor | |
| o[k] = Redact({ | |
| paths: shape[k], | |
| censor: wrappedCensor, | |
| serialize, | |
| strict, | |
| remove | |
| }) | |
| } | |
| return o | |
| }, result) | |
| } | |
| function handle (opts) { | |
| if (Array.isArray(opts)) { | |
| opts = { paths: opts, censor: CENSOR } | |
| return opts | |
| } | |
| let { paths, censor = CENSOR, remove } = opts | |
| if (Array.isArray(paths) === false) { throw Error('pino – redact must contain an array of strings') } | |
| if (remove === true) censor = undefined | |
| return { paths, censor, remove } | |
| } | |
| module.exports = redaction | |
Xet Storage Details
- Size:
- 3.17 kB
- Xet hash:
- 7219349fd2e28f913489a0ec7dcac3c42c2d16c237bd6704c878c4313f881b69
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.