jscodeshift
jscodeshift copied to clipboard
Better way to traverse nodes to find only direct descendants
What would be a good way to traverse down an object tree?
Consider the following file
// menu.js
const menu = {
beverages: {
soft: {
water: 2,
juice: 3,
},
},
happyHour: {
beverages: {
soft: {
water: 1,
juice: 2,
},
},
},
};
How could someone differentiate menu.beverages from menu.happyHour.beverages?
Doing the following codemod
// minimalExample.js
export default (fileInfo, api, options) => {
const j = api.jscodeshift;
const root = j(fileInfo.source);
const rootPaths = root.find(j.VariableDeclarator, {
id: { name: "menu" },
});
rootPaths
.find(j.Property, { key: { name: "beverages" } })
.replaceWith((nodePath) => {
const { node } = nodePath;
console.log(node);
node.key.name = "theFoundBeverage";
return node;
});
return root.toSource();
};
that can be run as
jscodeshift -t minimalExample.js menu.js -d -p
Both beverages would become theFoundBeverage.
Modifying the beverages to have a filter that would traverse a path that would find the first non ObjectExpression node and compare with the root would make only the first one be modified
// minimalExample.js
export default (fileInfo, api, options) => {
const j = api.jscodeshift;
const root = j(fileInfo.source);
const rootPaths = root.find(j.VariableDeclarator, {
id: { name: "menu" },
});
rootPaths
.find(j.Property, { key: { name: "beverages" } })
.filter((path) => isDirectChildOfObject(rootPaths.get(0).node, path))
.replaceWith((nodePath) => {
const { node } = nodePath;
console.log(node);
node.key.name = "theFoundBeverage";
return node;
});
return root.toSource();
};
function isDirectChildOfObject(parent, child) {
let current = child.parentPath;
// Ignoring object expressions
while (current.node && current.node.type === "ObjectExpression") {
current = current.parentPath;
}
return current.node === parent;
}
Is there a better way? I way to say "Given this path only consider if it is a direct child" ?
Thanks in advance
did you figure it out?
did you figure it out?
Not really , the problem just was solved good enough and I gave up...