{"id":20321374,"url":"https://github.com/retirejs/astronomical","last_synced_at":"2026-03-07T09:21:00.562Z","repository":{"id":220396253,"uuid":"751556675","full_name":"RetireJS/ASTronomical","owner":"RetireJS","description":null,"archived":false,"fork":false,"pushed_at":"2024-12-11T14:02:53.000Z","size":219,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-02T14:50:41.715Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RetireJS.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,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-02-01T20:57:26.000Z","updated_at":"2024-12-11T14:02:14.000Z","dependencies_parsed_at":"2024-02-05T15:05:36.364Z","dependency_job_id":"8607b63b-38bc-4c62-aeb0-3c443a0c9bed","html_url":"https://github.com/RetireJS/ASTronomical","commit_stats":{"total_commits":47,"total_committers":1,"mean_commits":47.0,"dds":0.0,"last_synced_commit":"131a617fba734d2b2a9ce075d210cbd4ca43a3cf"},"previous_names":["eoftedal/babel-q","retirejs/babel-q","retirejs/astronomical"],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RetireJS%2FASTronomical","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RetireJS%2FASTronomical/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RetireJS%2FASTronomical/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RetireJS%2FASTronomical/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RetireJS","download_url":"https://codeload.github.com/RetireJS/ASTronomical/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248339287,"owners_count":21087213,"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":[],"created_at":"2024-11-14T19:14:46.355Z","updated_at":"2026-03-07T09:21:00.519Z","avatar_url":"https://github.com/RetireJS.png","language":"TypeScript","readme":"# ASTronomical\n\n`astronomical` offers a way to query a JavaScript AST to find specific patterns using a syntax somewhat similar to XPath. \n`astronomical` was inspired by [astq](https://github.com/rse/astq), but offers some features that did not seem possible in `astq` and also has some limits compared to `astq`.\n\nGoals:\n\n* Should try to traverse the AST only once when resolving the Query\n* Should allow filtering of nodes\n* Allow running multiple queries at the same time _without traversing the AST multiple times_\n\n## Example\n\n\nThe following pattern:\n```\n//AssignmentExpression[\n      /MemberExpression[\n        /:property/:name == \"migrateVersion\" \u0026\u0026 \n        /$:object == ../../../../:params\n      ]\n    ]/:right/:value\n```\ntries to find the following code snippet and returns the string value assigned to the `migrateVersion` property:\n```\n...\n  function( jQuery, window ) {\n    ...\n    jQuery.migrateVersion = \"3.4.1\";\n    ...\n  }\n...\n```\nFind an AssignmentExpression at arbitrary depth, which directly contains a MemberExpression where the property name is \"migrateVersion\" and\nthe object is bound to a parameter of the surrounding function, an return the assigned value.\n\n## Grammar\n\n* `/\u003cnode type\u003e` - find a child node of the given type\n* `//\u003cnode type\u003e` - find a descendant of the given type\n* `/:\u003cname\u003e` - find an attribute of the current node with the given name\n* `//:\u003cname\u003e` - find an attribute of the current node with the given name regardless of whether it's on the current node or on a descendant\n* `/$:\u003cname\u003e` - find the binding of an Identifier\n* `/$$:\u003cname\u003e` - return the binding or the attribute if binding cannot be resolved (helpful if a variable is sometimes directly assigned and sometimes not)\n* `[]` - apply a filter to the node\n* `\u0026\u0026`, `||` - logical conditions of a filter\n* `==` - comparison in filter\n* `../` - go to parent in filter (use with care, as this causes extra traversal)\n* `/*` - wildcard type child\n* `//*` - wildcard type descendant\n* `'\u003csome value\u003e'`,`\"\u003csome value\u003e\"` - a string literal \n* `/fn:first(selector)` - returns the first result from all matches\n* `/fn:concat(...selectors...)` - concatenates results. If an argument has more than one value, those will be concatenated first.\n* `/fn:join(selector, \",\")` - concatenates the results of a selector with the given separator\n\n## API\n\n* `query(code: string, query: string) : Result[]` - Runs the given query on the given code in the form of an already parsed AST or a string (which is parsed as `sourceType: \"unambiguous\"`), and returns the result.\n* `multiQuery\u003cT extends Record\u003cstring, string\u003e\u003e(code: string, namedQueries: T) : Record\u003ckeyof T, Result[]\u003e` - Runs the given set of named queries on the given code in the form of an already parsed AST or a string (which is parsed as `sourceType: \"unambiguous\"`), and returns a map of named results (one result array per named query).\n\nwhere `Result` is `Babel.Node | string | number | boolean;`\n\n\n## Example code\n\n```\nimport { query } from \"astronomical\";\nimport * as fs from \"fs\";\n\nconst contents = fs.readFileSync(\"some-file.js\");\n\nconst result = query(\n  contents,\n  `//FunctionDeclaration/:id/:name`\n);\n\nconsole.log(\"Function names\", result);\n```\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fretirejs%2Fastronomical","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fretirejs%2Fastronomical","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fretirejs%2Fastronomical/lists"}