Security News
JSR Working Group Kicks Off with Ambitious Roadmap and Plans for Open Governance
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
neotraverse
Advanced tools
Traverse and transform objects by visiting every node on a recursive walk. This is a fork and TypeScript rewrite of traverse with 0 dependencies and major improvements:
@types/traverse
packageRules this package aims to follow for an indefinite period of time:
traverse
API. There already are many packages that do this. neotraverse
intends to be a drop-in replacement for traverse
and provide the same API with 0 dependencies and enhanced Developer Experience.neotraverse/modern
build.neotraverse/modern
provides a new class new Traverse()
, and all methods and state is provided as first argument ctx
(this.update -> ctx.update
, this.isLeaf -> ctx.isLeaf
, etc.)
Before:
import traverse from 'neotraverse';
const obj = { a: 1, b: 2, c: [3, 4] };
traverse(obj).forEach(function (x) {
if (x < 0) this.update(x + 128);
});
After:
import { Traverse } from 'neotraverse/modern';
const obj = { a: 1, b: 2, c: [3, 4] };
new Traverse(obj).forEach((ctx, x) => {
if (x < 0) ctx.update(x + 128);
});
neotraverse
provides 3 builds:
traverse
and provides the same API, but ESM only and compiled to ES2022 with Node 18+new Traverse()
, and all methods and state is provided as first argument ctx
(this.update -> ctx.update
, this.isLeaf -> ctx.isLeaf
, etc.)traverse
and provides the same API.Here's a matrix of the different builds:
Build | ESM | CJS | Browser | Node | Polyfills | Size |
---|---|---|---|---|---|---|
default | ✅ ES2022 | ✅ | ✅ | ❌ | 1.54KB min+brotli | |
modern | ✅ ES2022 | ✅ | ✅ | ❌ | 1.38KB min+brotli | |
legacy | ✅ ES5 | ✅ | ✅ | ✅ | ❌ | 2.73KB min+brotli |
If you are:
import { Traverse } from 'neotraverse/modern';
const obj = { a: 1, b: 2, c: [3, 4] };
new Traverse(obj).forEach((ctx, x) => {
if (x < 0) ctx.update(x + 128); // `this` is same as `ctx` when using regular function
});
traverse
Use default build for no breaking changes, and a modern build for better developer experience.
import traverse from 'neotraverse';
const obj = { a: 1, b: 2, c: [3, 4] };
traverse(obj).forEach(function (x) {
if (x < 0) this.update(x + 128);
});
Use legacy build for compatibility with old browsers and Node versions.
const traverse = require('neotraverse/legacy');
ESM:
import traverse from 'neotraverse/legacy';
negative.js
import { Traverse } from 'neotraverse/modern';
const obj = [5, 6, -3, [7, 8, -2, 1], { f: 10, g: -13 }];
new Traverse(obj).forEach(function (ctx, x) {
if (x < 0) ctx.update(x + 128);
});
console.dir(obj);
or in legacy mode:
import traverse from 'neotraverse';
// OR import traverse from 'neotraverse/legacy';
const obj = [5, 6, -3, [7, 8, -2, 1], { f: 10, g: -13 }];
traverse(obj).forEach(function (x) {
if (x < 0) this.update(x + 128);
});
// This is identical to the above
traverse.forEach(obj, function (x) {
if (x < 0) this.update(x + 128);
});
console.dir(obj);
Output:
[ 5, 6, 125, [ 7, 8, 126, 1 ], { f: 10, g: 115 } ]
leaves.js
import { Traverse } from 'neotraverse/modern';
const obj = {
a: [1, 2, 3],
b: 4,
c: [5, 6],
d: { e: [7, 8], f: 9 }
};
const leaves = new Traverse(obj).reduce((ctx, acc, x) => {
if (ctx.isLeaf) acc.push(x);
return acc;
}, []);
console.dir(leaves);
or in legacy mode:
import traverse from 'neotraverse';
// OR import traverse from 'neotraverse/legacy';
const obj = {
a: [1, 2, 3],
b: 4,
c: [5, 6],
d: { e: [7, 8], f: 9 }
};
const leaves = traverse(obj).reduce(function (acc, x) {
if (this.isLeaf) acc.push(x);
return acc;
}, []);
// Equivalent to the above
const leavesLegacy = traverse.reduce(
obj,
function (acc, x) {
if (this.isLeaf) acc.push(x);
return acc;
},
[]
);
console.dir(leaves);
console.dir(leavesLegacy);
Output:
[ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
scrub.js:
import { Traverse } from 'neotraverse/modern';
const obj = { a: 1, b: 2, c: [3, 4] };
obj.c.push(obj);
const scrubbed = new Traverse(obj).map(function (ctx, x) {
if (ctx.circular) ctx.remove();
});
console.dir(scrubbed);
or in legacy mode:
import traverse from 'neotraverse';
// OR import traverse from 'neotraverse/legacy';
const obj = { a: 1, b: 2, c: [3, 4] };
obj.c.push(obj);
const scrubbed = traverse(obj).map(function (x) {
if (this.circular) this.remove();
});
// Equivalent to the above
const scrubbedLegacy = traverse.map(obj, function (x) {
if (this.circular) this.remove();
});
console.dir(scrubbed);
console.dir(scrubbedLegacy);
output:
{ a: 1, b: 2, c: [ 3, 4 ] }
neotraverse/legacy is compatible with commonjs and provides the same API as traverse
, acting as a drop-in replacement:
const traverse = require('neotraverse/legacy');
import { Traverse } from 'neotraverse/modern';
import traverse from 'neotraverse';
traverse
@types/traverse
new Traverse()
class instead of regular old traverse()
ES5
and CJS
There is a legacy mode that provides the same API as traverse
, acting as a drop-in replacement:
import traverse from 'neotraverse';
const obj = { a: 1, b: 2, c: [3, 4] };
traverse(obj).forEach(function (x) {
if (x < 0) this.update(x + 128);
});
If you want to support really old browsers or NodeJS, supporting ES5, there's neotraverse/legacy
which is compatible with ES5 and provides the same API as traverse
, acting as a drop-in replacement for older browsers:
import traverse from 'neotraverse/legacy';
const obj = { a: 1, b: 2, c: [3, 4] };
traverse(obj).forEach(function (x) {
if (x < 0) this.update(x + 128);
});
traverse
neotraverse
npm install neotraverse
npm uninstall traverse @types/traverse # Remove the old dependencies
traverse
with neotraverse
-import traverse from 'traverse';
+import traverse from 'neotraverse';
const obj = { a: 1, b: 2, c: [3, 4] };
-traverse(obj).forEach(function (x) {
+traverse(obj).forEach(function (x) {
if (x < 0) this.update(x + 128);
});
Optionally, there's also a legacy mode that provides the same API as traverse
, acting as a drop-in replacement:
import traverse from 'neotraverse/legacy';
const obj = { a: 1, b: 2, c: [3, 4] };
traverse(obj).forEach(function (x) {
if (x < 0) this.update(x + 128);
});
If you use Vite, you can aliss traverse
to neotravers/legacy
in your vite.config.js
:
import { defineConfig } from 'vite';
export default defineConfig({
resolve: {
alias: {
traverse: 'neotraverse' // or 'neotraverse/legacy'
}
}
});
Each method that takes an fn
uses the context documented below in the context section.
Execute fn
for each node in the object and return a new object with the results of the walk. To update nodes in the result use ctx.update(value)
(modern) or this.update(value)
(legacy).
Execute fn
for each node in the object but unlike .map()
, when ctx.update()
(modern) or this.update()
(legacy) is called it updates the object in-place.
For each node in the object, perform a left-fold with the return value of fn(acc, node)
.
If acc
isn't specified, acc
is set to the root object for the first step and the root element is skipped.
Return an Array
of every possible non-cyclic path in the object. Paths are Array
s of string keys.
Return an Array
of every node in the object.
Create a deep clone of the object.
Get the element at the array path
.
Set the element at the array path
to value
.
Return whether the element at the array path
exists.
Each method that takes a callback has a context (its ctx
object, or this
object in legacy mode) with these attributes:
The present node on the recursive walk
An array of string keys from the root to the present node
The context of the node's parent. This is undefined
for the root node.
The name of the key of the present node in its parent. This is undefined
for the root node.
Whether the present node is the root node
Whether or not the present node is a leaf node (has no children)
Depth of the node within the traversal
If the node equals one of its parents, the circular
attribute is set to the context of that parent and the traversal progresses no deeper.
Set a new value for the present node.
All the elements in value
will be recursively traversed unless stopHere
is true.
Remove the current element from the output. If the node is in an Array it will be spliced off. Otherwise it will be deleted from its parent.
Delete the current element from its parent in the output. Calls delete
even on Arrays.
Call this function before any of the children are traversed.
You can assign into ctx.keys
(modern) or this.keys
(legacy) here to traverse in a custom order.
Call this function after any of the children are traversed.
Call this function before each of the children are traversed.
Call this function after each of the children are traversed.
MIT
0.6.15
PINNED: traverse@0.6.9
Pin engines
field to >= 10
FAQs
traverse and transform objects by visiting every node on a recursive walk
The npm package neotraverse receives a total of 376,469 weekly downloads. As such, neotraverse popularity was classified as popular.
We found that neotraverse demonstrated a healthy version release cadence and project activity because the last version was released less than 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
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
Security News
Research
An advanced npm supply chain attack is leveraging Ethereum smart contracts for decentralized, persistent malware control, evading traditional defenses.
Security News
Research
Attackers are impersonating Sindre Sorhus on npm with a fake 'chalk-node' package containing a malicious backdoor to compromise developers' projects.