{"id":13452601,"url":"https://github.com/phenomnomnominal/tsquery","last_synced_at":"2025-05-14T12:10:12.650Z","repository":{"id":31900624,"uuid":"130511852","full_name":"phenomnomnominal/tsquery","owner":"phenomnomnominal","description":"TypeScript AST query library","archived":false,"fork":false,"pushed_at":"2025-05-04T22:04:05.000Z","size":812,"stargazers_count":1017,"open_issues_count":12,"forks_count":31,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-05-04T23:22:42.934Z","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":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/phenomnomnominal.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}},"created_at":"2018-04-21T21:03:02.000Z","updated_at":"2025-05-04T22:04:08.000Z","dependencies_parsed_at":"2024-02-04T19:44:16.599Z","dependency_job_id":null,"html_url":"https://github.com/phenomnomnominal/tsquery","commit_stats":{"total_commits":95,"total_committers":11,"mean_commits":8.636363636363637,"dds":"0.34736842105263155","last_synced_commit":"db03c9c5b914e5211aaca219ce8b5857a7a93aac"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phenomnomnominal%2Ftsquery","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phenomnomnominal%2Ftsquery/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phenomnomnominal%2Ftsquery/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phenomnomnominal%2Ftsquery/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phenomnomnominal","download_url":"https://codeload.github.com/phenomnomnominal/tsquery/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254140749,"owners_count":22021219,"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-07-31T07:01:28.834Z","updated_at":"2025-05-14T12:10:07.637Z","avatar_url":"https://github.com/phenomnomnominal.png","language":"TypeScript","funding_links":[],"categories":["TypeScript","Packages","Tools"],"sub_categories":["Optimization"],"readme":"# TSQuery\n\n[![npm version](https://img.shields.io/npm/v/@phenomnomnominal/tsquery.svg)](https://img.shields.io/npm/v/@phenomnomnominal/tsquery.svg)\n\nTSQuery is a port of the ESQuery API for TypeScript! TSQuery allows you to query a TypeScript AST for patterns of syntax using a CSS style selector system. \n\n## Demos:\n\n[ESQuery demo](https://estools.github.io/esquery/) - note that the demo requires JavaScript code, not TypeScript\n[TSQuery demo](https://tsquery-playground.firebaseapp.com) by [Uri Shaked](https://github.com/urish)\n\n## Installation\n\n```sh\nnpm install @phenomnomnominal/tsquery --save-dev\n```\n\n## Examples\n\nSay we want to select all instances of an identifier with name \"Animal\", e.g. the identifier in the `class` declaration, and the identifier in the `extends` declaration.\n\nWe would do something like the following:\n\n```ts\nimport { ast, query } from '@phenomnomnominal/tsquery';\n\nconst typescript = `\n\nclass Animal {\n    constructor(public name: string) { }\n    move(distanceInMeters: number = 0) {\n        console.log(\\`\\${this.name} moved \\${distanceInMeters}m.\\`);\n    }\n}\n\nclass Snake extends Animal {\n    constructor(name: string) { super(name); }\n    move(distanceInMeters = 5) {\n        console.log(\"Slithering...\");\n        super.move(distanceInMeters);\n    }\n}\n\n`;\n\nconst ast = ast(typescript);\nconst nodes = query(ast, 'Identifier[name=\"Animal\"]');\nconsole.log(nodes.length); // 2\n```\n\n### Selectors\n\nThe following selectors are supported:\n\n* AST node type: `ForStatement` (see [common node types](#common-ast-node-types))\n* [wildcard](http://dev.w3.org/csswg/selectors4/#universal-selector): `*`\n* [attribute existence](http://dev.w3.org/csswg/selectors4/#attribute-selectors): `[attr]`\n* [attribute value](http://dev.w3.org/csswg/selectors4/#attribute-selectors): `[attr=\"foo\"]` or `[attr=123]`\n* attribute regex: `[attr=/foo.*/]`\n* attribute conditions: `[attr!=\"foo\"]`, `[attr\u003e2]`, `[attr\u003c3]`, `[attr\u003e=2]`, or `[attr\u003c=3]`\n* nested attribute: `[attr.level2=\"foo\"]`\n* field: `FunctionDeclaration \u003e Identifier.id`\n* [First](http://dev.w3.org/csswg/selectors4/#the-first-child-pseudo) or [last](http://dev.w3.org/csswg/selectors4/#the-last-child-pseudo) child: `:first-child` or `:last-child`\n* [nth-child](http://dev.w3.org/csswg/selectors4/#the-nth-child-pseudo) (no ax+b support): `:nth-child(2)`\n* [nth-last-child](http://dev.w3.org/csswg/selectors4/#the-nth-last-child-pseudo) (no ax+b support): `:nth-last-child(1)`\n* [descendant](http://dev.w3.org/csswg/selectors4/#descendant-combinators): `ancestor descendant`\n* [child](http://dev.w3.org/csswg/selectors4/#child-combinators): `parent \u003e child`\n* [following sibling](http://dev.w3.org/csswg/selectors4/#general-sibling-combinators): `node ~ sibling`\n* [adjacent sibling](http://dev.w3.org/csswg/selectors4/#adjacent-sibling-combinators): `node + adjacent`\n* [negation](http://dev.w3.org/csswg/selectors4/#negation-pseudo): `:not(ForStatement)`\n* [matches-any](http://dev.w3.org/csswg/selectors4/#matches): `:matches([attr] \u003e :first-child, :last-child)`\n* [has](https://drafts.csswg.org/selectors-4/#has-pseudo): `IfStatement:has([name=\"foo\"])`\n* class of AST node: `:statement`, `:expression`, `:declaration`, `:function`, or `:pattern`\n\n### Common AST node types\n\n* `Identifier` - any identifier (name of a function, class, variable, etc)\n* `IfStatement`, `ForStatement`, `WhileStatement`, `DoStatement` - control flow\n* `FunctionDeclaration`, `ClassDeclaration`, `ArrowFunction` - declarations\n* `VariableStatement` - var, const, let.\n* `ImportDeclaration` - any `import` statement\n* `StringLiteral` - any string\n* `TrueKeyword`, `FalseKeyword`, `NullKeyword`, `AnyKeyword` - various keywords\n* `CallExpression` - function call\n* `NumericLiteral` - any numeric constant\n* `NoSubstitutionTemplateLiteral`, `TemplateExpression` - template strings and expressions\n\n## API:\n\n### `ast`:\n\nParse a string of code into an Abstract Syntax Tree which can then be queried with TSQuery Selectors.\n\n```typescript\nimport { ast } from '@phenomnomnominal/tsquery';\n\nconst sourceFile = ast('const x = 1;');\n```\n\n### `includes`:\n\nCheck for `Nodes` within a given `string` of code or AST `Node` matching a `Selector`.\n\n```typescript\nimport { includes } from '@phenomnomnominal/tsquery';\n\nconst hasIdentifier = includes('const x = 1;', 'Identifier');\n```\n\n### `map`:\n\nTransform AST `Nodes` within a given `Node` matching a `Selector`. Can be used to do `Node`-based replacement or removal of parts of the input AST.\n\n```typescript\nimport { factory } from 'typescript';\nimport { map } from '@phenomnomnominal/tsquery';\n\nconst tree = ast('const x = 1;')\nconst updatedTree = map(tree, 'Identifier', () =\u003e factory.createIdentifier('y'));\n```\n\n### `match`:\n\nFind AST `Nodes` within a given AST `Node` matching a `Selector`.\n\n```typescript\nimport { ast, match } from '@phenomnomnominal/tsquery';\n\nconst tree = ast('const x = 1;')\nconst [xNode] = match(tree, 'Identifier');\n```\n\n### `parse`:\n\nParse a `string` into an [ESQuery](https://github.com/estools/esquery) `Selector`.\n\n```typescript\nimport { parse } from '@phenomnomnominal/tsquery';\n\nconst selector = parse(':matches([attr] \u003e :first-child, :last-child)');\n```\n\n### `print`:\n\nPrint a given `Node` or `SourceFile` to a string, using the default TypeScript printer.\n\n```typescript\nimport { print } from '@phenomnomnominal/tsquery';\nimport { factory } from 'typescript';\n\n  // create synthetic node:\nconst node = factory.createArrowFunction(\n  // ...\n);\nconst code = print(node);\n```\n\n### `project`:\n\nGet all the `SourceFiles` included in a the TypeScript project described by a given config file.\n\n```typescript\nimport { project } from '@phenomnomnominal/tsquery';\n\nconst files = project('./tsconfig.json');\n```\n\n### `files`:\n\nGet all the file paths included ina the TypeScript project described by a given config file.\n\n```typescript\nimport { files } from '@phenomnomnominal/tsquery';\n\nconst filePaths = files('./tsconfig.json');\n```\n\n### `match`:\n\nFind AST `Nodes` within a given `string` of code or AST `Node` matching a `Selector`.\n\n```typescript\nimport {query } from '@phenomnomnominal/tsquery';\n\nconst [xNode] = query('const x = 1;', 'Identifier');\n```\n\n### `replace`:\n\nTransform AST `Nodes` within a given `Node` matching a `Selector`. Can be used to do string-based replacement or removal of parts of the input AST. The updated code will be printed with the TypeScript [`Printer`](https://github.com/microsoft/TypeScript-wiki/blob/main/Using-the-Compiler-API.md#creating-and-printing-a-typescript-ast), so you may need to run your own formatter on any output code.\n\n```typescript\nimport { replace } from '@phenomnomnominal/tsquery';\n\nconst updatedCode = replace('const x = 1;', 'Identifier', () =\u003e 'y'));\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphenomnomnominal%2Ftsquery","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphenomnomnominal%2Ftsquery","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphenomnomnominal%2Ftsquery/lists"}