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.
@putout/operate
Advanced tools
Manipulate with path
nodes and keep comments
and loc
information.
npm i @putout/operate
If you write plugin for putout
you already have operator
in putout
, all exampes will get operator
from putout
, but you can use direct require('@putout/operate')
as well.
rename
Let's suppose you have code
const {hello} = one;
hello();
You want to change to:
const {world} = one;
world();
Use:
rename(path, 'hello', 'world');
renameProperty
Let's suppose you have code
const {hello: world} = one;
You want to change to:
const {world} = one;
Use:
renameProperty(path, 'hello', 'world');
setLiteralValue(path: Path | Node, value: string)
Set raw
and value
of a literal.
isSimple(path: Path | Node)
Check if path is:
Literal
;Identifier
;MemberExpression
;OptionalMemberExpression
;extract(path)
Extract node value according to it's type::
Identifier
or JSXIdentifier
or JSXAttribute
return name
;Literal
or JSXText
return value
;RegExp
return pattern
;TemplateLiteral
return qusis[0].value.raw
;TemplateElement
return value.raw
;ClassMethod
return key
;TSTypeReference
return typeName.name
;TSTypeParameter
return name
;MemberExpression
return object.property
;ArrayExpression
return element1,element2,...,elementN
;throw
in other casesinsertAfter(path, node)
Safe way to insert node
after path
without duplicating comments.
insertBefore(path, node)
Safe way to insert node
before path
.
replaceWith(path, node)
const {operator, types} = require('putout');
const {replaceWith} = operator;
const {ContinueStatement} = types;
replaceWith(path, ContinueStatement());
replaceWithMultiple(path, nodes)
const {operator, types} = require('putout');
const {replaceWithMultiple} = operator;
const {
ExpressionStatement,
ContinueStatement,
} = types;
replaceWithMultiple(path, [
ExpressionStatement(path.node.argument),
ContinueStatement,
]);
isModuleExports(path)
Check if currentPath is module.exports
expression.
toExpression(node)
Can be used to convert node to expression
when building new nodes.
remove(path)
Remove node
, preserve comments.
path.toString();
// returns const [a, b] = c;
remove(path.get('declarations.0.id.0'));
path.toString(); // returns const [, b] = c;
getLiteralRaw(path: Path|Node)
Get raw
or extra.raw
, which can be received from template
methods.
getPathAfterRequires(body)
Get next path
after latest require
:
const programPath = path.scope.getProgramParent().path;
const afterRequirePath = getPathAfterRequires(programPath.get('body'));
getPathAfterImports(body)
Get next path
after latest ImportDeclaration
:
const programPath = path.scope.getProgramParent().path;
const afterImportsPath = getPathAfterImports(programPath.get('body'));
getBinding(path, name: string | Node)
Get binding (declaration of variable) by name using starting from path
and move up.
getBinding(path, 'hello');
getBindingPath(path, name: string | Node)
Get binding path
by name using starting from path
and move up.
const bindingPath = getBindingPath(path, 'hello');
module.exports.match = () => ({
'typeof __a === "__b"': ({__a}, path) => {
// when __a declared proceed to replace
return getBindingPath(path, __a);
},
});
compute(path)
Computes value of expression:
For code
like this:
const bodies = {
function: `typeof __a === 'function'`,
};
module.exports.replace = () => ({
[bodies.function]: 'isFn(__a)',
});
You can compute value of bodies.function
:
const {parse, operator} = require('putout');
const {traverse, compute} = operator;
traverse({
'__a.__b': (path) => {
const [computed, value] = compute(path);
// returns
[true, `typeof __a === 'function'`];
},
});
getExportDefault(path)
Get export default
or null.
isESM(path)
Check if given source is ESM
search for ImportDeclaration
and ExportDeclaration
nodes.
getProperty(path: Path, name: string)
Get property from ObjectExpression
path:
const homepagePath = getProperty(__aPath, 'homepage');
getProperties(path: Path, names: string[])
Get properties from ObjectExpression
path and add a Path
suffix to each result:
const {homepagePath} = getProperties(__aPath, ['homepage']);
traverseProperties(path: Path | Node, name: string, {firstLevel?: false})
Traverse list of properties from ObjectExpression
.
const object = template.ast('x({"a": "b"})');
const [propertyPath] = traverseProperties(object, 'a');
MIT
FAQs
Operate on AST for 🐊 Putout
We found that @putout/operate 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
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.