forked from waja/action-debian-package
		
	update
This commit is contained in:
		
							parent
							
								
									d9becc67b6
								
							
						
					
					
						commit
						9308795b8b
					
				
					 964 changed files with 104265 additions and 16 deletions
				
			
		
							
								
								
									
										9
									
								
								node_modules/fast-redact/.travis.yml
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								node_modules/fast-redact/.travis.yml
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
language: node_js
 | 
			
		||||
sudo: false
 | 
			
		||||
node_js:
 | 
			
		||||
  - 6
 | 
			
		||||
  - 8
 | 
			
		||||
  - 10
 | 
			
		||||
  - 11
 | 
			
		||||
script:
 | 
			
		||||
  - npm run ci
 | 
			
		||||
							
								
								
									
										21
									
								
								node_modules/fast-redact/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								node_modules/fast-redact/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,21 @@
 | 
			
		|||
The MIT License (MIT)
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2019-2020 David Mark Clements
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
in the Software without restriction, including without limitation the rights
 | 
			
		||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
furnished to do so, subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
SOFTWARE.
 | 
			
		||||
							
								
								
									
										148
									
								
								node_modules/fast-redact/benchmark/index.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								node_modules/fast-redact/benchmark/index.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,148 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
const bench = require('fastbench')
 | 
			
		||||
const noir = require('pino-noir')(['a.b.c'])
 | 
			
		||||
const fastRedact = require('..')
 | 
			
		||||
const redactNoSerialize = fastRedact({ paths: ['a.b.c'], serialize: false })
 | 
			
		||||
const redactWildNoSerialize = fastRedact({ paths: ['a.b.*'], serialize: false })
 | 
			
		||||
const redactIntermediateWildNoSerialize = fastRedact({ paths: ['a.*.c'], serialize: false })
 | 
			
		||||
const redact = fastRedact({ paths: ['a.b.c'] })
 | 
			
		||||
const noirWild = require('pino-noir')(['a.b.*'])
 | 
			
		||||
const redactWild = fastRedact({ paths: ['a.b.*'] })
 | 
			
		||||
const redactIntermediateWild = fastRedact({ paths: ['a.*.c'] })
 | 
			
		||||
const redactIntermediateWildMatchWildOutcome = fastRedact({ paths: ['a.*.c', 'a.*.b', 'a.*.a'] })
 | 
			
		||||
const redactStaticMatchWildOutcome = fastRedact({ paths: ['a.b.c', 'a.d.a', 'a.d.b', 'a.d.c'] })
 | 
			
		||||
const noirCensorFunction = require('pino-noir')(['a.b.*'], (v) => v + '.')
 | 
			
		||||
const redactCensorFunction = fastRedact({ paths: ['a.b.*'], censor: (v) => v + '.', serialize: false })
 | 
			
		||||
 | 
			
		||||
