https://github.com/synvert-hq/node-mutation-javascript
It provides a set of APIs to rewrite AST node source code.
https://github.com/synvert-hq/node-mutation-javascript
Last synced: 6 months ago
JSON representation
It provides a set of APIs to rewrite AST node source code.
- Host: GitHub
- URL: https://github.com/synvert-hq/node-mutation-javascript
- Owner: synvert-hq
- Created: 2022-06-11T07:58:02.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2025-03-10T04:29:09.000Z (10 months ago)
- Last Synced: 2025-04-09T23:47:02.344Z (9 months ago)
- Language: TypeScript
- Homepage: https://xinminlabs.github.io/node-mutation-javascript/
- Size: 1.69 MB
- Stars: 2
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
Awesome Lists containing this project
README
[](https://badge.fury.io/js/@synvert-hq%2Fnode-mutation)
[](https://github.com/synvert-hq/node-mutation-javascript/actions/workflows/main.yml)
# NodeMutation
NodeMutation provides a set of APIs to rewrite node source code.
## Table of Contents
- [NodeMutation](#nodemutation)
- [Table of Contents](#table-of-contents)
- [Installation](#installation)
- [Usage](#usage)
- [Evaluated Value](#evaluated-value)
- [Configuration](#configuration)
- [adapter](#adapter)
- [strategy](#strategy)
- [tabWidth](#tabwidth)
- [Contributing Guide](#contributing-guide)
## Installation
Install NodeMutation using npm:
```
npm install --save @synvert-hq/node-mutation
```
Or yarn;
```
yarn add @synvert-hq/node-mutation
```
## Usage
1. initialize the NodeMutation instance:
```typescript
import { Node } from "typescript"
mutation = new NodeMutation(filePath: string, source: string, { adapter: "typescript" | "espree" | "gonzales-pe" })
```
2. call the rewrite apis:
```typescript
// append the code to the current node.
mutation.append(node: Node, code: string)
// delete source code of the child ast node
mutation.delete(node: Node, selectors: string | string[], options: DeleteOptions)
// insert code to the ast node.
mutation.insert(node: Node, code: string, options: InsertOptions)
// prepend code to the ast node.
mutation.prepend(node: Node, code: string)
// remove source code of the ast node
mutation.remove(node: Node, options: RemoveOptions)
// replace child node of the ast node with new code
mutation.replace(node: Node, selectors: string | string[], options: ReplaceOptions)
// replace the ast node with new code
mutation.replaceWith(node: Node, code: string)
// indent the ast node.
mutation.indent(node: Node, options: IndentOptions)
// no operation
mutation.noop(node: Node)
// group actions
mutation.group(() => {
mutation.delete(node: Node, selectors: string | string[], options: DeleteOptions)
mutation.insert(node: Node, code: string, options: InsertOptions)
})
// wrap the ast node
mutation.wrap(node: Node, options: WrapOptions)
```
3. process actions and write the new source code to file:
```typescript
mutation.process()
```
## Evaluated Value
NodeMutation supports to evaluate the value of the node, and use the evaluated value to rewrite the source code.
```ruby
source = 'class Synvert {}'
node = espree.parse(source)
mutation.replace node, '{{id}}', with: 'Foobar'
source # class Foobar {}
```
See more in [TypescriptAdapter](https://synvert-hq.github.io/node-mutation-javascript/TypescriptAdapter.html), [SyntaxTreeAdapter](https://synvert-hq.github.io/node-mutation-javascript/EspreeAdapter.html), and [GonzalesPeAdapter](https://synvert-hq.github.io/node-mutation-javascript/GonzalesPeAdapter.html)
## Configuration
### adapter
Different parsers, like typescript and espree, will generate different AST nodes, to make NodeMutation work for them all,
we define an [Adapter](https://github.com/synvert-hq/node-mutation-javascript/blob/main/src/adapter.ts) interface,
if you implement the Adapter interface, you can set it as NodeMutation's adapter.
It provides 3 adapters:
1. `TypescriptAdapter`
2. `EspreeAdapter`
3. `GonzalesPeAdapter`
```typescript
NodeMutation.configure({ adapter: new EspreeAdapter() }); // default is TypescriptAdapter
```
### strategy
It provides 2 strategies to handle conflicts when processing actions:
1. `Strategy.KEEP_RUNNING`: keep running and ignore the conflict action.
2. `Strategy.THROW_ERROR`: throw error when conflict action is found.
```typescript
NodeMutation.configure({ strategy: Strategy.KEEP_RUNNING }); // default is Strategy.THROW_ERROR
```
### tabWidth
```typescript
NodeMutation.configure({ tabWidth: 4 }); // default is 2
```
## Contributing Guide
1. Fork and clone the repo.
2. Run `npm install` to install dependencies.
3. Run `npm run test` or `npm run watch:test` to run tests.
4. Make some changes and make tests all passed.
5. Push the changes to the repo.