# espurify

> Clone AST without extra properties

Latest version **3.2.0** (published 2024-12-22) · MIT license · 0 weekly downloads

## Install

```sh
npm install espurify
pnpm add espurify
yarn add espurify
bun add espurify
```

## Health

**Score 35/100 (D)** — status: stable.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: stale.

## Facts

| | |
|---|---|
| Version | 3.2.0 |
| Published | 2024-12-22 |
| First published | 2014-07-22 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 0 |
| Unpacked size | 44.6 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 31 |
| Author | Takuto Wada |
| Maintainers | twada |
| Keywords | ast, estree, ecmascript, es6 |

## Links

- npm: https://www.npmjs.com/package/espurify
- Repository: https://github.com/estools/espurify
- Issues: https://github.com/estools/espurify/issues
- npm.io page: https://npm.io/package/espurify

## Alternatives

- [update-check](https://npm.io/package/update-check.md) — 4.0M weekly downloads
- [react-native-onesignal](https://npm.io/package/react-native-onesignal.md) — 134.5K weekly downloads
- [react-redux-toastr](https://npm.io/package/react-redux-toastr.md) — 33.7K weekly downloads
- [@nocobase/plugin-notification-manager](https://npm.io/package/@nocobase/plugin-notification-manager.md) — 2.0K weekly downloads
- [react-simple-toasts](https://npm.io/package/react-simple-toasts.md) — 1.9K weekly downloads

## Recent versions

- 3.2.0 (latest) — 2024-12-22
- 3.1.0 — 2024-07-03
- 3.0.0 — 2022-07-17
- 2.1.1 — 2021-03-29
- 2.1.0 — 2021-03-25
- 2.0.1 — 2019-02-15
- 2.0.0 — 2018-11-23
- 1.8.1 — 2018-07-10
- 1.8.0 — 2018-05-10
- 1.7.0 — 2017-02-24
- 1.6.1 — 2017-02-13
- 1.6.0 — 2016-05-25
- 1.5.1 — 2016-03-28
- 1.5.0 — 2015-12-21
- 1.4.0 — 2015-12-18
- … 9 more at https://npm.io/package/espurify/versions

## README

espurify
================================

Clone AST without extra properties

[![Build Status][ci-image]][ci-url]
[![NPM version][npm-image]][npm-url]
[![Code Style][style-image]][style-url]
[![License][license-image]][license-url]


API
---------------------------------------

### const purifiedAstClone = espurify.purifyAst(originalAst)

Returns new clone of `originalAst` but without extra properties.

Leaves properties defined in [The ESTree Spec](https://github.com/estree/estree) (formerly known as [Mozilla SpiderMonkey Parser API](https://speakerdeck.com/michaelficarra/spidermonkey-parser-api-a-standard-for-structured-js-representations)) only. Also note that extra informations (such as `loc`, `range` and `raw`) are eliminated too.

(note: using `espurify` as a default exported function is deprecated in favor of named exports aiming ESM era, and will be removed in future major releases)

#### Supported ECMAScript versions

- [ES5](https://github.com/estree/estree/blob/master/es5.md)
- [ES2015](https://github.com/estree/estree/blob/master/es2015.md)
- [ES2016](https://github.com/estree/estree/blob/master/es2016.md)
- [ES2017](https://github.com/estree/estree/blob/master/es2017.md)
- [ES2018](https://github.com/estree/estree/blob/master/es2018.md)
- [ES2019](https://github.com/estree/estree/blob/master/es2019.md)
- [ES2020](https://github.com/estree/estree/blob/master/es2020.md)
- [ES2021](https://github.com/estree/estree/blob/master/es2021.md)
- [ES2022](https://github.com/estree/estree/blob/master/es2022.md)
- ES2023
- ES2024
- [ES2025](https://github.com/estree/estree/blob/master/es2025.md)


### const customizedCloneFunctionWithAllowList = espurify.cloneWithAllowlist(allowList)

Returns customized function for cloning AST, with user-provided `allowList`.

(note: `espurify.cloneWithWhitelist` is still exported but deprecated in favor of more inclusive language and will be removed in future major releases)

### const purifiedAstClone = customizedCloneFunctionWithAllowList(originalAst)

Returns new clone of `originalAst` by customized function.


#### allowList

| type     | default value |
|:---------|:--------------|
| `object` | N/A           |

`allowList` is an object containing NodeType as keys and properties as values.

```js
{
    ArrayExpression: ['type', 'elements'],
    ArrayPattern: ['type', 'elements'],
    ArrowFunctionExpression: ['type', 'id', 'params', 'body', 'generator', 'expression'],
    AssignmentExpression: ['type', 'operator', 'left', 'right'],
    ...
```


### const customizedCloneFunction = espurify.customize(options)

Returns customized function for cloning AST, configured by custom `options`.


### const purifiedAstClone = customizedCloneFunction(originalAst)

Returns new clone of `originalAst` by customized function.



#### options

| type     | default value |
|:---------|:--------------|
| `object` | `{}`          |

Configuration options. If not passed, default options will be used.


#### options.ecmaVersion

| type                 | default value |
|:---------------------|:--------------|
| `string` or `number` | `2025`        |

Indicates the ECMAScript version to clone. Must be either 5, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025.


#### options.extra

| type                | default value |
|:--------------------|:--------------|
| `array` of `string` | null          |

List of extra properties to be left in result AST. For example, functions returned by `espurify.customize({extra: ['raw']})` will preserve `raw` properties of `Literal`. Functions return by `espurify.customize({extra: ['loc', 'range']})` will preserve `loc` and `range` properties of each Node.


EXAMPLE
---------------------------------------

```javascript
const espurify = require('espurify');
const estraverse = require('estraverse');
const acorn = require('acorn');
const syntax = estraverse.Syntax;
const assert = require('assert');

const jsCode = 'assert("foo")';

// Adding extra informations to AST
const originalAst = acorn.parse(jsCode, { locations: true, ranges: true, ecmaVersion: 2022 });
estraverse.replace(originalAst, {
  leave: function (currentNode, parentNode) {
    if (currentNode.type === syntax.Literal && typeof currentNode.raw !== 'undefined') {
      currentNode['x-verbatim-bar'] = {
        content : currentNode.raw,
        precedence : 18  // escodegen.Precedence.Primary
      };
      return currentNode;
    } else {
      return undefined;
    }
  }
});


// purify AST
const purifiedClone = espurify.purifyAst(originalAst);


// Extra properties are eliminated from cloned AST
assert.deepEqual(purifiedClone, {
  type: 'Program',
  body: [
    {
      type: 'ExpressionStatement',
      expression: {
        type: 'CallExpression',
        callee: {
          type: 'Identifier',
          name: 'assert'
        },
        arguments: [
          {
            type: 'Literal',
            value: 'foo'
          }
        ],
        optional: false
      }
    }
  ],
  sourceType: 'script'
});


// original AST is not modified
assert.deepEqual(originalAst,{
  type: 'Program',
  start: 0,
  end: 13,
  loc: {
    start: {
      line: 1,
      column: 0
    },
    end: {
      line: 1,
      column: 13
    }
  },
  range: [
    0,
    13
  ],
  body: [
    {
      type: 'ExpressionStatement',
      start: 0,
      end: 13,
      loc: {
        start: {
          line: 1,
          column: 0
        },
        end: {
          line: 1,
          column: 13
        }
      },
      range: [
        0,
        13
      ],
      expression: {
        type: 'CallExpression',
        start: 0,
        end: 13,
        loc: {
          start: {
            line: 1,
            column: 0
          },
          end: {
            line: 1,
            column: 13
          }
        },
        range: [
          0,
          13
        ],
        callee: {
          type: 'Identifier',
          start: 0,
          end: 6,
          loc: {
            start: {
              line: 1,
              column: 0
            },
            end: {
              line: 1,
              column: 6
            }
          },
          range: [
            0,
            6
          ],
          name: 'assert'
        },
        arguments: [
          {
            type: 'Literal',
            start: 7,
            end: 12,
            loc: {
              start: {
                line: 1,
                column: 7
              },
              end: {
                line: 1,
                column: 12
              }
            },
            range: [
              7,
              12
            ],
            value: 'foo',
            raw: '"foo"',
            "x-verbatim-bar": {
              content: '"foo"',
              precedence: 18
            }
          }
        ],
        optional: false
      }
    }
  ],
  sourceType: 'script'
});
```


INSTALL
---------------------------------------

### via npm

Install

    $ npm install --save espurify

Use

```javascript
const espurify = require('espurify');
```


AUTHOR
---------------------------------------
* [Takuto Wada](https://github.com/twada)


CONTRIBUTORS
---------------------------------------
* [Renée Kooi](https://github.com/goto-bus-stop)
* [Andreas Lind](https://github.com/papandreou)


LICENSE
---------------------------------------
Licensed under the [MIT](https://github.com/estools/espurify/blob/master/MIT-LICENSE.txt) license.


[npm-url]: https://npmjs.org/package/espurify
[npm-image]: https://badge.fury.io/js/espurify.svg

[ci-image]: https://github.com/estools/espurify/workflows/Node.js%20CI/badge.svg
[ci-url]: https://github.com/estools/espurify/actions?query=workflow%3A%22Node.js+CI%22

[style-url]: https://github.com/Flet/semistandard
[style-image]: https://img.shields.io/badge/code%20style-semistandard-brightgreen.svg

[license-url]: https://github.com/estools/espurify/blob/master/MIT-LICENSE.txt
[license-image]: https://img.shields.io/badge/license-MIT-brightgreen.svg

---
_Source: https://npm.io/package/espurify · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
