Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
json-reduce
Advanced tools
Reduce any JSON value by traversing depth first and visiting each node
Reduce any JSON value by traversing depth first and visiting each node
import {reduce} from 'json-reduce'
const document = {
first: 1,
second: 2,
deep: {
array: [3, 4, 5, 6],
seven: 7
}
}
const result = reduce(
document,
(acc, value, path) => (typeof value === 'number' ? acc + value : acc),
0
)
console.log(result)
//=> 28
reduce(value, reducer, initialValue)
reducer
is the reducer function to execute for each node in the tree, and is given three arguments:
accumulator
- The accumulation of the callback's return values; it is the value returned
from the previous invocation of the callback, or initialValue
.value
- The current node being traversedpath
- The "dot-path" to the current node being traversed, e.g. ['deep', 'array', 2]
Sometimes when encountering a specific object or array value, you want to skip traversing the subtree. This can be done calling a provided SKIP function like this:
import reduce, {SKIP} from 'json-reduce'
const doc = {
species: [
{name: 'clover', type: 'plant'},
{name: 'trout', type: 'fish', eats: [{type: 'animal', name: 'crayfish'}]},
{
type: 'animal',
name: 'bear',
food: [
{
type: 'animal',
name: 'deer',
food: [{type: 'plant', name: 'leaves'}]
},
{
type: 'plant',
name: 'blueberry'
}
]
}
]
}
const result = reduce(
doc,
(acc, val, path) => {
if (val.type === 'plant' || val.type === 'fish') {
// We don't want to traverse the subtrees of these
return SKIP
}
// Collect all traversed paths
return acc.concat([path])
},
[]
)
expect(result).toEqual([
[],
['species'],
['species', 2],
['species', 2, 'type'],
['species', 2, 'name'],
['species', 2, 'food'],
['species', 2, 'food', 0],
['species', 2, 'food', 0, 'type'],
['species', 2, 'food', 0, 'name'],
['species', 2, 'food', 0, 'food']
])
In addition to return SKIP
, you can also call SKIP with a return value for convenience, to both return the accumulated
value and signal subtree skipping in one operation, e.g.:
//
reduce(doc, (acc, node) => {
if (node.type === 'plant' || node.type === 'fish') {
// Uppercase plant and fish names, but skip traversing subtrees
return SKIP(
acc.concat({
...node,
name: node.name.toUpperCase()
})
)
}
return acc
}, [])
reduce()
will probably crash with maximum call stack size exceeded.Map
, Set
, etc. are not currently supported (PR welcome!).FAQs
Reduce any JSON value by traversing depth first and visiting each node
We found that json-reduce demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.