{"id":19826870,"url":"https://github.com/estools/espurify","last_synced_at":"2025-04-12T15:39:13.673Z","repository":{"id":18882636,"uuid":"22100186","full_name":"estools/espurify","owner":"estools","description":"Clone AST without extra properties","archived":false,"fork":false,"pushed_at":"2024-12-22T20:58:07.000Z","size":556,"stargazers_count":30,"open_issues_count":1,"forks_count":8,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-03T16:11:44.898Z","etag":null,"topics":["ast","ecmascript","estree","javascript"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/estools.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"MIT-LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-07-22T10:37:23.000Z","updated_at":"2025-01-27T08:09:40.000Z","dependencies_parsed_at":"2025-02-24T16:06:52.845Z","dependency_job_id":"29721059-1527-4219-bc2e-74faf88672e0","html_url":"https://github.com/estools/espurify","commit_stats":{"total_commits":205,"total_committers":5,"mean_commits":41.0,"dds":0.04390243902439028,"last_synced_commit":"38a210159fc8ad1985704b31f1e30a7a5b26345c"},"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/estools%2Fespurify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/estools%2Fespurify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/estools%2Fespurify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/estools%2Fespurify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/estools","download_url":"https://codeload.github.com/estools/espurify/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248590657,"owners_count":21129869,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ast","ecmascript","estree","javascript"],"created_at":"2024-11-12T11:11:52.737Z","updated_at":"2025-04-12T15:39:13.651Z","avatar_url":"https://github.com/estools.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"espurify\n================================\n\nClone AST without extra properties\n\n[![Build Status][ci-image]][ci-url]\n[![NPM version][npm-image]][npm-url]\n[![Code Style][style-image]][style-url]\n[![License][license-image]][license-url]\n\n\nAPI\n---------------------------------------\n\n### const purifiedAstClone = espurify.purifyAst(originalAst)\n\nReturns new clone of `originalAst` but without extra properties.\n\nLeaves 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.\n\n(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)\n\n#### Supported ECMAScript versions\n\n- [ES5](https://github.com/estree/estree/blob/master/es5.md)\n- [ES2015](https://github.com/estree/estree/blob/master/es2015.md)\n- [ES2016](https://github.com/estree/estree/blob/master/es2016.md)\n- [ES2017](https://github.com/estree/estree/blob/master/es2017.md)\n- [ES2018](https://github.com/estree/estree/blob/master/es2018.md)\n- [ES2019](https://github.com/estree/estree/blob/master/es2019.md)\n- [ES2020](https://github.com/estree/estree/blob/master/es2020.md)\n- [ES2021](https://github.com/estree/estree/blob/master/es2021.md)\n- [ES2022](https://github.com/estree/estree/blob/master/es2022.md)\n- ES2023\n- ES2024\n- [ES2025](https://github.com/estree/estree/blob/master/es2025.md)\n\n\n### const customizedCloneFunctionWithAllowList = espurify.cloneWithAllowlist(allowList)\n\nReturns customized function for cloning AST, with user-provided `allowList`.\n\n(note: `espurify.cloneWithWhitelist` is still exported but deprecated in favor of more inclusive language and will be removed in future major releases)\n\n### const purifiedAstClone = customizedCloneFunctionWithAllowList(originalAst)\n\nReturns new clone of `originalAst` by customized function.\n\n\n#### allowList\n\n| type     | default value |\n|:---------|:--------------|\n| `object` | N/A           |\n\n`allowList` is an object containing NodeType as keys and properties as values.\n\n```js\n{\n    ArrayExpression: ['type', 'elements'],\n    ArrayPattern: ['type', 'elements'],\n    ArrowFunctionExpression: ['type', 'id', 'params', 'body', 'generator', 'expression'],\n    AssignmentExpression: ['type', 'operator', 'left', 'right'],\n    ...\n```\n\n\n### const customizedCloneFunction = espurify.customize(options)\n\nReturns customized function for cloning AST, configured by custom `options`.\n\n\n### const purifiedAstClone = customizedCloneFunction(originalAst)\n\nReturns new clone of `originalAst` by customized function.\n\n\n\n#### options\n\n| type     | default value |\n|:---------|:--------------|\n| `object` | `{}`          |\n\nConfiguration options. If not passed, default options will be used.\n\n\n#### options.ecmaVersion\n\n| type                 | default value |\n|:---------------------|:--------------|\n| `string` or `number` | `2025`        |\n\nIndicates the ECMAScript version to clone. Must be either 5, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025.\n\n\n#### options.extra\n\n| type                | default value |\n|:--------------------|:--------------|\n| `array` of `string` | null          |\n\nList 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.\n\n\nEXAMPLE\n---------------------------------------\n\n```javascript\nconst espurify = require('espurify');\nconst estraverse = require('estraverse');\nconst acorn = require('acorn');\nconst syntax = estraverse.Syntax;\nconst assert = require('assert');\n\nconst jsCode = 'assert(\"foo\")';\n\n// Adding extra informations to AST\nconst originalAst = acorn.parse(jsCode, { locations: true, ranges: true, ecmaVersion: 2022 });\nestraverse.replace(originalAst, {\n  leave: function (currentNode, parentNode) {\n    if (currentNode.type === syntax.Literal \u0026\u0026 typeof currentNode.raw !== 'undefined') {\n      currentNode['x-verbatim-bar'] = {\n        content : currentNode.raw,\n        precedence : 18  // escodegen.Precedence.Primary\n      };\n      return currentNode;\n    } else {\n      return undefined;\n    }\n  }\n});\n\n\n// purify AST\nconst purifiedClone = espurify.purifyAst(originalAst);\n\n\n// Extra properties are eliminated from cloned AST\nassert.deepEqual(purifiedClone, {\n  type: 'Program',\n  body: [\n    {\n      type: 'ExpressionStatement',\n      expression: {\n        type: 'CallExpression',\n        callee: {\n          type: 'Identifier',\n          name: 'assert'\n        },\n        arguments: [\n          {\n            type: 'Literal',\n            value: 'foo'\n          }\n        ],\n        optional: false\n      }\n    }\n  ],\n  sourceType: 'script'\n});\n\n\n// original AST is not modified\nassert.deepEqual(originalAst,{\n  type: 'Program',\n  start: 0,\n  end: 13,\n  loc: {\n    start: {\n      line: 1,\n      column: 0\n    },\n    end: {\n      line: 1,\n      column: 13\n    }\n  },\n  range: [\n    0,\n    13\n  ],\n  body: [\n    {\n      type: 'ExpressionStatement',\n      start: 0,\n      end: 13,\n      loc: {\n        start: {\n          line: 1,\n          column: 0\n        },\n        end: {\n          line: 1,\n          column: 13\n        }\n      },\n      range: [\n        0,\n        13\n      ],\n      expression: {\n        type: 'CallExpression',\n        start: 0,\n        end: 13,\n        loc: {\n          start: {\n            line: 1,\n            column: 0\n          },\n          end: {\n            line: 1,\n            column: 13\n          }\n        },\n        range: [\n          0,\n          13\n        ],\n        callee: {\n          type: 'Identifier',\n          start: 0,\n          end: 6,\n          loc: {\n            start: {\n              line: 1,\n              column: 0\n            },\n            end: {\n              line: 1,\n              column: 6\n            }\n          },\n          range: [\n            0,\n            6\n          ],\n          name: 'assert'\n        },\n        arguments: [\n          {\n            type: 'Literal',\n            start: 7,\n            end: 12,\n            loc: {\n              start: {\n                line: 1,\n                column: 7\n              },\n              end: {\n                line: 1,\n                column: 12\n              }\n            },\n            range: [\n              7,\n              12\n            ],\n            value: 'foo',\n            raw: '\"foo\"',\n            \"x-verbatim-bar\": {\n              content: '\"foo\"',\n              precedence: 18\n            }\n          }\n        ],\n        optional: false\n      }\n    }\n  ],\n  sourceType: 'script'\n});\n```\n\n\nINSTALL\n---------------------------------------\n\n### via npm\n\nInstall\n\n    $ npm install --save espurify\n\nUse\n\n```javascript\nconst espurify = require('espurify');\n```\n\n\nAUTHOR\n---------------------------------------\n* [Takuto Wada](https://github.com/twada)\n\n\nCONTRIBUTORS\n---------------------------------------\n* [Renée Kooi](https://github.com/goto-bus-stop)\n* [Andreas Lind](https://github.com/papandreou)\n\n\nLICENSE\n---------------------------------------\nLicensed under the [MIT](https://github.com/estools/espurify/blob/master/MIT-LICENSE.txt) license.\n\n\n[npm-url]: https://npmjs.org/package/espurify\n[npm-image]: https://badge.fury.io/js/espurify.svg\n\n[ci-image]: https://github.com/estools/espurify/workflows/Node.js%20CI/badge.svg\n[ci-url]: https://github.com/estools/espurify/actions?query=workflow%3A%22Node.js+CI%22\n\n[style-url]: https://github.com/Flet/semistandard\n[style-image]: https://img.shields.io/badge/code%20style-semistandard-brightgreen.svg\n\n[license-url]: https://github.com/estools/espurify/blob/master/MIT-LICENSE.txt\n[license-image]: https://img.shields.io/badge/license-MIT-brightgreen.svg\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Festools%2Fespurify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Festools%2Fespurify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Festools%2Fespurify/lists"}