const obj = {
 | 
			
		||||
  a: {
 | 
			
		||||
    b: {
 | 
			
		||||
      c: 's'
 | 
			
		||||
    },
 | 
			
		||||
    d: {
 | 
			
		||||
      a: 's',
 | 
			
		||||
      b: 's',
 | 
			
		||||
      c: 's'
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const max = 500
 | 
			
		||||
 | 
			
		||||
var run = bench([
 | 
			
		||||
  function benchNoirV2 (cb) {
 | 
			
		||||
    for (var i = 0; i < max; i++) {
 | 
			
		||||
      noir.a(obj.a)
 | 
			
		||||
    }
 | 
			
		||||
    setImmediate(cb)
 | 
			
		||||
  },
 | 
			
		||||
  function benchFastRedact (cb) {
 | 
			
		||||
    for (var i = 0; i < max; i++) {
 | 
			
		||||
      redactNoSerialize(obj)
 | 
			
		||||
    }
 | 
			
		||||
    setImmediate(cb)
 | 
			
		||||
  },
 | 
			
		||||
  function benchFastRedactRestore (cb) {
 | 
			
		||||
    for (var i = 0; i < max; i++) {
 | 
			
		||||
      redactNoSerialize(obj)
 | 
			
		||||
      redactNoSerialize.restore(obj)
 | 
			
		||||
    }
 | 
			
		||||
    setImmediate(cb)
 | 
			
		||||
  },
 | 
			
		||||
  function benchNoirV2Wild (cb) {
 | 
			
		||||
    for (var i = 0; i < max; i++) {
 | 
			
		||||
      noirWild.a(obj.a)
 | 
			
		||||
    }
 | 
			
		||||
    setImmediate(cb)
 | 
			
		||||
  },
 | 
			
		||||
  function benchFastRedactWild (cb) {
 | 
			
		||||
    for (var i = 0; i < max; i++) {
 | 
			
		||||
      redactWildNoSerialize(obj)
 | 
			
		||||
    }
 | 
			
		||||
    setImmediate(cb)
 | 
			
		||||
  },
 | 
			
		||||
  function benchFastRedactWildRestore (cb) {
 | 
			
		||||
    for (var i = 0; i < max; i++) {
 | 
			
		||||
      redactWildNoSerialize(obj)
 | 
			
		||||
      redactWildNoSerialize.restore(obj)
 | 
			
		||||
    }
 | 
			
		||||
    setImmediate(cb)
 | 
			
		||||
  },
 | 
			
		||||
  function benchFastRedactIntermediateWild (cb) {
 | 
			
		||||
    for (var i = 0; i < max; i++) {
 | 
			
		||||
      redactIntermediateWildNoSerialize(obj)
 | 
			
		||||
    }
 | 
			
		||||
    setImmediate(cb)
 | 
			
		||||
  },
 | 
			
		||||
  function benchFastRedactIntermediateWildRestore (cb) {
 | 
			
		||||
    for (var i = 0; i < max; i++) {
 | 
			
		||||
      redactIntermediateWildNoSerialize(obj)
 | 
			
		||||
      redactIntermediateWildNoSerialize.restore(obj)
 | 
			
		||||
    }
 | 
			
		||||
    setImmediate(cb)
 | 
			
		||||
  },
 | 
			
		||||
  function benchJSONStringify (cb) {
 | 
			
		||||
    for (var i = 0; i < max; i++) {
 | 
			
		||||
      JSON.stringify(obj)
 | 
			
		||||
    }
 | 
			
		||||
    setImmediate(cb)
 | 
			
		||||
  },
 | 
			
		||||
  function benchNoirV2Serialize (cb) {
 | 
			
		||||
    for (var i = 0; i < max; i++) {
 | 
			
		||||
      noir.a(obj.a)
 | 
			
		||||
      JSON.stringify(obj)
 | 
			
		||||
    }
 | 
			
		||||
    setImmediate(cb)
 | 
			
		||||
  },
 | 
			
		||||
  function benchFastRedactSerialize (cb) {
 | 
			
		||||
    for (var i = 0; i < max; i++) {
 | 
			
		||||
      redact(obj)
 | 
			
		||||
    }
 | 
			
		||||
    setImmediate(cb)
 | 
			
		||||
  },
 | 
			
		||||
  function benchNoirV2WildSerialize (cb) {
 | 
			
		||||
    for (var i = 0; i < max; i++) {
 | 
			
		||||
      noirWild.a(obj.a)
 | 
			
		||||
      JSON.stringify(obj)
 | 
			
		||||
    }
 | 
			
		||||
    setImmediate(cb)
 | 
			
		||||
  },
 | 
			
		||||
  function benchFastRedactWildSerialize (cb) {
 | 
			
		||||
    for (var i = 0; i < max; i++) {
 | 
			
		||||
      redactWild(obj)
 | 
			
		||||
    }
 | 
			
		||||
    setImmediate(cb)
 | 
			
		||||
  },
 | 
			
		||||
  function benchFastRedactIntermediateWildSerialize (cb) {
 | 
			
		||||
    for (var i = 0; i < max; i++) {
 | 
			
		||||
      redactIntermediateWild(obj)
 | 
			
		||||
    }
 | 
			
		||||
    setImmediate(cb)
 | 
			
		||||
  },
 | 
			
		||||
  function benchFastRedactIntermediateWildMatchWildOutcomeSerialize (cb) {
 | 
			
		||||
    for (var i = 0; i < max; i++) {
 | 
			
		||||
      redactIntermediateWildMatchWildOutcome(obj)
 | 
			
		||||
    }
 | 
			
		||||
    setImmediate(cb)
 | 
			
		||||
  },
 | 
			
		||||
  function benchFastRedactStaticMatchWildOutcomeSerialize (cb) {
 | 
			
		||||
    for (var i = 0; i < max; i++) {
 | 
			
		||||
      redactStaticMatchWildOutcome(obj)
 | 
			
		||||
    }
 | 
			
		||||
    setImmediate(cb)
 | 
			
		||||
  },
 | 
			
		||||
  function benchNoirV2CensorFunction (cb) {
 | 
			
		||||
    for (var i = 0; i < max; i++) {
 | 
			
		||||
      noirCensorFunction.a(obj.a)
 | 
			
		||||
    }
 | 
			
		||||
    setImmediate(cb)
 | 
			
		||||
  },
 | 
			
		||||
  function benchFastRedactCensorFunction (cb) {
 | 
			
		||||
    for (var i = 0; i < max; i++) {
 | 
			
		||||
      redactCensorFunction(obj)
 | 
			
		||||
    }
 | 
			
		||||
    setImmediate(cb)
 | 
			
		||||
  }
 | 
			
		||||
], 500)
 | 
			
		||||
 | 
			
		||||
run(run)
 | 
			
		||||
							
								
								
									
										14
									
								
								node_modules/fast-redact/example/default-usage.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								node_modules/fast-redact/example/default-usage.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,14 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
const fastRedact = require('..')
 | 
			
		||||
const fauxRequest = {
 | 
			
		||||
  headers: {
 | 
			
		||||
    host: 'http://example.com',
 | 
			
		||||
    cookie: `oh oh we don't want this exposed in logs in etc.`,
 | 
			
		||||
    referer: `if we're cool maybe we'll even redact this`
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
const redact = fastRedact({
 | 
			
		||||
  paths: ['headers.cookie', 'headers.referer']
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
console.log(redact(fauxRequest))
 | 
			
		||||
							
								
								
									
										11
									
								
								node_modules/fast-redact/example/intermediate-wildcard-array.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								node_modules/fast-redact/example/intermediate-wildcard-array.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
const fastRedact = require('..')
 | 
			
		||||
const redact = fastRedact({ paths: ['a[*].c.d'] })
 | 
			
		||||
const obj = {
 | 
			
		||||
  a: [
 | 
			
		||||
    { c: { d: 'hide me', e: 'leave me be' } },
 | 
			
		||||
    { c: { d: 'and me', f: 'I want to live' } },
 | 
			
		||||
    { c: { d: 'and also I', g: 'I want to run in a stream' } }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
console.log(redact(obj))
 | 
			
		||||
							
								
								
									
										11
									
								
								node_modules/fast-redact/example/serialize-false.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								node_modules/fast-redact/example/serialize-false.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,11 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
const fastRedact = require('..')
 | 
			
		||||
const redact = fastRedact({
 | 
			
		||||
  paths: ['a'],
 | 
			
		||||
  serialize: false
 | 
			
		||||
})
 | 
			
		||||
const o = { a: 1, b: 2 }
 | 
			
		||||
console.log(redact(o) === o)
 | 
			
		||||
console.log(o)
 | 
			
		||||
console.log(redact.restore(o) === o)
 | 
			
		||||
console.log(o)
 | 
			
		||||
							
								
								
									
										4
									
								
								node_modules/fast-redact/example/serialize-function.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								node_modules/fast-redact/example/serialize-function.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,4 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
const fastRedact = require('..')
 | 
			
		||||
const redact = fastRedact({ paths: ['a'], serialize: (o) => JSON.stringify(o, 0, 2) })
 | 
			
		||||
console.log(redact({ a: 1, b: 2 }))
 | 
			
		||||
							
								
								
									
										9
									
								
								node_modules/fast-redact/example/top-wildcard-object.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								node_modules/fast-redact/example/top-wildcard-object.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
const fastRedact = require('..')
 | 
			
		||||
const redact = fastRedact({ paths: ['*.c.d'] })
 | 
			
		||||
const obj = {
 | 
			
		||||
  x: { c: { d: 'hide me', e: 'leave me be' } },
 | 
			
		||||
  y: { c: { d: 'and me', f: 'I want to live' } },
 | 
			
		||||
  z: { c: { d: 'and also I', g: 'I want to run in a stream' } }
 | 
			
		||||
}
 | 
			
		||||
console.log(redact(obj))
 | 
			
		||||
							
								
								
									
										55
									
								
								node_modules/fast-redact/index.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								node_modules/fast-redact/index.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,55 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const validator = require('./lib/validator')
 | 
			
		||||
const parse = require('./lib/parse')
 | 
			
		||||
const redactor = require('./lib/redactor')
 | 
			
		||||
const restorer = require('./lib/restorer')
 | 
			
		||||
const { groupRedact, nestedRedact } = require('./lib/modifiers')
 | 
			
		||||
const state = require('./lib/state')
 | 
			
		||||
const rx = require('./lib/rx')
 | 
			
		||||
const validate = validator()
 | 
			
		||||
const noop = (o) => o
 | 
			
		||||
noop.restore = noop
 | 
			
		||||
 | 
			
		||||
const DEFAULT_CENSOR = '[REDACTED]'
 | 
			
		||||
fastRedact.rx = rx
 | 
			
		||||
fastRedact.validator = validator
 | 
			
		||||
 | 
			
		||||
module.exports = fastRedact
 | 
			
		||||
 | 
			
		||||
function fastRedact (opts = {}) {
 | 
			
		||||
  const paths = Array.from(new Set(opts.paths || []))
 | 
			
		||||
  const serialize = 'serialize' in opts ? (
 | 
			
		||||
    opts.serialize === false ? opts.serialize
 | 
			
		||||
      : (typeof opts.serialize === 'function' ? opts.serialize : JSON.stringify)
 | 
			
		||||
  ) : JSON.stringify
 | 
			
		||||
  const remove = opts.remove
 | 
			
		||||
  if (remove === true && serialize !== JSON.stringify) {
 | 
			
		||||
    throw Error('fast-redact – remove option may only be set when serializer is JSON.stringify')
 | 
			
		||||
  }
 | 
			
		||||
  const censor = remove === true
 | 
			
		||||
    ? undefined
 | 
			
		||||
    : 'censor' in opts ? opts.censor : DEFAULT_CENSOR
 | 
			
		||||
 | 
			
		||||
  const isCensorFct = typeof censor === 'function'
 | 
			
		||||
 | 
			
		||||
  if (paths.length === 0) return serialize || noop
 | 
			
		||||
 | 
			
		||||
  validate({ paths, serialize, censor })
 | 
			
		||||
 | 
			
		||||
  const { wildcards, wcLen, secret } = parse({ paths, censor })
 | 
			
		||||
 | 
			
		||||
  const compileRestore = restorer({ secret, wcLen })
 | 
			
		||||
  const strict = 'strict' in opts ? opts.strict : true
 | 
			
		||||
 | 
			
		||||
  return redactor({ secret, wcLen, serialize, strict, isCensorFct }, state({
 | 
			
		||||
    secret,
 | 
			
		||||
    censor,
 | 
			
		||||
    compileRestore,
 | 
			
		||||
    serialize,
 | 
			
		||||
    groupRedact,
 | 
			
		||||
    nestedRedact,
 | 
			
		||||
    wildcards,
 | 
			
		||||
    wcLen
 | 
			
		||||
  }))
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										96
									
								
								node_modules/fast-redact/lib/modifiers.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								node_modules/fast-redact/lib/modifiers.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,96 @@
 | 
			
		|||
'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) {
 | 
			
		||||
  const target = get(o, path)
 | 
			
		||||
  if (target == null) return { keys: null, values: null, target: null, flat: true }
 | 
			
		||||
  const keys = Object.keys(target)
 | 
			
		||||
  const length = keys.length
 | 
			
		||||
  const values = new Array(length)
 | 
			
		||||
  for (var i = 0; i < length; i++) {
 | 
			
		||||
    const k = keys[i]
 | 
			
		||||
    values[i] = target[k]
 | 
			
		||||
    target[k] = isCensorFct ? censor(target[k]) : 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]
 | 
			
		||||
    target[key] = value
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function nestedRedact (store, o, path, ns, censor, isCensorFct) {
 | 
			
		||||
  const target = get(o, path)
 | 
			
		||||
  if (target == null) return
 | 
			
		||||
  const keys = Object.keys(target)
 | 
			
		||||
  const length = keys.length
 | 
			
		||||
  for (var i = 0; i < length; i++) {
 | 
			
		||||
    const key = keys[i]
 | 
			
		||||
    const { value, parent, exists } = specialSet(target, key, ns, censor, isCensorFct)
 | 
			
		||||
 | 
			
		||||
    if (exists === true && parent !== null) {
 | 
			
		||||
      store.push({ key: ns[ns.length - 1], target: parent, value })
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return store
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function has (obj, prop) {
 | 
			
		||||
  return Object.prototype.hasOwnProperty.call(obj, prop)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function specialSet (o, k, p, v, f) {
 | 
			
		||||
  var i = -1
 | 
			
		||||
  var l = p.length
 | 
			
		||||
  var li = l - 1
 | 
			
		||||
  var n
 | 
			
		||||
  var nv
 | 
			
		||||
  var ov
 | 
			
		||||
  var oov = null
 | 
			
		||||
  var exists = true
 | 
			
		||||
  ov = n = o[k]
 | 
			
		||||
  if (typeof n !== 'object') return { value: null, parent: null, exists }
 | 
			
		||||
  while (n != null && ++i < l) {
 | 
			
		||||
    k = p[i]
 | 
			
		||||
    oov = ov
 | 
			
		||||
    if (!(k in n)) {
 | 
			
		||||
      exists = false
 | 
			
		||||
      break
 | 
			
		||||
    }
 | 
			
		||||
    ov = n[k]
 | 
			
		||||
    nv = f ? v(ov) : v
 | 
			
		||||
    nv = (i !== li) ? ov : nv
 | 
			
		||||
    n[k] = (has(n, k) && nv === ov) || (nv === undefined && v !== undefined) ? n[k] : nv
 | 
			
		||||
    n = n[k]
 | 
			
		||||
    if (typeof n !== 'object') break
 | 
			
		||||
  }
 | 
			
		||||
  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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										45
									
								
								node_modules/fast-redact/lib/parse.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								node_modules/fast-redact/lib/parse.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,45 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const rx = require('./rx')
 | 
			
		||||
 | 
			
		||||
module.exports = parse
 | 
			
		||||
 | 
			
		||||
function parse ({ paths }) {
 | 
			
		||||
  const wildcards = []
 | 
			
		||||
  var wcLen = 0
 | 
			
		||||
  const secret = paths.reduce(function (o, strPath, ix) {
 | 
			
		||||
    var path = strPath.match(rx).map((p) => p.replace(/'|"|`/g, ''))
 | 
			
		||||
    const leadingBracket = strPath[0] === '['
 | 
			
		||||
    path = path.map((p) => {
 | 
			
		||||
      if (p[0] === '[') return p.substr(1, p.length - 2)
 | 
			
		||||
      else return p
 | 
			
		||||
    })
 | 
			
		||||
    const star = path.indexOf('*')
 | 
			
		||||
    if (star > -1) {
 | 
			
		||||
      const before = path.slice(0, star)
 | 
			
		||||
      const beforeStr = before.join('.')
 | 
			
		||||
      const after = path.slice(star + 1, path.length)
 | 
			
		||||
      if (after.indexOf('*') > -1) throw Error('fast-redact – Only one wildcard per path is supported')
 | 
			
		||||
      const nested = after.length > 0
 | 
			
		||||
      wcLen++
 | 
			
		||||
      wildcards.push({
 | 
			
		||||
        before,
 | 
			
		||||
        beforeStr,
 | 
			
		||||
        after,
 | 
			
		||||
        nested
 | 
			
		||||
      })
 | 
			
		||||
    } else {
 | 
			
		||||
      o[strPath] = {
 | 
			
		||||
        path: path,
 | 
			
		||||
        val: undefined,
 | 
			
		||||
        precensored: false,
 | 
			
		||||
        circle: '',
 | 
			
		||||
        escPath: JSON.stringify(strPath),
 | 
			
		||||
        leadingBracket: leadingBracket
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return o
 | 
			
		||||
  }, {})
 | 
			
		||||
 | 
			
		||||
  return { wildcards, wcLen, secret }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										94
									
								
								node_modules/fast-redact/lib/redactor.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								node_modules/fast-redact/lib/redactor.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,94 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const rx = require('./rx')
 | 
			
		||||
 | 
			
		||||
module.exports = redactor
 | 
			
		||||
 | 
			
		||||
function redactor ({ secret, serialize, wcLen, strict, isCensorFct }, state) {
 | 
			
		||||
  /* eslint-disable-next-line */
 | 
			
		||||
  const redact = Function('o', `
 | 
			
		||||
    if (typeof o !== 'object' || o == null) {
 | 
			
		||||
      ${strictImpl(strict, serialize)}
 | 
			
		||||
    }
 | 
			
		||||
    const { censor, secret } = this
 | 
			
		||||
    ${redactTmpl(secret, isCensorFct)}
 | 
			
		||||
    this.compileRestore()
 | 
			
		||||
    ${dynamicRedactTmpl(wcLen > 0, isCensorFct)}
 | 
			
		||||
    ${resultTmpl(serialize)}
 | 
			
		||||
  `).bind(state)
 | 
			
		||||
 | 
			
		||||
  if (serialize === false) {
 | 
			
		||||
    redact.restore = (o) => state.restore(o)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return redact
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function redactTmpl (secret, isCensorFct) {
 | 
			
		||||
  return Object.keys(secret).map((path) => {
 | 
			
		||||
    const { escPath, leadingBracket } = secret[path]
 | 
			
		||||
    const skip = leadingBracket ? 1 : 0
 | 
			
		||||
    const delim = leadingBracket ? '' : '.'
 | 
			
		||||
    const hops = []
 | 
			
		||||
    var match
 | 
			
		||||
    while ((match = rx.exec(path)) !== null) {
 | 
			
		||||
      const [ , ix ] = match
 | 
			
		||||
      const { index, input } = match
 | 
			
		||||
      if (index > skip) hops.push(input.substring(0, index - (ix ? 0 : 1)))
 | 
			
		||||
    }
 | 
			
		||||
    var existence = hops.map((p) => `o${delim}${p}`).join(' && ')
 | 
			
		||||
    if (existence.length === 0) existence += `o${delim}${path} != null`
 | 
			
		||||
    else existence += ` && o${delim}${path} != null`
 | 
			
		||||
 | 
			
		||||
    const circularDetection = `
 | 
			
		||||
      switch (true) {
 | 
			
		||||
        ${hops.reverse().map((p) => `
 | 
			
		||||
          case o${delim}${p} === censor:
 | 
			
		||||
            secret[${escPath}].circle = ${JSON.stringify(p)}
 | 
			
		||||
            break
 | 
			
		||||
        `).join('\n')}
 | 
			
		||||
      }
 | 
			
		||||
    `
 | 
			
		||||
    return `
 | 
			
		||||
      if (${existence}) {
 | 
			
		||||
        const val = o${delim}${path}
 | 
			
		||||
        if (val === censor) {
 | 
			
		||||
          secret[${escPath}].precensored = true
 | 
			
		||||
        } else {
 | 
			
		||||
          secret[${escPath}].val = val
 | 
			
		||||
          o${delim}${path} = ${isCensorFct ? 'censor(val)' : 'censor'}
 | 
			
		||||
          ${circularDetection}
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    `
 | 
			
		||||
  }).join('\n')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function dynamicRedactTmpl (hasWildcards, isCensorFct) {
 | 
			
		||||
  return hasWildcards === true ? `
 | 
			
		||||
    {
 | 
			
		||||
      const { wildcards, wcLen, groupRedact, nestedRedact } = this
 | 
			
		||||
      for (var i = 0; i < wcLen; i++) {
 | 
			
		||||
        const { before, beforeStr, after, nested } = wildcards[i]
 | 
			
		||||
        if (nested === true) {
 | 
			
		||||
          secret[beforeStr] = secret[beforeStr] || []
 | 
			
		||||
          nestedRedact(secret[beforeStr], o, before, after, censor, ${isCensorFct})
 | 
			
		||||
        } else secret[beforeStr] = groupRedact(o, before, censor, ${isCensorFct})
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  ` : ''
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function resultTmpl (serialize) {
 | 
			
		||||
  return serialize === false ? `return o` : `
 | 
			
		||||
    var s = this.serialize(o)
 | 
			
		||||
    this.restore(o)
 | 
			
		||||
    return s
 | 
			
		||||
  `
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function strictImpl (strict, serialize) {
 | 
			
		||||
  return strict === true
 | 
			
		||||
    ? `throw Error('fast-redact: primitives cannot be redacted')`
 | 
			
		||||
    : serialize === false ? `return o` : `return this.serialize(o)`
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										71
									
								
								node_modules/fast-redact/lib/restorer.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								node_modules/fast-redact/lib/restorer.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,71 @@
 | 
			
		|||
'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
 | 
			
		||||
  `
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										3
									
								
								node_modules/fast-redact/lib/rx.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								node_modules/fast-redact/lib/rx.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
module.exports = /[^.[\]]+|\[((?:.)*?)\]/g
 | 
			
		||||
							
								
								
									
										22
									
								
								node_modules/fast-redact/lib/state.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								node_modules/fast-redact/lib/state.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
module.exports = state
 | 
			
		||||
 | 
			
		||||
function state (o) {
 | 
			
		||||
  const {
 | 
			
		||||
    secret,
 | 
			
		||||
    censor,
 | 
			
		||||
    isCensorFct,
 | 
			
		||||
    compileRestore,
 | 
			
		||||
    serialize,
 | 
			
		||||
    groupRedact,
 | 
			
		||||
    nestedRedact,
 | 
			
		||||
    wildcards,
 | 
			
		||||
    wcLen
 | 
			
		||||
  } = o
 | 
			
		||||
  const builder = [{ secret, censor, isCensorFct, compileRestore }]
 | 
			
		||||
  builder.push({ secret })
 | 
			
		||||
  if (serialize !== false) builder.push({ serialize })
 | 
			
		||||
  if (wcLen > 0) builder.push({ groupRedact, nestedRedact, wildcards, wcLen })
 | 
			
		||||
  return Object.assign(...builder)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										38
									
								
								node_modules/fast-redact/lib/validator.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								node_modules/fast-redact/lib/validator.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,38 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const { createContext, runInContext } = require('vm')
 | 
			
		||||
 | 
			
		||||
module.exports = validator
 | 
			
		||||
 | 
			
		||||
function validator (opts = {}) {
 | 
			
		||||
  const {
 | 
			
		||||
    ERR_PATHS_MUST_BE_STRINGS = () => 'fast-redact - Paths must be strings',
 | 
			
		||||
    ERR_INVALID_PATH = (s) => `fast-redact – Invalid path (${s})`
 | 
			
		||||
  } = opts
 | 
			
		||||
 | 
			
		||||
  return function validate ({ paths }) {
 | 
			
		||||
    paths.forEach((s) => {
 | 
			
		||||
      if (typeof s !== 'string') {
 | 
			
		||||
        throw Error(ERR_PATHS_MUST_BE_STRINGS())
 | 
			
		||||
      }
 | 
			
		||||
      try {
 | 
			
		||||
        if (/〇/.test(s)) throw Error()
 | 
			
		||||
        const proxy = new Proxy({}, { get: () => proxy, set: () => { throw Error() } })
 | 
			
		||||
        const expr = (s[0] === '[' ? '' : '.') + s.replace(/^\*/, '〇').replace(/\.\*/g, '.〇').replace(/\[\*\]/g, '[〇]')
 | 
			
		||||
        if (/\n|\r|;/.test(expr)) throw Error()
 | 
			
		||||
        if (/\/\*/.test(expr)) throw Error()
 | 
			
		||||
        runInContext(`
 | 
			
		||||
          (function () {
 | 
			
		||||
            'use strict'
 | 
			
		||||
            o${expr}
 | 
			
		||||
            if ([o${expr}].length !== 1) throw Error()
 | 
			
		||||
          })()
 | 
			
		||||
        `, createContext({ o: proxy, 〇: null }), {
 | 
			
		||||
          codeGeneration: { strings: false, wasm: false }
 | 
			
		||||
        })
 | 
			
		||||
      } catch (e) {
 | 
			
		||||
        throw Error(ERR_INVALID_PATH(s))
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										78
									
								
								node_modules/fast-redact/package.json
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								node_modules/fast-redact/package.json
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,78 @@
 | 
			
		|||
{
 | 
			
		||||
  "_from": "fast-redact@^2.0.0",
 | 
			
		||||
  "_id": "fast-redact@2.0.0",
 | 
			
		||||
  "_inBundle": false,
 | 
			
		||||
  "_integrity": "sha512-zxpkULI9W9MNTK2sJ3BpPQrTEXFNESd2X6O1tXMFpK/XM0G5c5Rll2EVYZH2TqI3xRGK/VaJ+eEOt7pnENJpeA==",
 | 
			
		||||
  "_location": "/fast-redact",
 | 
			
		||||
  "_phantomChildren": {},
 | 
			
		||||
  "_requested": {
 | 
			
		||||
    "type": "range",
 | 
			
		||||
    "registry": true,
 | 
			
		||||
    "raw": "fast-redact@^2.0.0",
 | 
			
		||||
    "name": "fast-redact",
 | 
			
		||||
    "escapedName": "fast-redact",
 | 
			
		||||
    "rawSpec": "^2.0.0",
 | 
			
		||||
    "saveSpec": null,
 | 
			
		||||
    "fetchSpec": "^2.0.0"
 | 
			
		||||
  },
 | 
			
		||||
  "_requiredBy": [
 | 
			
		||||
    "/pino"
 | 
			
		||||
  ],
 | 
			
		||||
  "_resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-2.0.0.tgz",
 | 
			
		||||
  "_shasum": "17bb8f5e1f56ecf4a38c8455985e5eab4c478431",
 | 
			
		||||
  "_spec": "fast-redact@^2.0.0",
 | 
			
		||||
  "_where": "/home/dawidd6/github/dawidd6/action-debian-package/node_modules/pino",
 | 
			
		||||
  "author": {
 | 
			
		||||
    "name": "David Mark Clements",
 | 
			
		||||
    "email": "david.clements@nearform.com"
 | 
			
		||||
  },
 | 
			
		||||
  "bugs": {
 | 
			
		||||
    "url": "https://github.com/davidmarkclements/fast-redact/issues"
 | 
			
		||||
  },
 | 
			
		||||
  "bundleDependencies": false,
 | 
			
		||||
  "deprecated": false,
 | 
			
		||||
  "description": "very fast object redaction",
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "fastbench": "^1.0.1",
 | 
			
		||||
    "pino-noir": "^2.2.1",
 | 
			
		||||
    "snazzy": "^8.0.0",
 | 
			
		||||
    "standard": "^12.0.1",
 | 
			
		||||
    "tap": "^12.5.2"
 | 
			
		||||
  },
 | 
			
		||||
  "directories": {
 | 
			
		||||
    "example": "example",
 | 
			
		||||
    "lib": "lib",
 | 
			
		||||
    "test": "test"
 | 
			
		||||
  },
 | 
			
		||||
  "engines": {
 | 
			
		||||
    "node": ">=6"
 | 
			
		||||
  },
 | 
			
		||||
  "homepage": "https://github.com/davidmarkclements/fast-redact#readme",
 | 
			
		||||
  "keywords": [
 | 
			
		||||
    "redact",
 | 
			
		||||
    "censor",
 | 
			
		||||
    "performance",
 | 
			
		||||
    "performant",
 | 
			
		||||
    "gdpr",
 | 
			
		||||
    "fast",
 | 
			
		||||
    "speed",
 | 
			
		||||
    "serialize",
 | 
			
		||||
    "stringify"
 | 
			
		||||
  ],
 | 
			
		||||
  "license": "MIT",
 | 
			
		||||
  "main": "index.js",
 | 
			
		||||
  "name": "fast-redact",
 | 
			
		||||
  "repository": {
 | 
			
		||||
    "type": "git",
 | 
			
		||||
    "url": "git+https://github.com/davidmarkclements/fast-redact.git"
 | 
			
		||||
  },
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "bench": "node benchmark",
 | 
			
		||||
    "ci": "tap --cov --100 test",
 | 
			
		||||
    "cov": "tap --cov test",
 | 
			
		||||
    "cov-ui": "tap --coverage-report=html test",
 | 
			
		||||
    "posttest": "standard index.js 'lib/*.js' 'example/*.js' benchmark/index.js test/index.js | snazzy",
 | 
			
		||||
    "test": "tap test"
 | 
			
		||||
  },
 | 
			
		||||
  "version": "2.0.0"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										280
									
								
								node_modules/fast-redact/readme.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										280
									
								
								node_modules/fast-redact/readme.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,280 @@
 | 
			
		|||
# fast-redact
 | 
			
		||||
 | 
			
		||||
very fast object redaction
 | 
			
		||||
 | 
			
		||||
[](https://travis-ci.org/davidmarkclements/fast-redact)
 | 
			
		||||
 | 
			
		||||
## Default Usage
 | 
			
		||||
 | 
			
		||||
By default, `fast-redact` serializes an object with `JSON.stringify`, censoring any 
 | 
			
		||||
data at paths specified:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const fastRedact = require('fast-redact')
 | 
			
		||||
const fauxRequest = {
 | 
			
		||||
  headers: {
 | 
			
		||||
    host: 'http://example.com',
 | 
			
		||||
    cookie: `oh oh we don't want this exposed in logs in etc.`,
 | 
			
		||||
    referer: `if we're cool maybe we'll even redact this`
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
const redact = fastRedact({
 | 
			
		||||
  paths: ['headers.cookie', 'headers.referer']
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
console.log(redact(fauxRequest))
 | 
			
		||||
// {"headers":{"host":"http://example.com","cookie":"[REDACTED]","referer":"[REDACTED]"}}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## API
 | 
			
		||||
 | 
			
		||||
### `require('fast-redact')({paths, censor, serialize}) => Function`
 | 
			
		||||
 | 
			
		||||
When called without any options, or with a zero length `paths` array, 
 | 
			
		||||
`fast-redact` will return  `JSON.stringify` or the `serialize` option, if set.
 | 
			
		||||
 | 
			
		||||
#### `paths` – `Array`
 | 
			
		||||
 | 
			
		||||
An array of strings describing the nested location of a key in an object.
 | 
			
		||||
 | 
			
		||||
The syntax follows that of the EcmaScript specification, that is any JavaScript
 | 
			
		||||
path is accepted – both bracket and dot notation is supported. For instance in 
 | 
			
		||||
each of the following cases, the `c` property will be redacted: `a.b.c`,`a['b'].c`, 
 | 
			
		||||
`a["b"].c`, `a[``b``].c`. Since bracket notation is supported, array indices are also
 | 
			
		||||
supported `a[0].b` would redact the `b` key in the first object of the `a` array. 
 | 
			
		||||
 | 
			
		||||
Leading brackets are also allowed, for instance `["a"].b.c` will work.
 | 
			
		||||
 | 
			
		||||
##### Wildcards
 | 
			
		||||
 | 
			
		||||
In addition to static paths, asterisk wildcards are also supported.
 | 
			
		||||
 | 
			
		||||
When an asterisk is place in the final position it will redact all keys within the
 | 
			
		||||
parent object. For instance `a.b.*` will redact all keys in the `b` object. Similarly
 | 
			
		||||
for arrays `a.b[*]` will redact all elements of an array (in truth it actually doesn't matter 
 | 
			
		||||
whether `b` is in an object or array in either case, both notation styles will work).
 | 
			
		||||
 | 
			
		||||
When an asterisk is in an intermediate or first position, the paths following the asterisk will 
 | 
			
		||||
be redacted for every object within the parent.
 | 
			
		||||
 | 
			
		||||
For example:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const fastRedact = require('fast-redact')
 | 
			
		||||
const redact = fastRedact({paths: ['*.c.d']})
 | 
			
		||||
const obj = {
 | 
			
		||||
  x: {c: {d: 'hide me', e: 'leave me be'}},
 | 
			
		||||
  y: {c: {d: 'and me', f: 'I want to live'}},
 | 
			
		||||
  z: {c: {d: 'and also I', g: 'I want to run in a stream'}}
 | 
			
		||||
}
 | 
			
		||||
console.log(redact(obj)) 
 | 
			
		||||
// {"x":{"c":{"d":"[REDACTED]","e":"leave me be"}},"y":{"c":{"d":"[REDACTED]","f":"I want to live"}},"z":{"c":{"d":"[REDACTED]","g":"I want to run in a stream"}}}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Another example with a nested array:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const fastRedact = require('..')
 | 
			
		||||
const redact = fastRedact({paths: ['a[*].c.d']})
 | 
			
		||||
const obj = {
 | 
			
		||||
  a: [
 | 
			
		||||
    {c: {d: 'hide me', e: 'leave me be'}},
 | 
			
		||||
    {c: {d: 'and me', f: 'I want to live'}},
 | 
			
		||||
    {c: {d: 'and also I', g: 'I want to run in a stream'}}
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
console.log(redact(obj)) 
 | 
			
		||||
// {"a":[{"c":{"d":"[REDACTED]","e":"leave me be"}},{"c":{"d":"[REDACTED]","f":"I want to live"}},{"c":{"d":"[REDACTED]","g":"I want to run in a stream"}}]}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### `remove` - `Boolean` - `[false]`
 | 
			
		||||
 | 
			
		||||
The `remove` option, when set to `true` will cause keys to be removed from the 
 | 
			
		||||
serialized output. 
 | 
			
		||||
 | 
			
		||||
Since the implementation exploits the fact that `undefined` keys are ignored
 | 
			
		||||
by `JSON.stringify` the `remove` option may *only* be used when `JSON.stringify`
 | 
			
		||||
is the serializer (this is the default) – otherwise `fast-redact` will throw. 
 | 
			
		||||
 | 
			
		||||
If supplying a custom serializer that has the same behavior (removing keys 
 | 
			
		||||
with `undefined` values), this restriction can be bypassed by explicitly setting 
 | 
			
		||||
the `censor` to `undefined`.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#### `censor` – `<Any type>` – `('[REDACTED]')`
 | 
			
		||||
 | 
			
		||||
This is the value which overwrites redacted properties. 
 | 
			
		||||
 | 
			
		||||
Setting `censor` to `undefined` will cause properties to removed as long as this is 
 | 
			
		||||
the behavior of the `serializer` – which defaults to `JSON.stringify`, which does 
 | 
			
		||||
remove `undefined` properties.
 | 
			
		||||
 | 
			
		||||
Setting `censor` to a function will cause `fast-redact` to invoke it with the original 
 | 
			
		||||
value. The output of the `censor` function sets the redacted value.
 | 
			
		||||
Please note that asynchronous functions are not supported. 
 | 
			
		||||
 | 
			
		||||
#### `serialize` – `Function | Boolean` – `(JSON.stringify)`
 | 
			
		||||
 | 
			
		||||
The `serialize` option may be a function of a boolean. If a function is supplied, this
 | 
			
		||||
will be used to `serialize` the redacted object. It's important to understand that for 
 | 
			
		||||
performance reasons `fast-redact` *mutates* the original object, then serializes, then 
 | 
			
		||||
restores the original values. So the object passed to the serializer is the exact same
 | 
			
		||||
object passed to the redacting function. 
 | 
			
		||||
 | 
			
		||||
The `serialize` option as a function example:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const fastRedact = require('fast-redact')
 | 
			
		||||
const redact = fastRedact({
 | 
			
		||||
  paths: ['a'], 
 | 
			
		||||
  serialize: (o) => JSON.stringify(o, 0, 2)
 | 
			
		||||
})
 | 
			
		||||
console.log(redact({a: 1, b: 2}))
 | 
			
		||||
// {
 | 
			
		||||
//   "a": "[REDACTED]",
 | 
			
		||||
//   "b": 2
 | 
			
		||||
// }
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
For advanced usage the `serialize` option can be set to `false`. When `serialize` is set to `false`,
 | 
			
		||||
instead of the serialized object, the output of the redactor function will be the mutated object 
 | 
			
		||||
itself (this is the exact same as the object passed in). In addition a `restore` method is supplied
 | 
			
		||||
on the redactor function allowing the redacted keys to be restored with the original data. 
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const fastRedact = require('fast-redact')
 | 
			
		||||
const redact = fastRedact({
 | 
			
		||||
  paths: ['a'], 
 | 
			
		||||
  serialize: false
 | 
			
		||||
})
 | 
			
		||||
const o = {a: 1, b: 2}
 | 
			
		||||
console.log(redact(o) === o) // true
 | 
			
		||||
console.log(o) // { a: '[REDACTED]', b: 2 }
 | 
			
		||||
console.log(redact.restore(o) === o) // true
 | 
			
		||||
console.log(o) // { a: 1, b: 2 }
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### `strict` – `Boolean` - `[true]`
 | 
			
		||||
The `strict` option, when set to `true`, will cause the redactor function to throw if instead 
 | 
			
		||||
of an object it finds a primitive. When `strict` is set to `false`, the redactor function 
 | 
			
		||||
will treat the primitive value as having already been redacted, and return it serialized (with
 | 
			
		||||
`JSON.stringify` or the user's custom `serialize` function), or as-is if the `serialize` option
 | 
			
		||||
was set to false.
 | 
			
		||||
 | 
			
		||||
## Approach
 | 
			
		||||
 | 
			
		||||
In order to achieve lowest cost/highest performance redaction `fast-redact`
 | 
			
		||||
creates and compiles a function (using the `Function` constructor) on initialization.
 | 
			
		||||
It's important to distinguish this from the dangers of a runtime eval, no user input 
 | 
			
		||||
is involved in creating the string that compiles into the function. This is as safe 
 | 
			
		||||
as writing code normally and having it compiled by V8 in the usual way.
 | 
			
		||||
 | 
			
		||||
Thanks to changes in V8 in recent years, state can be injected into compiled functions
 | 
			
		||||
using `bind` at very low cost (whereas `bind` used to be expensive, and getting state
 | 
			
		||||
into a compiled function by any means was difficult without a performance penalty).
 | 
			
		||||
 | 
			
		||||
For static paths, this function simply checks that the path exists and then overwrites
 | 
			
		||||
with the censor. Wildcard paths are processed with normal functions that iterate over 
 | 
			
		||||
the object redacting values as necessary.
 | 
			
		||||
 | 
			
		||||
It's important to note, that the original object is mutated – for performance reasons
 | 
			
		||||
a copy is not made. See [rfdc](https://github.com/davidmarkclements/rfdc) (Really Fast 
 | 
			
		||||
Deep Clone) for the fastest known way to clone – it's not nearly close enough  in speed
 | 
			
		||||
to editing the original object, serializing and then restoring values. 
 | 
			
		||||
 | 
			
		||||
A `restore` function is also created and compiled to put the original state back on
 | 
			
		||||
to the object after redaction. This means that in the default usage case, the operation 
 | 
			
		||||
is essentially atomic - the object is mutated, serialized and restored internally which 
 | 
			
		||||
avoids any state management issues.
 | 
			
		||||
 | 
			
		||||
## Caveat
 | 
			
		||||
 | 
			
		||||
As mentioned in approach, the `paths` array input is dynamically compiled into a function
 | 
			
		||||
at initialization time. While the `paths` array is vigourously tested for any developer 
 | 
			
		||||
errors, it's strongly recommended against allowing user input to directly supply any 
 | 
			
		||||
paths to redact. It can't be guaranteed that allowing user input for `paths` couldn't
 | 
			
		||||
feasibly expose an attack vector.  
 | 
			
		||||
 | 
			
		||||
## Benchmarks
 | 
			
		||||
 | 
			
		||||
The fastest known predecessor to `fast-redact` is the non-generic [`pino-noir`](http://npm.im/pino-noir) 
 | 
			
		||||
library (which was also written by myself).
 | 
			
		||||
 | 
			
		||||
In the direct calling case, `fast-redact` is ~30x faster than `pino-noir`, however a more realistic
 | 
			
		||||
comparison is overhead on `JSON.stringify`. 
 | 
			
		||||
 | 
			
		||||
For a static redaction case (no wildcards) `pino-noir` adds ~25% overhead on top of `JSON.stringify`
 | 
			
		||||
whereas `fast-redact` adds ~1% overhead.
 | 
			
		||||
 | 
			
		||||
In the basic last-position wildcard case,`fast-redact` is ~12% faster than `pino-noir`.
 | 
			
		||||
 | 
			
		||||
The `pino-noir` module does not support intermediate wildcards, but `fast-redact` does,
 | 
			
		||||
the cost of an intermediate wildcard that results in two keys over two nested objects 
 | 
			
		||||
being redacted is about 25% overhead on `JSON.stringify`. The cost of an intermediate 
 | 
			
		||||
wildcard that results in four keys across two objects being redacted is about 55% overhead 
 | 
			
		||||
on `JSON.stringify` and ~50% more expensive that explicitly declaring the keys.  
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
npm run bench 
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
benchNoirV2*500: 59.108ms
 | 
			
		||||
benchFastRedact*500: 2.483ms
 | 
			
		||||
benchFastRedactRestore*500: 10.904ms
 | 
			
		||||
benchNoirV2Wild*500: 91.399ms
 | 
			
		||||
benchFastRedactWild*500: 21.200ms
 | 
			
		||||
benchFastRedactWildRestore*500: 27.304ms
 | 
			
		||||
benchFastRedactIntermediateWild*500: 92.304ms
 | 
			
		||||
benchFastRedactIntermediateWildRestore*500: 107.047ms
 | 
			
		||||
benchJSONStringify*500: 210.573ms
 | 
			
		||||
benchNoirV2Serialize*500: 281.148ms
 | 
			
		||||
benchFastRedactSerialize*500: 215.845ms
 | 
			
		||||
benchNoirV2WildSerialize*500: 281.168ms
 | 
			
		||||
benchFastRedactWildSerialize*500: 247.140ms
 | 
			
		||||
benchFastRedactIntermediateWildSerialize*500: 333.722ms
 | 
			
		||||
benchFastRedactIntermediateWildMatchWildOutcomeSerialize*500: 463.667ms
 | 
			
		||||
benchFastRedactStaticMatchWildOutcomeSerialize*500: 239.293ms
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Tests
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
npm test  
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
  224 passing (499.544ms)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Coverage
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
npm run cov 
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
-----------------|----------|----------|----------|----------|-------------------|
 | 
			
		||||
File             |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
 | 
			
		||||
-----------------|----------|----------|----------|----------|-------------------|
 | 
			
		||||
All files        |      100 |      100 |      100 |      100 |                   |
 | 
			
		||||
 fast-redact     |      100 |      100 |      100 |      100 |                   |
 | 
			
		||||
  index.js       |      100 |      100 |      100 |      100 |                   |
 | 
			
		||||
 fast-redact/lib |      100 |      100 |      100 |      100 |                   |
 | 
			
		||||
  modifiers.js   |      100 |      100 |      100 |      100 |                   |
 | 
			
		||||
  parse.js       |      100 |      100 |      100 |      100 |                   |
 | 
			
		||||
  redactor.js    |      100 |      100 |      100 |      100 |                   |
 | 
			
		||||
  restorer.js    |      100 |      100 |      100 |      100 |                   |
 | 
			
		||||
  rx.js          |      100 |      100 |      100 |      100 |                   |
 | 
			
		||||
  state.js       |      100 |      100 |      100 |      100 |                   |
 | 
			
		||||
  validator.js   |      100 |      100 |      100 |      100 |                   |
 | 
			
		||||
-----------------|----------|----------|----------|----------|-------------------|
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## License
 | 
			
		||||
 | 
			
		||||
MIT
 | 
			
		||||
 | 
			
		||||
## Acknowledgements
 | 
			
		||||
 | 
			
		||||
Sponsored by [nearForm](http://www.nearform.com)
 | 
			
		||||
							
								
								
									
										964
									
								
								node_modules/fast-redact/test/index.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										964
									
								
								node_modules/fast-redact/test/index.js
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,964 @@
 | 
			
		|||
'use strict'
 | 
			
		||||
 | 
			
		||||
const { test } = require('tap')
 | 
			
		||||
const fastRedact = require('..')
 | 
			
		||||
 | 
			
		||||
const censor = '[REDACTED]'
 | 
			
		||||
const censorFct = value => !value ? value : 'xxx' + value.substr(-2)
 | 
			
		||||
 | 
			
		||||
test('returns no-op when passed no paths [serialize: false]', ({ end, doesNotThrow }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: [], serialize: false })
 | 
			
		||||
  doesNotThrow(() => redact({}))
 | 
			
		||||
  doesNotThrow(() => {
 | 
			
		||||
    const o = redact({})
 | 
			
		||||
    redact.restore(o)
 | 
			
		||||
  })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('returns serializer when passed no paths [serialize: default]', ({ end, is }) => {
 | 
			
		||||
  is(fastRedact({ paths: [] }), JSON.stringify)
 | 
			
		||||
  is(fastRedact(), JSON.stringify)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('throws when passed non-object using defaults', ({ end, throws }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a.b.c'] })
 | 
			
		||||
  throws(() => redact(1))
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('throws when passed non-object number using [strict: true]', ({ end, throws }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a.b.c'], strict: true })
 | 
			
		||||
  throws(() => redact(1))
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('returns JSON.stringified value when passed non-object using [strict: false] and no serialize option', ({ end, is, doesNotThrow }) => {
 | 
			
		||||
  const redactDefaultSerialize = fastRedact({ paths: ['a.b.c'], strict: false })
 | 
			
		||||
 | 
			
		||||
  // expectedOutputs holds `JSON.stringify`ied versions of each primitive.
 | 
			
		||||
  // We write them out explicitly though to make the test a bit clearer.
 | 
			
		||||
  const primitives = [null, undefined, 'A', 1, false]
 | 
			
		||||
  const expectedOutputs = ['null', undefined, '"A"', '1', 'false']
 | 
			
		||||
 | 
			
		||||
  primitives.forEach((it, i) => {
 | 
			
		||||
    doesNotThrow(() => redactDefaultSerialize(it))
 | 
			
		||||
    const res = redactDefaultSerialize(it)
 | 
			
		||||
    is(res, expectedOutputs[i])
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('returns custom serialized value when passed non-object using [strict: false, serialize: fn]', ({ end, is, doesNotThrow }) => {
 | 
			
		||||
  const customSerialize = (v) => `Hello ${v}!`
 | 
			
		||||
  const redactCustomSerialize = fastRedact({
 | 
			
		||||
    paths: ['a.b.c'],
 | 
			
		||||
    strict: false,
 | 
			
		||||
    serialize: customSerialize
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  const primitives = [null, undefined, 'A', 1, false]
 | 
			
		||||
 | 
			
		||||
  primitives.forEach((it) => {
 | 
			
		||||
    doesNotThrow(() => redactCustomSerialize(it))
 | 
			
		||||
    const res = redactCustomSerialize(it)
 | 
			
		||||
    is(res, customSerialize(it))
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('returns original value when passed non-object using [strict: false, serialize: false]', ({ end, is, doesNotThrow }) => {
 | 
			
		||||
  const redactSerializeFalse = fastRedact({
 | 
			
		||||
    paths: ['a.b.c'],
 | 
			
		||||
    strict: false,
 | 
			
		||||
    serialize: false
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  const primitives = [null, undefined, 'A', 1, false]
 | 
			
		||||
 | 
			
		||||
  primitives.forEach((it) => {
 | 
			
		||||
    doesNotThrow(() => redactSerializeFalse(it))
 | 
			
		||||
    const res = redactSerializeFalse(it)
 | 
			
		||||
    is(res, it)
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('throws if a path is not a string', ({ end, is, throws }) => {
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: [1] })
 | 
			
		||||
  }, Error('fast-redact - Paths must be strings'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: [null] })
 | 
			
		||||
  }, Error('fast-redact - Paths must be strings'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: [undefined] })
 | 
			
		||||
  }, Error('fast-redact - Paths must be strings'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: [{}] })
 | 
			
		||||
  }, Error('fast-redact - Paths must be strings'))
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('throws when passed illegal paths', ({ end, is, throws }) => {
 | 
			
		||||
  const err = (s) => Error(`fast-redact – Invalid path (${s})`)
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['@'] })
 | 
			
		||||
  }, err('@'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['0'] })
 | 
			
		||||
  }, err('0'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['〇'] })
 | 
			
		||||
  }, err('〇'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['a.1.c'] })
 | 
			
		||||
  }, err('a.1.c'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['a..c'] })
 | 
			
		||||
  }, err('a..c'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['1..c'] })
 | 
			
		||||
  }, err('1..c'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['a = b'] })
 | 
			
		||||
  }, err('a = b'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['a(b)'] })
 | 
			
		||||
  }, err('a(b)'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['//a.b.c'] })
 | 
			
		||||
  }, err('//a.b.c'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['\\a.b.c'] })
 | 
			
		||||
  }, err('\\a.b.c'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['a.#.c'] })
 | 
			
		||||
  }, err('a.#.c'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['~~a.b.c'] })
 | 
			
		||||
  }, err('~~a.b.c'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['^a.b.c'] })
 | 
			
		||||
  }, err('^a.b.c'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['a + b'] })
 | 
			
		||||
  }, err('a + b'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['return a + b'] })
 | 
			
		||||
  }, err('return a + b'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['a / b'] })
 | 
			
		||||
  }, err('a / b'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['a * b'] })
 | 
			
		||||
  }, err('a * b'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['a - b'] })
 | 
			
		||||
  }, err('a - b'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['a ** b'] })
 | 
			
		||||
  }, err('a ** b'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['a % b'] })
 | 
			
		||||
  }, err('a % b'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['a.b*.c'] })
 | 
			
		||||
  }, err('a.b*.c'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['a;global.foo = "bar"'] })
 | 
			
		||||
  }, err('a;global.foo = "bar"'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['a;while(1){}'] })
 | 
			
		||||
  }, err('a;while(1){}'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['a//'] })
 | 
			
		||||
  }, err('a//'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['a/*foo*/'] })
 | 
			
		||||
  }, err('a/*foo*/'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['a,o.b'] })
 | 
			
		||||
  }, err('a,o.b'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['a = o.b'] })
 | 
			
		||||
  }, err('a = o.b'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['a\n'] })
 | 
			
		||||
  }, err('a\n'))
 | 
			
		||||
  throws((e) => {
 | 
			
		||||
    fastRedact({ paths: ['a\r'] })
 | 
			
		||||
  }, err('a\r'))
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('throws if more than one wildcard in a path', ({ end, throws }) => {
 | 
			
		||||
  throws(() => {
 | 
			
		||||
    fastRedact({ paths: ['a.*.x.*'], serialize: false })
 | 
			
		||||
  }, Error('fast-redact – Only one wildcard per path is supported'))
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('throws if a custom serializer is used and remove is true', ({ end, throws }) => {
 | 
			
		||||
  throws(() => {
 | 
			
		||||
    fastRedact({ paths: ['a'], serialize: (o) => o, remove: true })
 | 
			
		||||
  }, Error('fast-redact – remove option may only be set when serializer is JSON.stringify'))
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('throws if serialize is false and remove is true', ({ end, throws }) => {
 | 
			
		||||
  throws(() => {
 | 
			
		||||
    fastRedact({ paths: ['a'], serialize: false, remove: true })
 | 
			
		||||
  }, Error('fast-redact – remove option may only be set when serializer is JSON.stringify'))
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('masks according to supplied censor', ({ end, is }) => {
 | 
			
		||||
  const censor = 'test'
 | 
			
		||||
  const redact = fastRedact({ paths: ['a'], censor, serialize: false })
 | 
			
		||||
  is(redact({ a: 'a' }).a, censor)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact.restore function is available when serialize is false', ({ end, is }) => {
 | 
			
		||||
  const censor = 'test'
 | 
			
		||||
  const redact = fastRedact({ paths: ['a'], censor, serialize: false })
 | 
			
		||||
  is(typeof redact.restore, 'function')
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact.restore function places original values back in place', ({ end, is }) => {
 | 
			
		||||
  const censor = 'test'
 | 
			
		||||
  const redact = fastRedact({ paths: ['a'], censor, serialize: false })
 | 
			
		||||
  const o = { a: 'a' }
 | 
			
		||||
  redact(o)
 | 
			
		||||
  is(o.a, censor)
 | 
			
		||||
  redact.restore(o)
 | 
			
		||||
  is(o.a, 'a')
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('masks according to supplied censor function', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a'], censor: censorFct, serialize: false })
 | 
			
		||||
  is(redact({ a: '0123456' }).a, 'xxx56')
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('masks according to supplied censor function with wildcards', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: '*', censor: censorFct, serialize: false })
 | 
			
		||||
  is(redact({ a: '0123456' }).a, 'xxx56')
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('masks according to supplied censor function with nested wildcards', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['*.b'], censor: censorFct, serialize: false })
 | 
			
		||||
  is(redact({ a: { b: '0123456' } }).a.b, 'xxx56')
 | 
			
		||||
  is(redact({ c: { b: '0123456', d: 'pristine' } }).c.b, 'xxx56')
 | 
			
		||||
  is(redact({ c: { b: '0123456', d: 'pristine' } }).c.d, 'pristine')
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redact.restore function places original values back in place with censor function', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a'], censor: censorFct, serialize: false })
 | 
			
		||||
  const o = { a: 'qwerty' }
 | 
			
		||||
  redact(o)
 | 
			
		||||
  is(o.a, 'xxxty')
 | 
			
		||||
  redact.restore(o)
 | 
			
		||||
  is(o.a, 'qwerty')
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('serializes with JSON.stringify by default', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a'] })
 | 
			
		||||
  const o = { a: 'a' }
 | 
			
		||||
  is(redact(o), `{"a":"${censor}"}`)
 | 
			
		||||
  is(o.a, 'a')
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('removes during serialization instead of redacting when remove option is true', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a'], remove: true })
 | 
			
		||||
  const o = { a: 'a', b: 'b' }
 | 
			
		||||
  is(redact(o), `{"b":"b"}`)
 | 
			
		||||
  is(o.a, 'a')
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('serializes with JSON.stringify if serialize is true', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a'], serialize: true })
 | 
			
		||||
  const o = { a: 'a' }
 | 
			
		||||
  is(redact(o), `{"a":"${censor}"}`)
 | 
			
		||||
  is(o.a, 'a')
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('serializes with JSON.stringify if serialize is not a function', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a'], serialize: {} })
 | 
			
		||||
  const o = { a: 'a' }
 | 
			
		||||
  is(redact(o), `{"a":"${censor}"}`)
 | 
			
		||||
  is(o.a, 'a')
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('serializes with custom serializer if supplied', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a'], serialize: (o) => JSON.stringify(o, 0, 2) })
 | 
			
		||||
  const o = { a: 'a' }
 | 
			
		||||
  is(redact(o), `{\n  "a": "${censor}"\n}`)
 | 
			
		||||
  is(o.a, 'a')
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redacts parent keys', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a.b.c'], serialize: false })
 | 
			
		||||
  const result = redact({ a: { b: { c: 's' }, d: { a: 's', b: 's', c: 's' } } })
 | 
			
		||||
  is(result.a.b.c, censor)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('supports paths with array indexes', ({ end, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['insideArray.like[3].this'], serialize: false })
 | 
			
		||||
  same(redact({ insideArray: { like: ['a', 'b', 'c', { this: { foo: 'meow' } }] } }), { insideArray: { like: ['a', 'b', 'c', { this: censor }] } })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('censor may be any type, including function', ({ end, same }) => {
 | 
			
		||||
  const redactToString = fastRedact({ paths: ['a.b.c', 'a.b.d.*'], censor: 'censor', serialize: false })
 | 
			
		||||
  const redactToUndefined = fastRedact({ paths: ['a.b.c', 'a.b.d.*'], censor: undefined, serialize: false })
 | 
			
		||||
  const sym = Symbol('sym')
 | 
			
		||||
  const redactToSymbol = fastRedact({ paths: ['a.b.c', 'a.b.d.*'], censor: sym, serialize: false })
 | 
			
		||||
  const redactToNumber = fastRedact({ paths: ['a.b.c', 'a.b.d.*'], censor: 0, serialize: false })
 | 
			
		||||
  const redactToBoolean = fastRedact({ paths: ['a.b.c', 'a.b.d.*'], censor: false, serialize: false })
 | 
			
		||||
  const redactToNull = fastRedact({ paths: ['a.b.c', 'a.b.d.*'], censor: null, serialize: false })
 | 
			
		||||
  const redactToObject = fastRedact({ paths: ['a.b.c', 'a.b.d.*'], censor: { redacted: true }, serialize: false })
 | 
			
		||||
  const redactToArray = fastRedact({ paths: ['a.b.c', 'a.b.d.*'], censor: ['redacted'], serialize: false })
 | 
			
		||||
  const redactToBuffer = fastRedact({ paths: ['a.b.c', 'a.b.d.*'], censor: Buffer.from('redacted'), serialize: false })
 | 
			
		||||
  const redactToError = fastRedact({ paths: ['a.b.c', 'a.b.d.*'], censor: Error('redacted'), serialize: false })
 | 
			
		||||
  const redactToFunction = fastRedact({ paths: ['a.b.c', 'a.b.d.*'], censor: () => 'redacted', serialize: false })
 | 
			
		||||
  same(redactToString({ a: { b: { c: 's', d: { x: 's', y: 's' } } } }), { a: { b: { c: 'censor', d: { x: 'censor', y: 'censor' } } } })
 | 
			
		||||
  same(redactToUndefined({ a: { b: { c: 's', d: { x: 's', y: 's' } } } }), { a: { b: { c: undefined, d: { x: undefined, y: undefined } } } })
 | 
			
		||||
  same(redactToSymbol({ a: { b: { c: 's', d: { x: 's', y: 's' } } } }), { a: { b: { c: sym, d: { x: sym, y: sym } } } })
 | 
			
		||||
  same(redactToNumber({ a: { b: { c: 's', d: { x: 's', y: 's' } } } }), { a: { b: { c: 0, d: { x: 0, y: 0 } } } })
 | 
			
		||||
  same(redactToBoolean({ a: { b: { c: 's', d: { x: 's', y: 's' } } } }), { a: { b: { c: false, d: { x: false, y: false } } } })
 | 
			
		||||
  same(redactToNull({ a: { b: { c: 's', d: { x: 's', y: 's' } } } }), { a: { b: { c: null, d: { x: null, y: null } } } })
 | 
			
		||||
  same(redactToObject({ a: { b: { c: 's', d: { x: 's', y: 's' } } } }), { a: { b: { c: { redacted: true }, d: { x: { redacted: true }, y: { redacted: true } } } } })
 | 
			
		||||
  same(redactToArray({ a: { b: { c: 's', d: { x: 's', y: 's' } } } }), { a: { b: { c: ['redacted'], d: { x: ['redacted'], y: ['redacted'] } } } })
 | 
			
		||||
  same(redactToBuffer({ a: { b: { c: 's', d: { x: 's', y: 's' } } } }), { a: { b: { c: Buffer.from('redacted'), d: { x: Buffer.from('redacted'), y: Buffer.from('redacted') } } } })
 | 
			
		||||
  same(redactToError({ a: { b: { c: 's', d: { x: 's', y: 's' } } } }), { a: { b: { c: Error('redacted'), d: { x: Error('redacted'), y: Error('redacted') } } } })
 | 
			
		||||
  same(redactToFunction({ a: { b: { c: 's', d: { x: 's', y: 's' } } } }), { a: { b: { c: 'redacted', d: { x: 'redacted', y: 'redacted' } } } })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('supports multiple paths from the same root', ({ end, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['deep.bar.shoe', 'deep.baz.shoe', 'deep.foo', 'deep.not.there.sooo', 'deep.fum.shoe'], serialize: false })
 | 
			
		||||
  same(redact({ deep: { bar: 'hmm', baz: { shoe: { k: 1 } }, foo: {}, fum: { shoe: 'moo' } } }), { deep: { bar: 'hmm', baz: { shoe: censor }, foo: censor, fum: { shoe: censor } } })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('supports strings in bracket notation paths (single quote)', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: [`a['@#!='].c`], serialize: false })
 | 
			
		||||
  const result = redact({ a: { '@#!=': { c: 's' }, d: { a: 's', b: 's', c: 's' } } })
 | 
			
		||||
  is(result.a['@#!='].c, censor)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('supports strings in bracket notation paths (double quote)', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: [`a["@#!="].c`], serialize: false })
 | 
			
		||||
  const result = redact({ a: { '@#!=': { c: 's' }, d: { a: 's', b: 's', c: 's' } } })
 | 
			
		||||
  is(result.a['@#!='].c, censor)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('supports strings in bracket notation paths (backtick quote)', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a[`@#!=`].c'], serialize: false })
 | 
			
		||||
  const result = redact({ a: { '@#!=': { c: 's' }, d: { a: 's', b: 's', c: 's' } } })
 | 
			
		||||
  is(result.a['@#!='].c, censor)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('allows * within a bracket notation string', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a["*"].c'], serialize: false })
 | 
			
		||||
  const result = redact({ a: { '*': { c: 's', x: 1 } } })
 | 
			
		||||
  is(result.a['*'].c, censor)
 | 
			
		||||
  is(result.a['*'].x, 1)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('redacts parent keys – restore', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a.b.c'], serialize: false })
 | 
			
		||||
  const result = redact({ a: { b: { c: 's' }, d: { a: 's', b: 's', c: 's' } } })
 | 
			
		||||
  is(result.a.b.c, censor)
 | 
			
		||||
  redact.restore(result)
 | 
			
		||||
  is(result.a.b.c, 's')
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('handles null proto objects', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a.b.c'], serialize: false })
 | 
			
		||||
  const result = redact({ __proto__: null, a: { b: { c: 's' }, d: { a: 's', b: 's', c: 's' } } })
 | 
			
		||||
  is(result.a.b.c, censor)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('handles null proto objects – restore', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a.b.c'], serialize: false })
 | 
			
		||||
  const result = redact({ __proto__: null, a: { b: { c: 's' }, d: { a: 's', b: 's', c: 's' } } })
 | 
			
		||||
  is(result.a.b.c, censor)
 | 
			
		||||
  redact.restore(result, 's')
 | 
			
		||||
  is(result.a.b.c, 's')
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('handles paths that do not match object structure', ({ end, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['x.y.z'], serialize: false })
 | 
			
		||||
  same(redact({ a: { b: { c: 's' } } }), { a: { b: { c: 's' } } })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('ignores missing paths in object', ({ end, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a.b.c', 'a.z.d', 'a.b.z'], serialize: false })
 | 
			
		||||
  same(redact({ a: { b: { c: 's' } } }), { a: { b: { c: censor } } })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('ignores missing paths in object – restore', ({ end, doesNotThrow }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a.b.c', 'a.z.d', 'a.b.z'], serialize: false })
 | 
			
		||||
  const o = { a: { b: { c: 's' } } }
 | 
			
		||||
  redact(o)
 | 
			
		||||
  doesNotThrow(() => {
 | 
			
		||||
    redact.restore(o)
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('gracefully handles primitives that match intermediate keys in paths', ({ end, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a.b.c', 'a.b.c.d'], serialize: false })
 | 
			
		||||
  same(redact({ a: { b: null } }), { a: { b: null } })
 | 
			
		||||
  same(redact({ a: { b: 's' } }), { a: { b: 's' } })
 | 
			
		||||
  same(redact({ a: { b: 1 } }), { a: { b: 1 } })
 | 
			
		||||
  same(redact({ a: { b: undefined } }), { a: { b: undefined } })
 | 
			
		||||
  same(redact({ a: { b: true } }), { a: { b: true } })
 | 
			
		||||
  const sym = Symbol('sym')
 | 
			
		||||
  same(redact({ a: { b: sym } }), { a: { b: sym } })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('handles circulars', ({ end, is, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['bar.baz.baz'], serialize: false })
 | 
			
		||||
  const bar = { b: 2 }
 | 
			
		||||
  const o = { a: 1, bar }
 | 
			
		||||
  bar.baz = bar
 | 
			
		||||
  o.bar.baz = o.bar
 | 
			
		||||
  same(redact(o), { a: 1, bar: { b: 2, baz: censor } })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('handles circulars – restore', ({ end, is, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['bar.baz.baz'], serialize: false })
 | 
			
		||||
  const bar = { b: 2 }
 | 
			
		||||
  const o = { a: 1, bar }
 | 
			
		||||
  bar.baz = bar
 | 
			
		||||
  o.bar.baz = o.bar
 | 
			
		||||
  is(o.bar.baz, bar)
 | 
			
		||||
  redact(o)
 | 
			
		||||
  is(o.bar.baz, censor)
 | 
			
		||||
  redact.restore(o)
 | 
			
		||||
  is(o.bar.baz, bar)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('handles circulars and cross references – restore', ({ end, is, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['bar.baz.baz', 'cf.bar'], serialize: false })
 | 
			
		||||
  const bar = { b: 2 }
 | 
			
		||||
  const o = { a: 1, bar, cf: { bar } }
 | 
			
		||||
  bar.baz = bar
 | 
			
		||||
  o.bar.baz = o.bar
 | 
			
		||||
  is(o.bar.baz, bar)
 | 
			
		||||
  is(o.cf.bar, bar)
 | 
			
		||||
  redact(o)
 | 
			
		||||
  is(o.bar.baz, censor)
 | 
			
		||||
  is(o.cf.bar, censor)
 | 
			
		||||
  redact.restore(o)
 | 
			
		||||
  is(o.bar.baz, bar)
 | 
			
		||||
  is(o.cf.bar, bar)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('ultimate wildcards – shallow', ({ end, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['test.*'], serialize: false })
 | 
			
		||||
  same(redact({ test: { baz: 1, bar: 'private' } }), { test: { baz: censor, bar: censor } })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('ultimate wildcards – deep', ({ end, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['deep.bar.baz.ding.*'], serialize: false })
 | 
			
		||||
  same(redact({ deep: { a: 1, bar: { b: 2, baz: { c: 3, ding: { d: 4, e: 5, f: 'six' } } } } }), { deep: { a: 1, bar: { b: 2, baz: { c: 3, ding: { d: censor, e: censor, f: censor } } } } })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('ultimate wildcards - array – shallow', ({ end, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['array[*]'], serialize: false })
 | 
			
		||||
  same(redact({ array: ['a', 'b', 'c', 'd'] }), { array: [censor, censor, censor, censor] })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('ultimate wildcards – array – deep', ({ end, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['deepArray.down.here[*]'], serialize: false })
 | 
			
		||||
  same(redact({ deepArray: { down: { here: ['a', 'b', 'c'] } } }), { deepArray: { down: { here: [censor, censor, censor] } } })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('ultimate wildcards – array – single index', ({ end, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['insideArray.like[3].this.*'], serialize: false })
 | 
			
		||||
  same(redact({ insideArray: { like: ['a', 'b', 'c', { this: { foo: 'meow' } }] } }), { insideArray: { like: ['a', 'b', 'c', { this: { foo: censor } }] } })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('ultimate wildcards - handles null proto objects', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a.b.c'], serialize: false })
 | 
			
		||||
  const result = redact({ __proto__: null, a: { b: { c: 's' }, d: { a: 's', b: 's', c: 's' } } })
 | 
			
		||||
  is(result.a.b.c, censor)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('ultimate wildcards - handles paths that do not match object structure', ({ end, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['x.y.z'], serialize: false })
 | 
			
		||||
  same(redact({ a: { b: { c: 's' } } }), { a: { b: { c: 's' } } })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('ultimate wildcards - gracefully handles primitives that match intermediate keys in paths', ({ end, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a.b.c', 'a.b.c.d'], serialize: false })
 | 
			
		||||
  same(redact({ a: { b: null } }), { a: { b: null } })
 | 
			
		||||
  same(redact({ a: { b: 's' } }), { a: { b: 's' } })
 | 
			
		||||
  same(redact({ a: { b: 1 } }), { a: { b: 1 } })
 | 
			
		||||
  same(redact({ a: { b: undefined } }), { a: { b: undefined } })
 | 
			
		||||
  same(redact({ a: { b: true } }), { a: { b: true } })
 | 
			
		||||
  const sym = Symbol('sym')
 | 
			
		||||
  same(redact({ a: { b: sym } }), { a: { b: sym } })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('ultimate wildcards – handles circulars', ({ end, is, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['bar.baz.*'], serialize: false })
 | 
			
		||||
  const bar = { b: 2 }
 | 
			
		||||
  const o = { a: 1, bar }
 | 
			
		||||
  bar.baz = bar
 | 
			
		||||
  o.bar.baz = o.bar
 | 
			
		||||
  same(redact(o), { a: 1, bar: { b: censor, baz: censor } })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('ultimate wildcards – handles circulars – restore', ({ end, is, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['bar.baz.*'], serialize: false })
 | 
			
		||||
  const bar = { b: 2 }
 | 
			
		||||
  const o = { a: 1, bar }
 | 
			
		||||
  bar.baz = bar
 | 
			
		||||
  o.bar.baz = o.bar
 | 
			
		||||
  is(o.bar.baz, bar)
 | 
			
		||||
  redact(o)
 | 
			
		||||
  is(o.bar.baz, censor)
 | 
			
		||||
  redact.restore(o)
 | 
			
		||||
  is(o.bar.baz, bar)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('ultimate wildcards – handles circulars and cross references – restore', ({ end, is, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['bar.baz.*', 'cf.*'], serialize: false })
 | 
			
		||||
  const bar = { b: 2 }
 | 
			
		||||
  const o = { a: 1, bar, cf: { bar } }
 | 
			
		||||
  bar.baz = bar
 | 
			
		||||
  o.bar.baz = o.bar
 | 
			
		||||
  is(o.bar.baz, bar)
 | 
			
		||||
  is(o.cf.bar, bar)
 | 
			
		||||
  redact(o)
 | 
			
		||||
  is(o.bar.baz, censor)
 | 
			
		||||
  is(o.cf.bar, censor)
 | 
			
		||||
  redact.restore(o)
 | 
			
		||||
  is(o.bar.baz, bar)
 | 
			
		||||
  is(o.cf.bar, bar)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('static + wildcards', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a.b.c', 'a.d.*', 'a.b.z.*'], serialize: false })
 | 
			
		||||
  const result = redact({ a: { b: { c: 's', z: { x: 's', y: 's' } }, d: { a: 's', b: 's', c: 's' } } })
 | 
			
		||||
 | 
			
		||||
  is(result.a.b.c, censor)
 | 
			
		||||
  is(result.a.d.a, censor)
 | 
			
		||||
  is(result.a.d.b, censor)
 | 
			
		||||
  is(result.a.d.c, censor)
 | 
			
		||||
  is(result.a.b.z.x, censor)
 | 
			
		||||
  is(result.a.b.z.y, censor)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('static + wildcards reuse', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a.b.c', 'a.d.*'], serialize: false })
 | 
			
		||||
  const result = redact({ a: { b: { c: 's' }, d: { a: 's', b: 's', c: 's' } } })
 | 
			
		||||
 | 
			
		||||
  is(result.a.b.c, censor)
 | 
			
		||||
  is(result.a.d.a, censor)
 | 
			
		||||
  is(result.a.d.b, censor)
 | 
			
		||||
  is(result.a.d.c, censor)
 | 
			
		||||
 | 
			
		||||
  redact.restore(result)
 | 
			
		||||
 | 
			
		||||
  const result2 = redact({ a: { b: { c: 's' }, d: { a: 's', b: 's', c: 's' } } })
 | 
			
		||||
  is(result2.a.b.c, censor)
 | 
			
		||||
  is(result2.a.d.a, censor)
 | 
			
		||||
  is(result2.a.d.b, censor)
 | 
			
		||||
  is(result2.a.d.c, censor)
 | 
			
		||||
 | 
			
		||||
  redact.restore(result2)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('parent wildcard – first position', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['*.c'], serialize: false })
 | 
			
		||||
  const result = redact({ b: { c: 's' }, d: { a: 's', b: 's', c: 's' } })
 | 
			
		||||
  is(result.b.c, censor)
 | 
			
		||||
  is(result.d.a, 's')
 | 
			
		||||
  is(result.d.b, 's')
 | 
			
		||||
  is(result.d.c, censor)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('parent wildcard – one following key', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a.*.c'], serialize: false })
 | 
			
		||||
  const result = redact({ a: { b: { c: 's' }, d: { a: 's', b: 's', c: 's' } } })
 | 
			
		||||
  is(result.a.b.c, censor)
 | 
			
		||||
  is(result.a.d.a, 's')
 | 
			
		||||
  is(result.a.d.b, 's')
 | 
			
		||||
  is(result.a.d.c, censor)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('restore parent wildcard  – one following key', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a.*.c'], serialize: false })
 | 
			
		||||
  const result = redact({ a: { b: { c: 's' }, d: { a: 's', b: 's', c: 's' } } })
 | 
			
		||||
  redact.restore(result)
 | 
			
		||||
  is(result.a.b.c, 's')
 | 
			
		||||
  is(result.a.d.a, 's')
 | 
			
		||||
  is(result.a.d.b, 's')
 | 
			
		||||
  is(result.a.d.c, 's')
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('parent wildcard – one following key – reuse', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a.*.c'], serialize: false })
 | 
			
		||||
  const result = redact({ a: { b: { c: 's' }, d: { a: 's', b: 's', c: 's' } } })
 | 
			
		||||
  is(result.a.b.c, censor)
 | 
			
		||||
  is(result.a.d.a, 's')
 | 
			
		||||
  is(result.a.d.b, 's')
 | 
			
		||||
  is(result.a.d.c, censor)
 | 
			
		||||
  const result2 = redact({ a: { b: { c: 's' }, d: { a: 's', b: 's', c: 's' } } })
 | 
			
		||||
  is(result2.a.b.c, censor)
 | 
			
		||||
  is(result2.a.d.a, 's')
 | 
			
		||||
  is(result2.a.d.b, 's')
 | 
			
		||||
  is(result2.a.d.c, censor)
 | 
			
		||||
  redact.restore(result2)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('parent wildcard – two following keys', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a.*.x.c'], serialize: false })
 | 
			
		||||
  const result = redact({ a: { b: { x: { c: 's' } }, d: { x: { a: 's', b: 's', c: 's' } } } })
 | 
			
		||||
  is(result.a.b.x.c, censor)
 | 
			
		||||
  is(result.a.d.x.a, 's')
 | 
			
		||||
  is(result.a.d.x.b, 's')
 | 
			
		||||
  is(result.a.d.x.c, censor)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('parent wildcard  – two following keys – reuse', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a.*.x.c'], serialize: false })
 | 
			
		||||
  const result = redact({ a: { b: { x: { c: 's' } }, d: { x: { a: 's', b: 's', c: 's' } } } })
 | 
			
		||||
  is(result.a.b.x.c, censor)
 | 
			
		||||
  is(result.a.d.x.a, 's')
 | 
			
		||||
  is(result.a.d.x.b, 's')
 | 
			
		||||
  is(result.a.d.x.c, censor)
 | 
			
		||||
  redact.restore(result)
 | 
			
		||||
  const result2 = redact({ a: { b: { x: { c: 's' } }, d: { x: { a: 's', b: 's', c: 's' } } } })
 | 
			
		||||
  is(result2.a.b.x.c, censor)
 | 
			
		||||
  is(result2.a.d.x.a, 's')
 | 
			
		||||
  is(result2.a.d.x.b, 's')
 | 
			
		||||
  is(result2.a.d.x.c, censor)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('restore parent wildcard  – two following keys', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a.*.x.c'], serialize: false })
 | 
			
		||||
  const result = redact({ a: { b: { x: { c: 's' } }, d: { x: { a: 's', b: 's', c: 's' } } } })
 | 
			
		||||
  redact.restore(result)
 | 
			
		||||
  is(result.a.b.x.c, 's')
 | 
			
		||||
  is(result.a.d.x.a, 's')
 | 
			
		||||
  is(result.a.d.x.b, 's')
 | 
			
		||||
  is(result.a.d.x.c, 's')
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('parent wildcard - array', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a.b[*].x'], serialize: false })
 | 
			
		||||
  const result = redact({ a: { b: [{ x: 1 }, { a: 2 }], d: { a: 's', b: 's', c: 's' } } })
 | 
			
		||||
  is(result.a.b[0].x, censor)
 | 
			
		||||
  is(result.a.b[1].a, 2)
 | 
			
		||||
  is(result.a.d.a, 's')
 | 
			
		||||
  is(result.a.d.b, 's')
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('parent wildcards – array – single index', ({ end, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['insideArray.like[3].*.foo'], serialize: false })
 | 
			
		||||
  same(redact({ insideArray: { like: ['a', 'b', 'c', { this: { foo: 'meow' } }] } }), { insideArray: { like: ['a', 'b', 'c', { this: { foo: censor } }] } })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('parent wildcards - handles null proto objects', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a.*.c'], serialize: false })
 | 
			
		||||
  const result = redact({ __proto__: null, a: { b: { c: 's' }, d: { a: 's', b: 's', c: 's' } } })
 | 
			
		||||
  is(result.a.b.c, censor)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('parent wildcards - handles paths that do not match object structure', ({ end, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a.*.y.z'], serialize: false })
 | 
			
		||||
  same(redact({ a: { b: { c: 's' } } }), { a: { b: { c: 's' } } })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('parent wildcards - gracefully handles primitives that match intermediate keys in paths', ({ end, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a.*.c'], serialize: false })
 | 
			
		||||
  same(redact({ a: { b: null } }), { a: { b: null } })
 | 
			
		||||
  same(redact({ a: { b: 's' } }), { a: { b: 's' } })
 | 
			
		||||
  same(redact({ a: { b: 1 } }), { a: { b: 1 } })
 | 
			
		||||
  same(redact({ a: { b: undefined } }), { a: { b: undefined } })
 | 
			
		||||
  same(redact({ a: { b: true } }), { a: { b: true } })
 | 
			
		||||
  const sym = Symbol('sym')
 | 
			
		||||
  same(redact({ a: { b: sym } }), { a: { b: sym } })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('parent wildcards – handles circulars', ({ end, is, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['x.*.baz'], serialize: false })
 | 
			
		||||
  const bar = { b: 2 }
 | 
			
		||||
  const o = { x: { a: 1, bar } }
 | 
			
		||||
  bar.baz = bar
 | 
			
		||||
  o.x.bar.baz = o.x.bar
 | 
			
		||||
  same(redact(o), { x: { a: 1, bar: { b: 2, baz: censor } } })
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('parent wildcards – handles circulars – restore', ({ end, is, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['x.*.baz'], serialize: false })
 | 
			
		||||
  const bar = { b: 2 }
 | 
			
		||||
  const o = { x: { a: 1, bar } }
 | 
			
		||||
  bar.baz = bar
 | 
			
		||||
  o.x.bar.baz = o.x.bar
 | 
			
		||||
  is(o.x.bar.baz, bar)
 | 
			
		||||
  redact(o)
 | 
			
		||||
  is(o.x.a, 1)
 | 
			
		||||
  is(o.x.bar.baz, censor)
 | 
			
		||||
  redact.restore(o)
 | 
			
		||||
  is(o.x.bar.baz, bar)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('parent wildcards – handles circulars and cross references – restore', ({ end, is, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['x.*.baz', 'x.*.cf.bar'], serialize: false })
 | 
			
		||||
  const bar = { b: 2 }
 | 
			
		||||
  const o = { x: { a: 1, bar, y: { cf: { bar } } } }
 | 
			
		||||
  bar.baz = bar
 | 
			
		||||
  o.x.bar.baz = o.x.bar
 | 
			
		||||
  is(o.x.bar.baz, bar)
 | 
			
		||||
  is(o.x.y.cf.bar, bar)
 | 
			
		||||
  redact(o)
 | 
			
		||||
  is(o.x.bar.baz, censor)
 | 
			
		||||
  is(o.x.y.cf.bar, censor)
 | 
			
		||||
  redact.restore(o)
 | 
			
		||||
  is(o.x.bar.baz, bar)
 | 
			
		||||
  is(o.x.y.cf.bar, bar)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('parent wildcards – handles missing paths', ({ end, is, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['z.*.baz'] })
 | 
			
		||||
  const o = { a: { b: { c: 's' }, d: { a: 's', b: 's', c: 's' } } }
 | 
			
		||||
  is(redact(o), JSON.stringify(o))
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('ultimate wildcards – handles missing paths', ({ end, is, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['z.*'] })
 | 
			
		||||
  const o = { a: { b: { c: 's' }, d: { a: 's', b: 's', c: 's' } } }
 | 
			
		||||
  is(redact(o), JSON.stringify(o))
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('parent wildcards – removes during serialization instead of redacting when remove option is true', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a.*.c'], remove: true })
 | 
			
		||||
  const o = { a: { b: { c: 'c' }, x: { c: 1 } } }
 | 
			
		||||
  is(redact(o), `{"a":{"b":{},"x":{}}}`)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('ultimate wildcards – removes during serialization instead of redacting when remove option is true', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['a.b.*'], remove: true })
 | 
			
		||||
  const o = { a: { b: { c: 'c' }, x: { c: 1 } } }
 | 
			
		||||
  is(redact(o), `{"a":{"b":{},"x":{"c":1}}}`)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('supports leading bracket notation', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['["a"].b.c'] })
 | 
			
		||||
  const o = { a: { b: { c: 'd' } } }
 | 
			
		||||
  is(redact(o), `{"a":{"b":{"c":"${censor}"}}}`)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('supports leading bracket notation containing non-legal keyword characters', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['["a-x"].b.c'] })
 | 
			
		||||
  const o = { 'a-x': { b: { c: 'd' } } }
 | 
			
		||||
  is(redact(o), `{"a-x":{"b":{"c":"${censor}"}}}`)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('supports single leading bracket', ({ end, is }) => {
 | 
			
		||||
  const censor = 'test'
 | 
			
		||||
  const redact = fastRedact({ paths: ['["a"]'], censor, serialize: false })
 | 
			
		||||
  is(redact({ a: 'a' }).a, censor)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('supports single leading bracket containing non-legal keyword characters', ({ end, is }) => {
 | 
			
		||||
  const censor = 'test'
 | 
			
		||||
  const redact = fastRedact({ paths: ['["a-x"]'], censor, serialize: false })
 | 
			
		||||
  is(redact({ 'a-x': 'a' })['a-x'], censor)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('(leading brackets) ultimate wildcards – handles circulars and cross references – restore', ({ end, is, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['bar.baz.*', 'cf.*'], serialize: false })
 | 
			
		||||
  const bar = { b: 2 }
 | 
			
		||||
  const o = { a: 1, bar, cf: { bar } }
 | 
			
		||||
  bar.baz = bar
 | 
			
		||||
  o.bar.baz = o.bar
 | 
			
		||||
  is(o.bar.baz, bar)
 | 
			
		||||
  is(o.cf.bar, bar)
 | 
			
		||||
  redact(o)
 | 
			
		||||
  is(o.bar.baz, censor)
 | 
			
		||||
  is(o.cf.bar, censor)
 | 
			
		||||
  redact.restore(o)
 | 
			
		||||
  is(o.bar.baz, bar)
 | 
			
		||||
  is(o.cf.bar, bar)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('(leading brackets) parent wildcards – handles circulars and cross references – restore', ({ end, is, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['["x"].*.baz', '["x"].*.cf.bar'], serialize: false })
 | 
			
		||||
  const bar = { b: 2 }
 | 
			
		||||
  const o = { x: { a: 1, bar, y: { cf: { bar } } } }
 | 
			
		||||
  bar.baz = bar
 | 
			
		||||
  o.x.bar.baz = o.x.bar
 | 
			
		||||
  is(o.x.bar.baz, bar)
 | 
			
		||||
  is(o.x.y.cf.bar, bar)
 | 
			
		||||
  redact(o)
 | 
			
		||||
  is(o.x.bar.baz, censor)
 | 
			
		||||
  is(o.x.y.cf.bar, censor)
 | 
			
		||||
  redact.restore(o)
 | 
			
		||||
  is(o.x.bar.baz, bar)
 | 
			
		||||
  is(o.x.y.cf.bar, bar)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('(leading brackets) ultimate wildcards – handles missing paths', ({ end, is, same }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['["z"].*'] })
 | 
			
		||||
  const o = { a: { b: { c: 's' }, d: { a: 's', b: 's', c: 's' } } }
 | 
			
		||||
  is(redact(o), JSON.stringify(o))
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('(leading brackets) static + wildcards reuse', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['["a"].b.c', '["a"].d.*'], serialize: false })
 | 
			
		||||
  const result = redact({ a: { b: { c: 's' }, d: { a: 's', b: 's', c: 's' } } })
 | 
			
		||||
 | 
			
		||||
  is(result.a.b.c, censor)
 | 
			
		||||
  is(result.a.d.a, censor)
 | 
			
		||||
  is(result.a.d.b, censor)
 | 
			
		||||
  is(result.a.d.c, censor)
 | 
			
		||||
 | 
			
		||||
  redact.restore(result)
 | 
			
		||||
 | 
			
		||||
  const result2 = redact({ a: { b: { c: 's' }, d: { a: 's', b: 's', c: 's' } } })
 | 
			
		||||
  is(result2.a.b.c, censor)
 | 
			
		||||
  is(result2.a.d.a, censor)
 | 
			
		||||
  is(result2.a.d.b, censor)
 | 
			
		||||
  is(result2.a.d.c, censor)
 | 
			
		||||
 | 
			
		||||
  redact.restore(result2)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('correctly restores original object when a path does not match object', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['foo.bar'], strict: false })
 | 
			
		||||
  const o = {}
 | 
			
		||||
  is(redact({ foo: o }), '{"foo":{}}')
 | 
			
		||||
  is(o.hasOwnProperty('bar'), false)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('correctly restores original object when a matching path has value of `undefined`', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['foo.bar'], strict: false })
 | 
			
		||||
  const o = { bar: undefined }
 | 
			
		||||
  is(redact({ foo: o }), '{"foo":{}}')
 | 
			
		||||
  is(o.hasOwnProperty('bar'), true)
 | 
			
		||||
  is(o.bar, undefined)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('handles multiple paths with leading brackets', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['["x-y"]', '["y-x"]'] })
 | 
			
		||||
  const o = { 'x-y': 'test', 'y-x': 'test2' }
 | 
			
		||||
  is(redact(o), '{"x-y":"[REDACTED]","y-x":"[REDACTED]"}')
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('handles objects with and then without target paths', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['test'] })
 | 
			
		||||
  const o1 = { test: 'check' }
 | 
			
		||||
  const o2 = {}
 | 
			
		||||
  is(redact(o1), '{"test":"[REDACTED]"}')
 | 
			
		||||
  is(redact(o2), '{}')
 | 
			
		||||
  // run each check twice to ensure no mutations
 | 
			
		||||
  is(redact(o1), '{"test":"[REDACTED]"}')
 | 
			
		||||
  is(redact(o2), '{}')
 | 
			
		||||
  is('test' in o1, true)
 | 
			
		||||
  is('test' in o2, false)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('handles leading wildcards and null values', ({ end, is }) => {
 | 
			
		||||
  const redact = fastRedact({ paths: ['*.test'] })
 | 
			
		||||
  const o = { prop: null }
 | 
			
		||||
  is(redact(o), '{"prop":null}')
 | 
			
		||||
  is(o.prop, null)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('handles keys with dots', ({ end, is }) => {
 | 
			
		||||
  const redactSingleQ = fastRedact({ paths: [`a['b.c']`], serialize: false })
 | 
			
		||||
  const redactDoubleQ = fastRedact({ paths: [`a["b.c"]`], serialize: false })
 | 
			
		||||
  const redactBacktickQ = fastRedact({ paths: ['a[`b.c`]'], serialize: false })
 | 
			
		||||
  const redactNum = fastRedact({ paths: [`a[-1.2]`], serialize: false })
 | 
			
		||||
  const redactLeading = fastRedact({ paths: [`["b.c"]`], serialize: false })
 | 
			
		||||
  is(redactSingleQ({ a: { 'b.c': 'x', '-1.2': 'x' } }).a['b.c'], censor)
 | 
			
		||||
  is(redactDoubleQ({ a: { 'b.c': 'x', '-1.2': 'x' } }).a['b.c'], censor)
 | 
			
		||||
  is(redactBacktickQ({ a: { 'b.c': 'x', '-1.2': 'x' } }).a['b.c'], censor)
 | 
			
		||||
  is(redactNum({ a: { 'b.c': 'x', '-1.2': 'x' } }).a['-1.2'], censor)
 | 
			
		||||
  is(redactLeading({ 'b.c': 'x', '-1.2': 'x' })['b.c'], censor)
 | 
			
		||||
  end()
 | 
			
		||||
})
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue