{"id":14155535,"url":"https://github.com/davidbonnet/astravel","last_synced_at":"2025-05-12T14:29:15.298Z","repository":{"id":36185124,"uuid":"40489297","full_name":"davidbonnet/astravel","owner":"davidbonnet","description":"👟 Tiny and fast ESTree-compliant AST walker and modifier.","archived":false,"fork":false,"pushed_at":"2023-11-10T18:40:25.000Z","size":533,"stargazers_count":62,"open_issues_count":10,"forks_count":5,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-12T14:29:09.459Z","etag":null,"topics":["ast","ast-explorer","ast-traveler","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/davidbonnet.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2015-08-10T15:10:38.000Z","updated_at":"2025-02-20T12:19:43.000Z","dependencies_parsed_at":"2023-01-16T23:14:17.327Z","dependency_job_id":"805ed815-8705-463e-9cd0-c83ed002ca19","html_url":"https://github.com/davidbonnet/astravel","commit_stats":{"total_commits":104,"total_committers":3,"mean_commits":"34.666666666666664","dds":0.07692307692307687,"last_synced_commit":"a468ddce102644a3622260f8a15df987e535f794"},"previous_names":[],"tags_count":30,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidbonnet%2Fastravel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidbonnet%2Fastravel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidbonnet%2Fastravel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidbonnet%2Fastravel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/davidbonnet","download_url":"https://codeload.github.com/davidbonnet/astravel/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253754713,"owners_count":21958898,"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","ast-explorer","ast-traveler","estree","javascript"],"created_at":"2024-08-17T08:03:48.505Z","updated_at":"2025-05-12T14:29:15.272Z","avatar_url":"https://github.com/davidbonnet.png","language":"JavaScript","funding_links":[],"categories":["javascript"],"sub_categories":[],"readme":"# Astravel\n\n[![NPM Version](https://img.shields.io/npm/v/astravel.svg)](https://www.npmjs.org/package/astravel)\n[![Build Status](https://travis-ci.org/davidbonnet/astravel.svg?branch=master)](https://travis-ci.org/davidbonnet/astravel)\n[![Coverage](https://codecov.io/gh/davidbonnet/astravel/branch/master/graph/badge.svg)](https://codecov.io/gh/davidbonnet/astravel)\n[![devDependency Status](https://david-dm.org/davidbonnet/astravel/dev-status.svg)](https://david-dm.org/davidbonnet/astravel#info=devDependencies)\n[![Greenkeeper](https://badges.greenkeeper.io/davidbonnet/astravel.svg)](https://greenkeeper.io/)\n\n👟 A tiny and fast [ESTree](https://github.com/estree/estree)-compliant AST walker and modifier.\n\n### Key features\n\n- Works on [ESTree](https://github.com/estree/estree)-compliant ASTs (JavaScript [version 13 (2022)](https://tc39.github.io/ecma262/)), such as the ones produced by [Meriyah](https://github.com/meriyah/meriyah).\n- Out-of-the-box functions such as source code comments insertion for [Astring](https://github.com/davidbonnet/astring).\n- Extensible with custom nodes.\n- No dependencies and small footprint.\n\n## Installation\n\nInstall with the [Node Package Manager](https://www.npmjs.com/package/astravel):\n\n```bash\nnpm install astravel\n```\n\nAlternatively, checkout this repository and install the development dependencies to build the module file:\n\n```bash\ngit clone https://github.com/davidbonnet/astravel.git\ncd astravel\nnpm install\n```\n\n## Usage\n\nThe `astravel` module exports the following items:\n\n\u003c!-- MarkdownTOC autolink=\"true\" levels=\"4\" --\u003e\n\n- [`defaultTraveler`](#defaulttraveler)\n- [`makeTraveler()`](#maketraveler)\n- [`attachComments()`](#attachcomments)\n\n\u003c!-- /MarkdownTOC --\u003e\n\n#### `defaultTraveler`\n\n\u003e ⬅️ `traveler`\n\n\u003e ⚠️ Deprecated in favor of ES6 class notation.\n\nThis object describes a basic AST traveler. It contains the following methods:\n\n- `go(node, state)`: Travels through the provided AST `node` with a given `state` (an object that can be of any type) by recursively calling this method.\n- `find(predicate, node, state) ➞ { node, state }?`: Returns `{ node, state }` for which `predicate(node, state)` returns truthy, starting at the specified AST `node` and with the provided `state`. Otherwise, returns `undefined`.\n- `[NodeType](node, state)`: Method handler for a specific `NodeType`.\n- `makeChild(properties) ➞ traveler`: Returns a custom AST traveler that inherits from `this` traveler with its own provided `properties` and the property `super` that points to `this` traveler.\n\n#### `makeTraveler()`\n\n\u003e ➡️ `(properties)`\n\u003e ⬅️ `traveler`\n\n\u003e ⚠️ Deprecated in favor of ES6 class notation.\n\nThis function is similar to `astravel.defaultTraveler.makeChild`: it returns a traveler that inherits from the `defaultTraveler` with its own provided `properties` and the property `super` that points to the `defaultTraveler` object. These properties should redefine the traveler's behavior by implementing the `go(node, state)` method and/or any node handler.\n\nWhen redefining the `go` method, make sure its basic functionality is kept by calling the parent's `go` method to keep traveling through the AST:\n\n```javascript\nconst customTraveler = makeTraveler({\n  go: function (node, state) {\n    // Code before entering the node\n    console.log('Entering ' + node.type)\n    // Call the parent's `go` method\n    this.super.go.call(this, node, state)\n    // Code after leaving the node\n    console.log('Leaving ' + node.type)\n  },\n})\n```\n\nTo skip specific node types, the most effective way is to replace the corresponding node handlers with a function that does nothing:\n\n```javascript\nimport { makeTraveler } from 'astravel'\n\nconst ignore = Function.prototype\nconst customTraveler = makeTraveler({\n  FunctionDeclaration: ignore,\n  FunctionExpression: ignore,\n  ArrowFunctionExpression: ignore,\n})\n```\n\n#### `attachComments()`\n\n\u003e ➡️ `(ast, comments)`\n\u003e ⬅️ `ast`\n\nThis function attaches a list of `comments` to the corresponding nodes of a provided `ast` and returns that same `ast`. The `ast` is modified in-place and only the nodes getting comments are augmented with a `comments` and/or a `trailingComments` array property.\n\nEach comment should be an object with the following properties:\n\n- `type`: `\"Line\"` or `\"Block\"`\n- `value`: Comment string value\n- `start`: Comment starting character offset number\n- `end`: Comment ending character offset number\n- `loc`: Location object with `start` and `end` properties containing one-based `line` number and zero-based `column` number properties.\n\nThe following examples show how to obtain a proper list of `comments` of a given source `code` and how to attach them on the generated `ast`:\n\n##### Usage with [Meriyah](https://github.com/meriyah/meriyah)\n\n```javascript\nimport { parse } from 'meriyah'\nimport { attachComments } from 'astravel'\n\nconst comments = []\nconst ast = parse(code, {\n  // Comments are stored in this array\n  onComment: comments,\n})\n// Attach comments on the AST\nattachComments(ast, comments)\n```\n\n##### Usage with [Acorn](https://github.com/acornjs/acorn)\n\n```javascript\nimport { parse } from 'acorn'\nimport { attachComments } from 'astravel'\n\nconst comments = []\nconst ast = parse(code, {\n  // This ensures that the `loc` property is present on comment objects\n  locations: true,\n  onComment: comments,\n})\nattachComments(ast, comments)\n```\n\nThe algorithm assumes that comments are not put in exotic places, such as in-between function arguments, and proceeds as follows:\n\n- For a given statement, it stores all comments right above it and on the same line to it's right side in a `comments` property.\n- If a comment block is at the beginning of a code block, it is attached to that code block.\n- Comments not followed by any statement in a code block are attached as `trailingComments` to that code block.\n\nIn this example, the comments tell to which statement they are attached:\n\n```javascript\n// Attached to the variable declaration just below\nconst point = {\n  // Attached to the property definition just below\n  x: 0,\n  y: 0, // Attached to the property definition on its left\n}\n/*\nAttached to the function declaration just below.\n*/\nfunction add(a, b) {\n  /*\n   Attached to the function body because it is the first comment block.\n   */\n  return a + b // Attached to the return statement on its left\n  // Trailing comment attached as such to the function body\n}\n// Trailing comment attached as such to the program body\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavidbonnet%2Fastravel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdavidbonnet%2Fastravel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavidbonnet%2Fastravel/lists"}