Skip to content

estools/espurify

Repository files navigation

espurify

Clone AST without extra properties

Build Status NPM version Code Style License

API

const purifiedAstClone = espurify.purifyAst(originalAst)

Returns new clone of originalAst but without extra properties.

Leaves properties defined in The ESTree Spec (formerly known as Mozilla SpiderMonkey Parser API) 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

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.

{
    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

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

const espurify = require('espurify');

AUTHOR

CONTRIBUTORS

LICENSE

Licensed under the MIT license.