Project Init

This commit is contained in:
Muluhabt
2026-05-29 15:23:46 +03:00
commit 2fbc557aac
67387 changed files with 6063341 additions and 0 deletions

21
node_modules/@phenomnomnominal/tsquery/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 Craig Spence
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

196
node_modules/@phenomnomnominal/tsquery/README.md generated vendored Normal file
View File

@@ -0,0 +1,196 @@
# TSQuery
[![npm version](https://img.shields.io/npm/v/@phenomnomnominal/tsquery.svg)](https://img.shields.io/npm/v/@phenomnomnominal/tsquery.svg)
TSQuery 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.
## Demos:
[ESQuery demo](https://estools.github.io/esquery/) - note that the demo requires JavaScript code, not TypeScript
[TSQuery demo](https://tsquery-playground.firebaseapp.com) by [Uri Shaked](https://github.com/urish)
## Installation
```sh
npm install @phenomnomnominal/tsquery --save-dev
```
## Examples
Say 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.
We would do something like the following:
```ts
import { ast, query } from '@phenomnomnominal/tsquery';
const typescript = `
class Animal {
constructor(public name: string) { }
move(distanceInMeters: number = 0) {
console.log(\`\${this.name} moved \${distanceInMeters}m.\`);
}
}
class Snake extends Animal {
constructor(name: string) { super(name); }
move(distanceInMeters = 5) {
console.log("Slithering...");
super.move(distanceInMeters);
}
}
`;
const tree = ast(typescript);
const nodes = query(tree, 'Identifier[name="Animal"]');
console.log(nodes.length); // 2
```
### Selectors
The following selectors are supported:
* AST node type: `ForStatement` (see [common node types](#common-ast-node-types))
* [wildcard](http://dev.w3.org/csswg/selectors4/#universal-selector): `*`
* [attribute existence](http://dev.w3.org/csswg/selectors4/#attribute-selectors): `[attr]`
* [attribute value](http://dev.w3.org/csswg/selectors4/#attribute-selectors): `[attr="foo"]` or `[attr=123]`
* attribute regex: `[attr=/foo.*/]`
* attribute conditions: `[attr!="foo"]`, `[attr>2]`, `[attr<3]`, `[attr>=2]`, or `[attr<=3]`
* nested attribute: `[attr.level2="foo"]`
* field: `FunctionDeclaration > Identifier.id`
* [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`
* [nth-child](http://dev.w3.org/csswg/selectors4/#the-nth-child-pseudo) (no ax+b support): `:nth-child(2)`
* [nth-last-child](http://dev.w3.org/csswg/selectors4/#the-nth-last-child-pseudo) (no ax+b support): `:nth-last-child(1)`
* [descendant](http://dev.w3.org/csswg/selectors4/#descendant-combinators): `ancestor descendant`
* [child](http://dev.w3.org/csswg/selectors4/#child-combinators): `parent > child`
* [following sibling](http://dev.w3.org/csswg/selectors4/#general-sibling-combinators): `node ~ sibling`
* [adjacent sibling](http://dev.w3.org/csswg/selectors4/#adjacent-sibling-combinators): `node + adjacent`
* [negation](http://dev.w3.org/csswg/selectors4/#negation-pseudo): `:not(ForStatement)`
* [matches-any](http://dev.w3.org/csswg/selectors4/#matches): `:matches([attr] > :first-child, :last-child)`
* [has](https://drafts.csswg.org/selectors-4/#has-pseudo): `IfStatement:has([name="foo"])`
* class of AST node: `:statement`, `:expression`, `:declaration`, `:function`, or `:pattern`
### Common AST node types
* `Identifier` - any identifier (name of a function, class, variable, etc)
* `IfStatement`, `ForStatement`, `WhileStatement`, `DoStatement` - control flow
* `FunctionDeclaration`, `ClassDeclaration`, `ArrowFunction` - declarations
* `VariableStatement` - var, const, let.
* `ImportDeclaration` - any `import` statement
* `StringLiteral` - any string
* `TrueKeyword`, `FalseKeyword`, `NullKeyword`, `AnyKeyword` - various keywords
* `CallExpression` - function call
* `NumericLiteral` - any numeric constant
* `NoSubstitutionTemplateLiteral`, `TemplateExpression` - template strings and expressions
## API:
### `ast`:
Parse a string of code into an Abstract Syntax Tree which can then be queried with TSQuery Selectors.
```typescript
import { ast } from '@phenomnomnominal/tsquery';
const sourceFile = ast('const x = 1;');
```
### `includes`:
Check for `Nodes` within a given `string` of code or AST `Node` matching a `Selector`.
```typescript
import { includes } from '@phenomnomnominal/tsquery';
const hasIdentifier = includes('const x = 1;', 'Identifier');
```
### `map`:
Transform 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.
```typescript
import { factory } from 'typescript';
import { map } from '@phenomnomnominal/tsquery';
const tree = ast('const x = 1;')
const updatedTree = map(tree, 'Identifier', () => factory.createIdentifier('y'));
```
### `match`:
Find AST `Nodes` within a given AST `Node` matching a `Selector`.
```typescript
import { ast, match } from '@phenomnomnominal/tsquery';
const tree = ast('const x = 1;')
const [xNode] = match(tree, 'Identifier');
```
### `parse`:
Parse a `string` into an [ESQuery](https://github.com/estools/esquery) `Selector`.
```typescript
import { parse } from '@phenomnomnominal/tsquery';
const selector = parse(':matches([attr] > :first-child, :last-child)');
```
### `print`:
Print a given `Node` or `SourceFile` to a string, using the default TypeScript printer.
```typescript
import { print } from '@phenomnomnominal/tsquery';
import { factory } from 'typescript';
// create synthetic node:
const node = factory.createArrowFunction(
// ...
);
const code = print(node);
```
### `project`:
Get all the `SourceFiles` included in a the TypeScript project described by a given config file.
```typescript
import { project } from '@phenomnomnominal/tsquery';
const files = project('./tsconfig.json');
```
### `files`:
Get all the file paths included ina the TypeScript project described by a given config file.
```typescript
import { files } from '@phenomnomnominal/tsquery';
const filePaths = files('./tsconfig.json');
```
### `match`:
Find AST `Nodes` within a given `string` of code or AST `Node` matching a `Selector`.
```typescript
import {query } from '@phenomnomnominal/tsquery';
const [xNode] = query('const x = 1;', 'Identifier');
```
### `replace`:
Transform 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.
```typescript
import { replace } from '@phenomnomnominal/tsquery';
const updatedCode = replace('const x = 1;', 'Identifier', () => 'y'));
```

View File

@@ -0,0 +1,18 @@
import type { Node, SourceFile } from './index';
import { ScriptKind } from './index';
/**
* @public
* Parse a string of code into an Abstract Syntax Tree which can then be queried with TSQuery Selectors.
*
* @param source - the code that should be parsed into a [`SourceFile`](https://github.com/microsoft/TypeScript/blob/main/src/services/types.ts#L159). A `SourceFile` is the TypeScript implementation of an Abstract Syntax Tree (with extra details).
* @param fileName - a name (if known) for the `SourceFile`. Defaults to empty string.
* @param scriptKind - the TypeScript [`ScriptKind`](https://github.com/microsoft/TypeScript/blob/main/src/compiler/types.ts#L7305) of the code. Defaults to `ScriptKind.TSX`. Set this to `ScriptKind.TS` if your code uses the `<Type>` syntax for casting.
* @returns a TypeScript `SourceFile`.
*/
export declare function ast(source: string, fileName?: string, scriptKind?: ScriptKind): SourceFile;
export declare namespace ast {
var ensure: {
(code: string, scriptKind: ScriptKind): Node;
(code: Node): Node;
};
}

26
node_modules/@phenomnomnominal/tsquery/dist/src/ast.js generated vendored Normal file
View File

@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ast = void 0;
const typescript_1 = require("typescript");
const index_1 = require("./index");
/**
* @public
* Parse a string of code into an Abstract Syntax Tree which can then be queried with TSQuery Selectors.
*
* @param source - the code that should be parsed into a [`SourceFile`](https://github.com/microsoft/TypeScript/blob/main/src/services/types.ts#L159). A `SourceFile` is the TypeScript implementation of an Abstract Syntax Tree (with extra details).
* @param fileName - a name (if known) for the `SourceFile`. Defaults to empty string.
* @param scriptKind - the TypeScript [`ScriptKind`](https://github.com/microsoft/TypeScript/blob/main/src/compiler/types.ts#L7305) of the code. Defaults to `ScriptKind.TSX`. Set this to `ScriptKind.TS` if your code uses the `<Type>` syntax for casting.
* @returns a TypeScript `SourceFile`.
*/
function ast(source, fileName = '', scriptKind = index_1.ScriptKind.TSX) {
return (0, typescript_1.createSourceFile)(fileName || '', source, typescript_1.ScriptTarget.Latest, true, scriptKind);
}
exports.ast = ast;
function ensure(code, scriptKind) {
return isNode(code) ? code : ast(code, '', scriptKind);
}
ast.ensure = ensure;
function isNode(node) {
return !!node.getSourceFile;
}
//# sourceMappingURL=ast.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ast.js","sourceRoot":"","sources":["../../src/ast.ts"],"names":[],"mappings":";;;AAEA,2CAA4D;AAC5D,mCAAqC;AAErC;;;;;;;;GAQG;AACH,SAAgB,GAAG,CACjB,MAAc,EACd,QAAQ,GAAG,EAAE,EACb,UAAU,GAAG,kBAAU,CAAC,GAAG;IAE3B,OAAO,IAAA,6BAAgB,EACrB,QAAQ,IAAI,EAAE,EACd,MAAM,EACN,yBAAY,CAAC,MAAM,EACnB,IAAI,EACJ,UAAU,CACX,CAAC;AACJ,CAAC;AAZD,kBAYC;AAYD,SAAS,MAAM,CAAC,IAAmB,EAAE,UAAuB;IAC1D,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC;AACzD,CAAC;AACD,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC;AAEpB,SAAS,MAAM,CAAC,IAAa;IAC3B,OAAO,CAAC,CAAE,IAAa,CAAC,aAAa,CAAC;AACxC,CAAC"}

View File

@@ -0,0 +1,11 @@
/// <reference types="esquery" />
import type { Node, Selector } from './index';
/**
* @public
* Check for `Nodes` within a given `string` of code or AST `Node` matching a `Selector`.
*
* @param node - the `Node` to be searched. This could be a TypeScript [`SourceFile`](https://github.com/microsoft/TypeScript/blob/main/src/services/types.ts#L159), or a `Node` from a previous query.
* @param selector - a TSQuery `Selector` (using the [ESQuery selector syntax](https://github.com/estools/esquery)).
* @returns `true` if the code contains matches for the `Selector`, `false` if not.
*/
export declare function includes(node: Node, selector: string | Selector): boolean;

View File

@@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.includes = void 0;
const index_1 = require("./index");
/**
* @public
* Check for `Nodes` within a given `string` of code or AST `Node` matching a `Selector`.
*
* @param node - the `Node` to be searched. This could be a TypeScript [`SourceFile`](https://github.com/microsoft/TypeScript/blob/main/src/services/types.ts#L159), or a `Node` from a previous query.
* @param selector - a TSQuery `Selector` (using the [ESQuery selector syntax](https://github.com/estools/esquery)).
* @returns `true` if the code contains matches for the `Selector`, `false` if not.
*/
function includes(node, selector) {
return !!(0, index_1.query)(node, selector).length;
}
exports.includes = includes;
//# sourceMappingURL=includes.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"includes.js","sourceRoot":"","sources":["../../src/includes.ts"],"names":[],"mappings":";;;AACA,mCAAgC;AAEhC;;;;;;;GAOG;AACH,SAAgB,QAAQ,CAAC,IAAU,EAAE,QAA2B;IAC9D,OAAO,CAAC,CAAC,IAAA,aAAK,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC;AACxC,CAAC;AAFD,4BAEC"}

View File

@@ -0,0 +1,33 @@
import { ast } from './ast';
import { map } from './map';
import { match } from './match';
import { parse } from './parse';
import { project, files } from './project';
import { query } from './query';
import { replace } from './replace';
import { syntaxKindName } from './syntax-kind';
export type { Selector, Field, Type, Sequence, Identifier, Wildcard, Attribute, NthChild, NthLastChild, Descendant, Child, Sibling, Adjacent, Negation, Matches, Has, Class, MultiSelector, BinarySelector, NthSelector, SubjectSelector, StringLiteral, NumericLiteral, Literal } from 'esquery';
export type { Node, SourceFile, VisitResult } from 'typescript';
export type { NodeTransformer, StringTransformer } from './types';
export { ScriptKind, SyntaxKind } from 'typescript';
export { ast } from './ast';
export { print } from './print';
export { includes } from './includes';
export { match } from './match';
export { query } from './query';
export { parse } from './parse';
export { map } from './map';
export { replace } from './replace';
export { project, files } from './project';
export type API = typeof query & {
ast: typeof ast;
map: typeof map;
match: typeof match;
parse: typeof parse;
project: typeof project;
projectFiles: typeof files;
query: typeof query;
replace: typeof replace;
syntaxKindName: typeof syntaxKindName;
};
export declare const tsquery: API;

View File

@@ -0,0 +1,58 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.tsquery = exports.files = exports.project = exports.replace = exports.map = exports.parse = exports.query = exports.match = exports.includes = exports.print = exports.ast = exports.SyntaxKind = exports.ScriptKind = void 0;
const ast_1 = require("./ast");
const map_1 = require("./map");
const match_1 = require("./match");
const parse_1 = require("./parse");
const project_1 = require("./project");
const query_1 = require("./query");
const replace_1 = require("./replace");
const syntax_kind_1 = require("./syntax-kind");
var typescript_1 = require("typescript");
Object.defineProperty(exports, "ScriptKind", { enumerable: true, get: function () { return typescript_1.ScriptKind; } });
Object.defineProperty(exports, "SyntaxKind", { enumerable: true, get: function () { return typescript_1.SyntaxKind; } });
var ast_2 = require("./ast");
Object.defineProperty(exports, "ast", { enumerable: true, get: function () { return ast_2.ast; } });
var print_1 = require("./print");
Object.defineProperty(exports, "print", { enumerable: true, get: function () { return print_1.print; } });
var includes_1 = require("./includes");
Object.defineProperty(exports, "includes", { enumerable: true, get: function () { return includes_1.includes; } });
var match_2 = require("./match");
Object.defineProperty(exports, "match", { enumerable: true, get: function () { return match_2.match; } });
var query_2 = require("./query");
Object.defineProperty(exports, "query", { enumerable: true, get: function () { return query_2.query; } });
var parse_2 = require("./parse");
Object.defineProperty(exports, "parse", { enumerable: true, get: function () { return parse_2.parse; } });
var map_2 = require("./map");
Object.defineProperty(exports, "map", { enumerable: true, get: function () { return map_2.map; } });
var replace_2 = require("./replace");
Object.defineProperty(exports, "replace", { enumerable: true, get: function () { return replace_2.replace; } });
var project_2 = require("./project");
Object.defineProperty(exports, "project", { enumerable: true, get: function () { return project_2.project; } });
Object.defineProperty(exports, "files", { enumerable: true, get: function () { return project_2.files; } });
/**
* @deprecated Will be removed in v7. Use the directly exported functions instead:
*
* ```
* // Use:
* import { ast } from '@phenomnomnominal/tsquery';
* ast('1 + 1')
*
* // Don't use:
* import { tsquery } from '@phenomnomnominal/tsquery';
* tsquery.ast('1 + 1')
* ```
*/
const api = query_1.query;
api.ast = ast_1.ast;
api.map = map_1.map;
api.match = match_1.match;
api.parse = parse_1.parse;
api.project = project_1.project;
api.projectFiles = project_1.files;
api.query = query_1.query;
api.replace = replace_1.replace;
api.syntaxKindName = syntax_kind_1.syntaxKindName;
exports.tsquery = api;
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,+BAA4B;AAC5B,+BAA4B;AAC5B,mCAAgC;AAChC,mCAAgC;AAChC,uCAA2C;AAC3C,mCAAgC;AAChC,uCAAoC;AACpC,+CAA+C;AA+B/C,yCAAoD;AAA3C,wGAAA,UAAU,OAAA;AAAE,wGAAA,UAAU,OAAA;AAE/B,6BAA4B;AAAnB,0FAAA,GAAG,OAAA;AACZ,iCAAgC;AAAvB,8FAAA,KAAK,OAAA;AAEd,uCAAsC;AAA7B,oGAAA,QAAQ,OAAA;AACjB,iCAAgC;AAAvB,8FAAA,KAAK,OAAA;AACd,iCAAgC;AAAvB,8FAAA,KAAK,OAAA;AAEd,iCAAgC;AAAvB,8FAAA,KAAK,OAAA;AAEd,6BAA4B;AAAnB,0FAAA,GAAG,OAAA;AACZ,qCAAoC;AAA3B,kGAAA,OAAO,OAAA;AAEhB,qCAA2C;AAAlC,kGAAA,OAAO,OAAA;AAAE,gGAAA,KAAK,OAAA;AAcvB;;;;;;;;;;;;GAYG;AACH,MAAM,GAAG,GAAQ,aAAK,CAAC;AACvB,GAAG,CAAC,GAAG,GAAG,SAAG,CAAC;AACd,GAAG,CAAC,GAAG,GAAG,SAAG,CAAC;AACd,GAAG,CAAC,KAAK,GAAG,aAAK,CAAC;AAClB,GAAG,CAAC,KAAK,GAAG,aAAK,CAAC;AAClB,GAAG,CAAC,OAAO,GAAG,iBAAO,CAAC;AACtB,GAAG,CAAC,YAAY,GAAG,eAAK,CAAC;AACzB,GAAG,CAAC,KAAK,GAAG,aAAK,CAAC;AAClB,GAAG,CAAC,OAAO,GAAG,iBAAO,CAAC;AACtB,GAAG,CAAC,cAAc,GAAG,4BAAc,CAAC;AAEvB,QAAA,OAAO,GAAG,GAAG,CAAC"}

View File

@@ -0,0 +1,14 @@
/// <reference types="esquery" />
import type { SourceFile, TransformerFactory } from 'typescript';
import type { Node, NodeTransformer, Selector } from './index';
/**
* @public
* Transform 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.
*
* @param sourceFile - the TypeScript [`SourceFile`](https://github.com/microsoft/TypeScript/blob/main/src/services/types.ts#L159) to be searched.
* @param selector - a TSQuery `Selector` (using the [ESQuery selector syntax](https://github.com/estools/esquery)).
* @param nodeTransformer - a function to transform any matched `Nodes`. If the original `Node` is returned, there is no change. If a new `Node` is returned, the original `Node` is replaced. If `undefined` is returned, the original `Node` is removed.
* @returns a transformed `Node`.
*/
export declare function map(sourceFile: SourceFile, selector: string | Selector, nodeTransformer: NodeTransformer): SourceFile;
export declare function createTransformer(nodeTransformer: NodeTransformer): TransformerFactory<Node>;

45
node_modules/@phenomnomnominal/tsquery/dist/src/map.js generated vendored Normal file
View File

@@ -0,0 +1,45 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createTransformer = exports.map = void 0;
const typescript_1 = require("typescript");
const index_1 = require("./index");
/**
* @public
* Transform 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.
*
* @param sourceFile - the TypeScript [`SourceFile`](https://github.com/microsoft/TypeScript/blob/main/src/services/types.ts#L159) to be searched.
* @param selector - a TSQuery `Selector` (using the [ESQuery selector syntax](https://github.com/estools/esquery)).
* @param nodeTransformer - a function to transform any matched `Nodes`. If the original `Node` is returned, there is no change. If a new `Node` is returned, the original `Node` is replaced. If `undefined` is returned, the original `Node` is removed.
* @returns a transformed `Node`.
*/
function map(sourceFile, selector, nodeTransformer) {
const matches = (0, index_1.match)(sourceFile, index_1.parse.ensure(selector));
return mapTransform(sourceFile, matches, nodeTransformer);
}
exports.map = map;
function mapTransform(sourceFile, matches, nodeTransformer) {
const transformer = createTransformer((node) => {
if (matches.includes(node)) {
return nodeTransformer(node);
}
return node;
});
const [transformed] = (0, typescript_1.transform)(sourceFile, [transformer]).transformed;
return (0, index_1.ast)((0, index_1.print)(transformed));
}
function createTransformer(nodeTransformer) {
return function (context) {
return function (rootNode) {
function visit(node) {
const replacement = nodeTransformer(node);
if (replacement !== node) {
return replacement;
}
return (0, typescript_1.visitEachChild)(node, visit, context);
}
return (0, typescript_1.visitNode)(rootNode, visit) || rootNode;
};
};
}
exports.createTransformer = createTransformer;
//# sourceMappingURL=map.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"map.js","sourceRoot":"","sources":["../../src/map.ts"],"names":[],"mappings":";;;AAQA,2CAAkE;AAClE,mCAAmD;AAEnD;;;;;;;;GAQG;AACH,SAAgB,GAAG,CACjB,UAAsB,EACtB,QAA2B,EAC3B,eAAgC;IAEhC,MAAM,OAAO,GAAG,IAAA,aAAK,EAAC,UAAU,EAAE,aAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC1D,OAAO,YAAY,CAAC,UAAU,EAAE,OAAO,EAAE,eAAe,CAAC,CAAC;AAC5D,CAAC;AAPD,kBAOC;AAED,SAAS,YAAY,CACnB,UAAsB,EACtB,OAAoB,EACpB,eAAgC;IAEhC,MAAM,WAAW,GAAG,iBAAiB,CAAC,CAAC,IAAU,EAAE,EAAE;QACnD,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;YAC1B,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;SAC9B;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,WAAW,CAAC,GAAG,IAAA,sBAAS,EAAC,UAAU,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC;IACvE,OAAO,IAAA,WAAG,EAAC,IAAA,aAAK,EAAC,WAAW,CAAC,CAAC,CAAC;AACjC,CAAC;AAED,SAAgB,iBAAiB,CAC/B,eAAgC;IAEhC,OAAO,UAAU,OAA8B;QAC7C,OAAO,UAAU,QAAc;YAC7B,SAAS,KAAK,CAAC,IAAU;gBACvB,MAAM,WAAW,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;gBAC1C,IAAI,WAAW,KAAK,IAAI,EAAE;oBACxB,OAAO,WAAW,CAAC;iBACpB;gBAED,OAAO,IAAA,2BAAc,EAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;YAC9C,CAAC;YACD,OAAO,IAAA,sBAAS,EAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,QAAQ,CAAC;QAChD,CAAC,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAhBD,8CAgBC"}

View File

@@ -0,0 +1,11 @@
/// <reference types="esquery" />
import { type Node, type Selector } from './index';
/**
* @public
* Find AST `Nodes` within a given AST `Node` matching a `Selector`.
*
* @param node - the `Node` to be searched. This could be a TypeScript [`SourceFile`](https://github.com/microsoft/TypeScript/blob/main/src/services/types.ts#L159), or a `Node` from a previous query.
* @param selector - a TSQuery `Selector` (using the [ESQuery selector syntax](https://github.com/estools/esquery)).
* @returns an `Array` of `Nodes` which match the `Selector`.
*/
export declare function match<T extends Node = Node>(node: Node, selector: string | Selector): Array<T>;

View File

@@ -0,0 +1,25 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.match = void 0;
const index_1 = require("./index");
const traverse_1 = require("./traverse");
/**
* @public
* Find AST `Nodes` within a given AST `Node` matching a `Selector`.
*
* @param node - the `Node` to be searched. This could be a TypeScript [`SourceFile`](https://github.com/microsoft/TypeScript/blob/main/src/services/types.ts#L159), or a `Node` from a previous query.
* @param selector - a TSQuery `Selector` (using the [ESQuery selector syntax](https://github.com/estools/esquery)).
* @returns an `Array` of `Nodes` which match the `Selector`.
*/
function match(node, selector) {
const results = [];
const parsedSelector = index_1.parse.ensure(selector);
(0, traverse_1.traverse)(node, (childNode, ancestry) => {
if ((0, traverse_1.findMatches)(childNode, parsedSelector, ancestry)) {
results.push(childNode);
}
});
return results;
}
exports.match = match;
//# sourceMappingURL=match.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"match.js","sourceRoot":"","sources":["../../src/match.ts"],"names":[],"mappings":";;;AAAA,mCAA0D;AAE1D,yCAAmD;AAEnD;;;;;;;GAOG;AACH,SAAgB,KAAK,CACnB,IAAU,EACV,QAA2B;IAE3B,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,cAAc,GAAG,aAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAE9C,IAAA,mBAAQ,EAAC,IAAI,EAAE,CAAC,SAAe,EAAE,QAAqB,EAAE,EAAE;QACxD,IAAI,IAAA,sBAAW,EAAC,SAAS,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE;YACpD,OAAO,CAAC,IAAI,CAAC,SAAc,CAAC,CAAC;SAC9B;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC;AACjB,CAAC;AAdD,sBAcC"}

View File

@@ -0,0 +1,3 @@
import type { Attribute } from 'esquery';
import type { Node } from 'typescript';
export declare function attribute(node: Node, selector: Attribute): boolean;

View File

@@ -0,0 +1,66 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.attribute = void 0;
const utils_1 = require("../utils");
const OPERATOR = {
'=': equal,
'!=': notEqual,
'<=': lessThanEqual,
'<': lessThan,
'>=': greaterThanEqual,
'>': greaterThan
};
function attribute(node, selector) {
const obj = (0, utils_1.getPath)(node, selector.name);
// Bail on undefined but *not* if value is explicitly `null`:
if (obj === undefined) {
return false;
}
if ((selector === null || selector === void 0 ? void 0 : selector.operator) == null) {
return obj != null;
}
const { operator } = selector;
if (!(selector === null || selector === void 0 ? void 0 : selector.value)) {
return false;
}
const { type, value } = selector.value;
const matcher = OPERATOR[operator];
if (matcher) {
return matcher(obj, value, type);
}
return false;
}
exports.attribute = attribute;
function equal(obj, value, type) {
switch (type) {
case 'regexp':
return typeof obj === 'string' && value.test(obj);
case 'literal':
return `${value}` === `${obj}`;
case 'type':
return value === typeof obj;
}
}
function notEqual(obj, value, type) {
switch (type) {
case 'regexp':
return typeof obj === 'string' && !value.test(obj);
case 'literal':
return `${value}` !== `${obj}`;
case 'type':
return value !== typeof obj;
}
}
function lessThanEqual(obj, value) {
return obj <= value;
}
function lessThan(obj, value) {
return obj < value;
}
function greaterThanEqual(obj, value) {
return obj >= value;
}
function greaterThan(obj, value) {
return obj > value;
}
//# sourceMappingURL=attribute.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"attribute.js","sourceRoot":"","sources":["../../../src/matchers/attribute.ts"],"names":[],"mappings":";;;AAIA,oCAAmC;AAEnC,MAAM,QAAQ,GAAG;IACf,GAAG,EAAE,KAAK;IACV,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE,aAAa;IACnB,GAAG,EAAE,QAAQ;IACb,IAAI,EAAE,gBAAgB;IACtB,GAAG,EAAE,WAAW;CACjB,CAAC;AAEF,SAAgB,SAAS,CAAC,IAAU,EAAE,QAAmB;IACvD,MAAM,GAAG,GAAY,IAAA,eAAO,EAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;IAElD,6DAA6D;IAC7D,IAAI,GAAG,KAAK,SAAS,EAAE;QACrB,OAAO,KAAK,CAAC;KACd;IAED,IAAI,CAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,QAAQ,KAAI,IAAI,EAAE;QAC9B,OAAO,GAAG,IAAI,IAAI,CAAC;KACpB;IAED,MAAM,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAAC;IAE9B,IAAI,CAAC,CAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,KAAK,CAAA,EAAE;QACpB,OAAO,KAAK,CAAC;KACd;IAED,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC;IAEvC,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACnC,IAAI,OAAO,EAAE;QACX,OAAO,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;KAClC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAzBD,8BAyBC;AAED,SAAS,KAAK,CACZ,GAAY,EACZ,KAAc,EACd,IAA2B;IAE3B,QAAQ,IAAI,EAAE;QACZ,KAAK,QAAQ;YACX,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAK,KAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChE,KAAK,SAAS;YACZ,OAAO,GAAG,KAAe,EAAE,KAAK,GAAG,GAAa,EAAE,CAAC;QACrD,KAAK,MAAM;YACT,OAAO,KAAK,KAAK,OAAO,GAAG,CAAC;KAC/B;AACH,CAAC;AAED,SAAS,QAAQ,CACf,GAAY,EACZ,KAAc,EACd,IAA2B;IAE3B,QAAQ,IAAI,EAAE;QACZ,KAAK,QAAQ;YACX,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAE,KAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjE,KAAK,SAAS;YACZ,OAAO,GAAG,KAAe,EAAE,KAAK,GAAG,GAAa,EAAE,CAAC;QACrD,KAAK,MAAM;YACT,OAAO,KAAK,KAAK,OAAO,GAAG,CAAC;KAC/B;AACH,CAAC;AAED,SAAS,aAAa,CAAC,GAAY,EAAE,KAAc;IACjD,OAAQ,GAAc,IAAK,KAAgB,CAAC;AAC9C,CAAC;AAED,SAAS,QAAQ,CAAC,GAAY,EAAE,KAAc;IAC5C,OAAQ,GAAc,GAAI,KAAgB,CAAC;AAC7C,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAY,EAAE,KAAc;IACpD,OAAQ,GAAc,IAAK,KAAgB,CAAC;AAC9C,CAAC;AAED,SAAS,WAAW,CAAC,GAAY,EAAE,KAAc;IAC/C,OAAQ,GAAc,GAAI,KAAgB,CAAC;AAC7C,CAAC"}

View File

@@ -0,0 +1,3 @@
import type { Child } from 'esquery';
import type { Node } from 'typescript';
export declare function child(node: Node, selector: Child, ancestors: Array<Node>): boolean;

View File

@@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.child = void 0;
const traverse_1 = require("../traverse");
function child(node, selector, ancestors) {
if ((0, traverse_1.findMatches)(node, selector.right, ancestors)) {
return (0, traverse_1.findMatches)(ancestors[0], selector.left, ancestors.slice(1));
}
return false;
}
exports.child = child;
//# sourceMappingURL=child.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"child.js","sourceRoot":"","sources":["../../../src/matchers/child.ts"],"names":[],"mappings":";;;AAGA,0CAA0C;AAE1C,SAAgB,KAAK,CACnB,IAAU,EACV,QAAe,EACf,SAAsB;IAEtB,IAAI,IAAA,sBAAW,EAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE;QAChD,OAAO,IAAA,sBAAW,EAAC,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;KACrE;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AATD,sBASC"}

View File

@@ -0,0 +1,9 @@
import type { Class, Selector } from 'esquery';
import type { Node } from 'typescript';
import type { Properties } from '../types';
type ClassMatcher = (node: Node, properties: Properties, selector: Selector, ancestors: Array<Node>) => boolean;
export type ClassMatchers = {
[Key in Class['name']]: ClassMatcher;
};
export declare function classMatcher(node: Node, selector: Class, ancestors: Array<Node>): boolean;
export {};

View File

@@ -0,0 +1,48 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.classMatcher = void 0;
const traverse_1 = require("../traverse");
const CLASS_MATCHERS = {
declaration,
expression,
function: functionMatcher,
pattern,
statement
};
function classMatcher(node, selector, ancestors) {
const properties = (0, traverse_1.getProperties)(node);
if (!properties.kindName) {
return false;
}
const matcher = CLASS_MATCHERS[selector.name];
if (matcher) {
return matcher(node, properties, selector, ancestors);
}
throw new SyntaxError(`Unknown class name: "${selector.name}"`);
}
exports.classMatcher = classMatcher;
function declaration(_, properties) {
return properties.kindName.endsWith('Declaration');
}
function expression(node, properties) {
const { kindName } = properties;
return (kindName.endsWith('Expression') ||
kindName.endsWith('Literal') ||
(kindName === 'Identifier' &&
!!node.parent &&
(0, traverse_1.getProperties)(node.parent).kindName !== 'MetaProperty') ||
kindName === 'MetaProperty');
}
function functionMatcher(_, properties) {
const { kindName } = properties;
return (kindName.startsWith('Function') ||
kindName === 'ArrowFunction' ||
kindName === 'MethodDeclaration');
}
function pattern(node, properties) {
return (properties.kindName.endsWith('Pattern') || expression(node, properties));
}
function statement(node, properties) {
return (properties.kindName.endsWith('Statement') || declaration(node, properties));
}
//# sourceMappingURL=class.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"class.js","sourceRoot":"","sources":["../../../src/matchers/class.ts"],"names":[],"mappings":";;;AAIA,0CAA4C;AAY5C,MAAM,cAAc,GAAkB;IACpC,WAAW;IACX,UAAU;IACV,QAAQ,EAAE,eAAe;IACzB,OAAO;IACP,SAAS;CACV,CAAC;AAEF,SAAgB,YAAY,CAC1B,IAAU,EACV,QAAe,EACf,SAAsB;IAEtB,MAAM,UAAU,GAAG,IAAA,wBAAa,EAAC,IAAI,CAAC,CAAC;IACvC,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE;QACxB,OAAO,KAAK,CAAC;KACd;IAED,MAAM,OAAO,GAAG,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC9C,IAAI,OAAO,EAAE;QACX,OAAO,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;KACvD;IAED,MAAM,IAAI,WAAW,CAAC,wBAAwB,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC;AAClE,CAAC;AAhBD,oCAgBC;AAED,SAAS,WAAW,CAAC,CAAO,EAAE,UAAsB;IAClD,OAAO,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;AACrD,CAAC;AAED,SAAS,UAAU,CAAC,IAAU,EAAE,UAAsB;IACpD,MAAM,EAAE,QAAQ,EAAE,GAAG,UAAU,CAAC;IAChC,OAAO,CACL,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC;QAC/B,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC5B,CAAC,QAAQ,KAAK,YAAY;YACxB,CAAC,CAAC,IAAI,CAAC,MAAM;YACb,IAAA,wBAAa,EAAC,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,KAAK,cAAc,CAAC;QACzD,QAAQ,KAAK,cAAc,CAC5B,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,CAAO,EAAE,UAAsB;IACtD,MAAM,EAAE,QAAQ,EAAE,GAAG,UAAU,CAAC;IAChC,OAAO,CACL,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC;QAC/B,QAAQ,KAAK,eAAe;QAC5B,QAAQ,KAAK,mBAAmB,CACjC,CAAC;AACJ,CAAC;AAED,SAAS,OAAO,CAAC,IAAU,EAAE,UAAsB;IACjD,OAAO,CACL,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,IAAI,EAAE,UAAU,CAAC,CACxE,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,IAAU,EAAE,UAAsB;IACnD,OAAO,CACL,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,WAAW,CAAC,IAAI,EAAE,UAAU,CAAC,CAC3E,CAAC;AACJ,CAAC"}

View File

@@ -0,0 +1,3 @@
import type { Descendant } from 'esquery';
import type { Node } from 'typescript';
export declare function descendant(node: Node, selector: Descendant, ancestors: Array<Node>): boolean;

View File

@@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.descendant = void 0;
const traverse_1 = require("../traverse");
function descendant(node, selector, ancestors) {
if ((0, traverse_1.findMatches)(node, selector.right, ancestors)) {
return ancestors.some((ancestor, index) => (0, traverse_1.findMatches)(ancestor, selector.left, ancestors.slice(index + 1)));
}
return false;
}
exports.descendant = descendant;
//# sourceMappingURL=descendant.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"descendant.js","sourceRoot":"","sources":["../../../src/matchers/descendant.ts"],"names":[],"mappings":";;;AAGA,0CAA0C;AAE1C,SAAgB,UAAU,CACxB,IAAU,EACV,QAAoB,EACpB,SAAsB;IAEtB,IAAI,IAAA,sBAAW,EAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE;QAChD,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAW,EAAE,CACjD,IAAA,sBAAW,EAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CACjE,CAAC;KACH;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAXD,gCAWC"}

View File

@@ -0,0 +1,3 @@
import type { Field } from 'esquery';
import type { Node } from 'typescript';
export declare function field(node: Node, selector: Field, ancestors: Array<Node>): boolean;

View File

@@ -0,0 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.field = void 0;
const utils_1 = require("../utils");
function field(node, selector, ancestors) {
const path = selector.name.split('.');
const ancestor = ancestors[path.length - 1];
return (0, utils_1.inPath)(node, ancestor, path);
}
exports.field = field;
//# sourceMappingURL=field.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"field.js","sourceRoot":"","sources":["../../../src/matchers/field.ts"],"names":[],"mappings":";;;AAGA,oCAAkC;AAElC,SAAgB,KAAK,CACnB,IAAU,EACV,QAAe,EACf,SAAsB;IAEtB,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC5C,OAAO,IAAA,cAAM,EAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;AACtC,CAAC;AARD,sBAQC"}

View File

@@ -0,0 +1,3 @@
import type { Has } from 'esquery';
import type { Node } from 'typescript';
export declare function has(node: Node, selector: Has): boolean;

View File

@@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.has = void 0;
const traverse_1 = require("../traverse");
function has(node, selector) {
const collector = [];
selector.selectors.forEach((childSelector) => {
(0, traverse_1.traverse)(node, (childNode, ancestors) => {
if ((0, traverse_1.findMatches)(childNode, childSelector, ancestors)) {
collector.push(childNode);
}
});
});
return collector.length > 0;
}
exports.has = has;
//# sourceMappingURL=has.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"has.js","sourceRoot":"","sources":["../../../src/matchers/has.ts"],"names":[],"mappings":";;;AAGA,0CAAoD;AAEpD,SAAgB,GAAG,CAAC,IAAU,EAAE,QAAa;IAC3C,MAAM,SAAS,GAAgB,EAAE,CAAC;IAClC,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE,EAAE;QAC3C,IAAA,mBAAQ,EAAC,IAAI,EAAE,CAAC,SAAe,EAAE,SAAsB,EAAE,EAAE;YACzD,IAAI,IAAA,sBAAW,EAAC,SAAS,EAAE,aAAa,EAAE,SAAS,CAAC,EAAE;gBACpD,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;aAC3B;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;AAC9B,CAAC;AAVD,kBAUC"}

View File

@@ -0,0 +1,3 @@
import type { Identifier } from 'esquery';
import type { Node } from 'typescript';
export declare function identifier(node: Node, selector: Identifier): boolean;

View File

@@ -0,0 +1,10 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.identifier = void 0;
const syntax_kind_1 = require("../syntax-kind");
function identifier(node, selector) {
const name = (0, syntax_kind_1.syntaxKindName)(node.kind);
return !!name && name.toLowerCase() === selector.value.toLowerCase();
}
exports.identifier = identifier;
//# sourceMappingURL=identifier.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"identifier.js","sourceRoot":"","sources":["../../../src/matchers/identifier.ts"],"names":[],"mappings":";;;AAGA,gDAAgD;AAEhD,SAAgB,UAAU,CAAC,IAAU,EAAE,QAAoB;IACzD,MAAM,IAAI,GAAG,IAAA,4BAAc,EAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvC,OAAO,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;AACvE,CAAC;AAHD,gCAGC"}

View File

@@ -0,0 +1,10 @@
import type { Selector } from 'esquery';
import type { Node } from 'typescript';
export type Matcher<Selector> = (node: Node, selector: Selector, ancestors: Array<Node>) => boolean;
type Matchers = {
[Key in Selector['type']]: Matcher<Selector & {
type: Key;
}>;
};
export declare const MATCHERS: Matchers;
export {};

View File

@@ -0,0 +1,35 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MATCHERS = void 0;
const attribute_1 = require("./attribute");
const child_1 = require("./child");
const class_1 = require("./class");
const descendant_1 = require("./descendant");
const field_1 = require("./field");
const has_1 = require("./has");
const identifier_1 = require("./identifier");
const matches_1 = require("./matches");
const not_1 = require("./not");
const nth_child_1 = require("./nth-child");
const sibling_1 = require("./sibling");
const type_1 = require("./type");
const wildcard_1 = require("./wildcard");
exports.MATCHERS = {
adjacent: sibling_1.adjacent,
attribute: attribute_1.attribute,
child: child_1.child,
compound: (0, matches_1.matches)('every'),
class: class_1.classMatcher,
descendant: descendant_1.descendant,
field: field_1.field,
'nth-child': nth_child_1.nthChild,
'nth-last-child': nth_child_1.nthLastChild,
has: has_1.has,
identifier: identifier_1.identifier,
matches: (0, matches_1.matches)('some'),
not: not_1.not,
sibling: sibling_1.sibling,
type: type_1.type,
wildcard: wildcard_1.wildcard
};
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/matchers/index.ts"],"names":[],"mappings":";;;AAGA,2CAAwC;AACxC,mCAAgC;AAChC,mCAAuC;AACvC,6CAA0C;AAC1C,mCAAgC;AAChC,+BAA4B;AAC5B,6CAA0C;AAC1C,uCAAoC;AACpC,+BAA4B;AAC5B,2CAAqD;AACrD,uCAA8C;AAC9C,iCAA8B;AAC9B,yCAAsC;AAYzB,QAAA,QAAQ,GAAa;IAChC,QAAQ,EAAR,kBAAQ;IACR,SAAS,EAAT,qBAAS;IACT,KAAK,EAAL,aAAK;IACL,QAAQ,EAAE,IAAA,iBAAO,EAAW,OAAO,CAAC;IACpC,KAAK,EAAE,oBAAY;IACnB,UAAU,EAAV,uBAAU;IACV,KAAK,EAAL,aAAK;IACL,WAAW,EAAE,oBAAQ;IACrB,gBAAgB,EAAE,wBAAY;IAC9B,GAAG,EAAH,SAAG;IACH,UAAU,EAAV,uBAAU;IACV,OAAO,EAAE,IAAA,iBAAO,EAAU,MAAM,CAAC;IACjC,GAAG,EAAH,SAAG;IACH,OAAO,EAAP,iBAAO;IACP,IAAI,EAAJ,WAAI;IACJ,QAAQ,EAAR,mBAAQ;CACT,CAAC"}

View File

@@ -0,0 +1,3 @@
import type { MultiSelector } from 'esquery';
import type { Node } from 'typescript';
export declare function matches<Selector extends MultiSelector>(modifier: 'some' | 'every'): (node: Node, selector: Selector, ancestors: Array<Node>) => boolean;

View File

@@ -0,0 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.matches = void 0;
const traverse_1 = require("../traverse");
function matches(modifier) {
return function (node, selector, ancestors) {
return selector.selectors[modifier]((childSelector) => (0, traverse_1.findMatches)(node, childSelector, ancestors));
};
}
exports.matches = matches;
//# sourceMappingURL=matches.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"matches.js","sourceRoot":"","sources":["../../../src/matchers/matches.ts"],"names":[],"mappings":";;;AAGA,0CAA0C;AAE1C,SAAgB,OAAO,CACrB,QAA0B;IAE1B,OAAO,UACL,IAAU,EACV,QAAkB,EAClB,SAAsB;QAEtB,OAAO,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,EAAE,EAAE,CACpD,IAAA,sBAAW,EAAC,IAAI,EAAE,aAAa,EAAE,SAAS,CAAC,CAC5C,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAZD,0BAYC"}

View File

@@ -0,0 +1,3 @@
import type { MultiSelector } from 'esquery';
import type { Node } from 'typescript';
export declare function not(node: Node, selector: MultiSelector, ancestors: Array<Node>): boolean;

View File

@@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.not = void 0;
const traverse_1 = require("../traverse");
function not(node, selector, ancestors) {
return !selector.selectors.some((childSelector) => (0, traverse_1.findMatches)(node, childSelector, ancestors));
}
exports.not = not;
//# sourceMappingURL=not.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"not.js","sourceRoot":"","sources":["../../../src/matchers/not.ts"],"names":[],"mappings":";;;AAGA,0CAA0C;AAE1C,SAAgB,GAAG,CACjB,IAAU,EACV,QAAuB,EACvB,SAAsB;IAEtB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,EAAE,CAChD,IAAA,sBAAW,EAAC,IAAI,EAAE,aAAa,EAAE,SAAS,CAAC,CAC5C,CAAC;AACJ,CAAC;AARD,kBAQC"}

View File

@@ -0,0 +1,4 @@
import type { SubjectSelector } from 'esquery';
import type { Node } from 'typescript';
export declare function nthChild(node: Node, selector: SubjectSelector, ancestors: Array<Node>): boolean;
export declare function nthLastChild(node: Node, selector: SubjectSelector, ancestors: Array<Node>): boolean;

View File

@@ -0,0 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.nthLastChild = exports.nthChild = void 0;
const traverse_1 = require("../traverse");
const sibling_1 = require("./sibling");
function nthChild(node, selector, ancestors) {
const { right } = selector;
if (right && !(0, traverse_1.findMatches)(node, right, ancestors)) {
return false;
}
return findNthChild(node, () => selector.index.value - 1);
}
exports.nthChild = nthChild;
function nthLastChild(node, selector, ancestors) {
const { right } = selector;
if (right && !(0, traverse_1.findMatches)(node, right, ancestors)) {
return false;
}
return findNthChild(node, (length) => length - selector.index.value);
}
exports.nthLastChild = nthLastChild;
function findNthChild(node, getIndex) {
if (!node.parent) {
return false;
}
const keys = (0, sibling_1.getVisitorKeys)(node.parent || null);
return keys.some((key) => {
const prop = node.parent[key];
if (Array.isArray(prop)) {
const index = prop.indexOf(node);
return index >= 0 && index === getIndex(prop.length);
}
return false;
});
}
//# sourceMappingURL=nth-child.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"nth-child.js","sourceRoot":"","sources":["../../../src/matchers/nth-child.ts"],"names":[],"mappings":";;;AAQA,0CAA0C;AAC1C,uCAA2C;AAE3C,SAAgB,QAAQ,CACtB,IAAU,EACV,QAAyB,EACzB,SAAsB;IAEtB,MAAM,EAAE,KAAK,EAAE,GAAG,QAA0B,CAAC;IAC7C,IAAI,KAAK,IAAI,CAAC,IAAA,sBAAW,EAAC,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE;QACjD,OAAO,KAAK,CAAC;KACd;IACD,OAAO,YAAY,CAAC,IAAI,EAAE,GAAG,EAAE,CAAE,QAAqB,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;AAC1E,CAAC;AAVD,4BAUC;AAED,SAAgB,YAAY,CAC1B,IAAU,EACV,QAAyB,EACzB,SAAsB;IAEtB,MAAM,EAAE,KAAK,EAAE,GAAG,QAA0B,CAAC;IAC7C,IAAI,KAAK,IAAI,CAAC,IAAA,sBAAW,EAAC,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE;QACjD,OAAO,KAAK,CAAC;KACd;IACD,OAAO,YAAY,CACjB,IAAI,EACJ,CAAC,MAAc,EAAE,EAAE,CAAC,MAAM,GAAI,QAAyB,CAAC,KAAK,CAAC,KAAK,CACpE,CAAC;AACJ,CAAC;AAbD,oCAaC;AAED,SAAS,YAAY,CACnB,IAAU,EACV,QAAoC;IAEpC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;QAChB,OAAO,KAAK,CAAC;KACd;IAED,MAAM,IAAI,GAAG,IAAA,wBAAc,EAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC;IACjD,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE;QACvB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAiB,CAAC,CAAC;QAC5C,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;YACvB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACjC,OAAO,KAAK,IAAI,CAAC,IAAI,KAAK,KAAK,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;SACtD;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,CAAC;AACL,CAAC"}

View File

@@ -0,0 +1,5 @@
import type { Adjacent, Sibling } from 'esquery';
import type { Node } from 'typescript';
export declare function sibling(node: Node, selector: Sibling, ancestors: Array<Node>): boolean;
export declare function adjacent(node: Node, selector: Adjacent, ancestors: Array<Node>): boolean;
export declare function getVisitorKeys(node: Node | null): Array<string>;

View File

@@ -0,0 +1,68 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getVisitorKeys = exports.adjacent = exports.sibling = void 0;
const traverse_1 = require("../traverse");
function sibling(node, selector, ancestors) {
return !!(((0, traverse_1.findMatches)(node, selector.right, ancestors) &&
findSibling(node, ancestors, siblingLeft)) ||
(selector.left.subject &&
(0, traverse_1.findMatches)(node, selector.left, ancestors) &&
findSibling(node, ancestors, siblingRight)));
function siblingLeft(prop, index) {
return prop
.slice(0, index)
.some((precedingSibling) => (0, traverse_1.findMatches)(precedingSibling, selector.left, ancestors));
}
function siblingRight(prop, index) {
return prop
.slice(index, prop.length)
.some((followingSibling) => (0, traverse_1.findMatches)(followingSibling, selector.right, ancestors));
}
}
exports.sibling = sibling;
function adjacent(node, selector, ancestors) {
return !!(((0, traverse_1.findMatches)(node, selector.right, ancestors) &&
findSibling(node, ancestors, adjacentLeft)) ||
(selector.right.subject &&
(0, traverse_1.findMatches)(node, selector.left, ancestors) &&
findSibling(node, ancestors, adjacentRight)));
function adjacentLeft(prop, index) {
return index > 0 && (0, traverse_1.findMatches)(prop[index - 1], selector.left, ancestors);
}
function adjacentRight(prop, index) {
return (index < prop.length - 1 &&
(0, traverse_1.findMatches)(prop[index + 1], selector.right, ancestors));
}
}
exports.adjacent = adjacent;
function findSibling(node, ancestors, test) {
const [parent] = ancestors;
if (!parent) {
return false;
}
const keys = getVisitorKeys(node.parent || null);
return keys.some((key) => {
const prop = node.parent[key];
if (Array.isArray(prop)) {
const index = prop.indexOf(node);
if (index === -1) {
return false;
}
return test(prop, index);
}
return false;
});
}
const FILTERED_KEYS = ['parent'];
function getVisitorKeys(node) {
return node
? Object.keys(node)
.filter((key) => !FILTERED_KEYS.includes(key))
.filter((key) => {
const value = node[key];
return Array.isArray(value) || typeof value === 'object';
})
: [];
}
exports.getVisitorKeys = getVisitorKeys;
//# sourceMappingURL=sibling.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"sibling.js","sourceRoot":"","sources":["../../../src/matchers/sibling.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1 @@
export declare function type(): boolean;

View File

@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.type = void 0;
function type() {
return false;
}
exports.type = type;
//# sourceMappingURL=type.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"type.js","sourceRoot":"","sources":["../../../src/matchers/type.ts"],"names":[],"mappings":";;;AAAA,SAAgB,IAAI;IAClB,OAAO,KAAK,CAAC;AACf,CAAC;AAFD,oBAEC"}

View File

@@ -0,0 +1 @@
export declare function wildcard(): boolean;

View File

@@ -0,0 +1,8 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.wildcard = void 0;
function wildcard() {
return true;
}
exports.wildcard = wildcard;
//# sourceMappingURL=wildcard.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"wildcard.js","sourceRoot":"","sources":["../../../src/matchers/wildcard.ts"],"names":[],"mappings":";;;AAAA,SAAgB,QAAQ;IACtB,OAAO,IAAI,CAAC;AACd,CAAC;AAFD,4BAEC"}

View File

@@ -0,0 +1,14 @@
/// <reference types="esquery" />
import type { Selector } from './index';
/**
* @public
* Parse a `string` into an ESQuery `Selector`.
*
* @param selector - a TSQuery `Selector` (using the [ESQuery selector syntax](https://github.com/estools/esquery)).
* @returns a validated `Selector` or `null` if the input `string` is invalid.
* @throws if the `Selector` is syntactically valid, but contains an invalid TypeScript Node kind.
*/
export declare function parse(selector: string): Selector | null;
export declare namespace parse {
var ensure: (selector: string | Selector) => Selector;
}

View File

@@ -0,0 +1,93 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.parse = void 0;
const esquery = __importStar(require("esquery"));
const typescript_1 = require("typescript");
const IDENTIFIER_QUERY = 'identifier';
/**
* @public
* Parse a `string` into an ESQuery `Selector`.
*
* @param selector - a TSQuery `Selector` (using the [ESQuery selector syntax](https://github.com/estools/esquery)).
* @returns a validated `Selector` or `null` if the input `string` is invalid.
* @throws if the `Selector` is syntactically valid, but contains an invalid TypeScript Node kind.
*/
function parse(selector) {
const cleanSelector = stripComments(stripNewLines(selector));
return validate(esquery.parse(cleanSelector));
}
exports.parse = parse;
/**
* @public
* Ensure that an input is a parsed ESQuery `Selector`.
*
* @param selector - a TSQuery `Selector` (using the [ESQuery selector syntax](https://github.com/estools/esquery)).
* @returns a validated `Selector`
* @throws if the input `string` is invalid.
*/
parse.ensure = function ensure(selector) {
if (isSelector(selector)) {
return selector;
}
const parsed = parse(selector);
if (!parsed) {
throw new SyntaxError(`"${selector}" is not a valid TSQuery Selector.`);
}
return parsed;
};
function isSelector(selector) {
return typeof selector !== 'string';
}
function stripComments(input) {
return input.replace(/\/\*[\w\W]*\*\//g, '');
}
function stripNewLines(input) {
return input.replace(/\n/g, '');
}
function validate(selector) {
if (!selector) {
return null;
}
const { selectors } = selector;
if (selectors) {
selectors.map(validate);
}
const { left, right } = selector;
if (left) {
validate(left);
}
if (right) {
validate(right);
}
if (selector.type === IDENTIFIER_QUERY) {
const { value } = selector;
if (typescript_1.SyntaxKind[value] == null) {
throw new SyntaxError(`"${value}" is not a valid TypeScript Node kind.`);
}
}
return selector;
}
//# sourceMappingURL=parse.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/parse.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,iDAAmC;AACnC,2CAAwC;AAExC,MAAM,gBAAgB,GAAG,YAAY,CAAC;AAEtC;;;;;;;GAOG;AACH,SAAgB,KAAK,CAAC,QAAgB;IACpC,MAAM,aAAa,GAAG,aAAa,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC7D,OAAO,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC;AAChD,CAAC;AAHD,sBAGC;AAED;;;;;;;GAOG;AACH,KAAK,CAAC,MAAM,GAAG,SAAS,MAAM,CAAC,QAA2B;IACxD,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE;QACxB,OAAO,QAAQ,CAAC;KACjB;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC/B,IAAI,CAAC,MAAM,EAAE;QACX,MAAM,IAAI,WAAW,CAAC,IAAI,QAAQ,oCAAoC,CAAC,CAAC;KACzE;IACD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,SAAS,UAAU,CAAC,QAA2B;IAC7C,OAAO,OAAO,QAAQ,KAAK,QAAQ,CAAC;AACtC,CAAC;AAED,SAAS,aAAa,CAAC,KAAa;IAClC,OAAO,KAAK,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;AAC/C,CAAC;AAED,SAAS,aAAa,CAAC,KAAa;IAClC,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAClC,CAAC;AAED,SAAS,QAAQ,CAAC,QAAkB;IAClC,IAAI,CAAC,QAAQ,EAAE;QACb,OAAO,IAAI,CAAC;KACb;IAED,MAAM,EAAE,SAAS,EAAE,GAAG,QAAyB,CAAC;IAChD,IAAI,SAAS,EAAE;QACb,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;KACzB;IACD,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,QAA0B,CAAC;IACnD,IAAI,IAAI,EAAE;QACR,QAAQ,CAAC,IAAI,CAAC,CAAC;KAChB;IACD,IAAI,KAAK,EAAE;QACT,QAAQ,CAAC,KAAK,CAAC,CAAC;KACjB;IAED,IAAK,QAAQ,CAAC,IAAe,KAAK,gBAAgB,EAAE;QAClD,MAAM,EAAE,KAAK,EAAE,GAAG,QAAsB,CAAC;QACzC,IAAI,uBAAU,CAAC,KAAgC,CAAC,IAAI,IAAI,EAAE;YACxD,MAAM,IAAI,WAAW,CAAC,IAAI,KAAK,wCAAwC,CAAC,CAAC;SAC1E;KACF;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}

View File

@@ -0,0 +1,11 @@
import type { PrinterOptions } from 'typescript';
import type { Node, SourceFile } from './index';
/**
* @public
* Print a given `Node` or `SourceFile` to a string, using the default TypeScript printer.
*
* @param source - the `Node` or `SourceFile` to print.
* @param options - any `PrinterOptions`.
* @returns the printed code
*/
export declare function print(source: Node | SourceFile, options?: PrinterOptions): string;

View File

@@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.print = void 0;
const typescript_1 = require("typescript");
const index_1 = require("./index");
/**
* @public
* Print a given `Node` or `SourceFile` to a string, using the default TypeScript printer.
*
* @param source - the `Node` or `SourceFile` to print.
* @param options - any `PrinterOptions`.
* @returns the printed code
*/
function print(source, options = {}) {
const printer = (0, typescript_1.createPrinter)(Object.assign({ newLine: typescript_1.NewLineKind.LineFeed }, options));
if (!(0, typescript_1.isSourceFile)(source)) {
const file = (0, index_1.ast)('');
deletePos(source);
return printer.printNode(typescript_1.EmitHint.Unspecified, source, file);
}
return printer.printFile(source).trim();
}
exports.print = print;
function deletePos(node) {
node.pos = -1;
node.forEachChild(deletePos);
}
//# sourceMappingURL=print.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"print.js","sourceRoot":"","sources":["../../src/print.ts"],"names":[],"mappings":";;;AAGA,2CAAgF;AAChF,mCAA8B;AAE9B;;;;;;;GAOG;AACH,SAAgB,KAAK,CACnB,MAAyB,EACzB,UAA0B,EAAE;IAE5B,MAAM,OAAO,GAAG,IAAA,0BAAa,kBAC3B,OAAO,EAAE,wBAAW,CAAC,QAAQ,IAC1B,OAAO,EACV,CAAC;IAEH,IAAI,CAAC,IAAA,yBAAY,EAAC,MAAM,CAAC,EAAE;QACzB,MAAM,IAAI,GAAG,IAAA,WAAG,EAAC,EAAE,CAAC,CAAC;QACrB,SAAS,CAAC,MAAM,CAAC,CAAC;QAClB,OAAO,OAAO,CAAC,SAAS,CAAC,qBAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;KAC9D;IAED,OAAO,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;AAC1C,CAAC;AAhBD,sBAgBC;AAMD,SAAS,SAAS,CAAC,IAAkB;IACnC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IACd,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;AAC/B,CAAC"}

View File

@@ -0,0 +1,17 @@
import { SourceFile } from './index';
/**
* @public
* Get all the `SourceFiles` included in a the TypeScript project described by a given config file.
*
* @param configFilePath - the path to the TypeScript config file, or a directory containing a `tsconfig.json` file.
* @returns an `Array` of the `SourceFiles` for all files in the project.
*/
export declare function project(configFilePath: string): Array<SourceFile>;
/**
* @public
* Get all the file paths included ina the TypeScript project described by a given config file.
*
* @param configFilePath - the path to the TypeScript config file, or a directory containing a `tsconfig.json` file.
* @returns an `Array` of the file paths for all files in the project.
*/
export declare function files(configFilePath: string): Array<string>;

View File

@@ -0,0 +1,93 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.files = exports.project = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const typescript_1 = require("typescript");
/**
* @public
* Get all the `SourceFiles` included in a the TypeScript project described by a given config file.
*
* @param configFilePath - the path to the TypeScript config file, or a directory containing a `tsconfig.json` file.
* @returns an `Array` of the `SourceFiles` for all files in the project.
*/
function project(configFilePath) {
const fullPath = findConfig(configFilePath);
if (fullPath) {
return getSourceFiles(fullPath);
}
return [];
}
exports.project = project;
/**
* @public
* Get all the file paths included ina the TypeScript project described by a given config file.
*
* @param configFilePath - the path to the TypeScript config file, or a directory containing a `tsconfig.json` file.
* @returns an `Array` of the file paths for all files in the project.
*/
function files(configFilePath) {
const fullPath = findConfig(configFilePath);
if (fullPath) {
return parseConfig(configFilePath).fileNames;
}
return [];
}
exports.files = files;
function findConfig(configFilePath) {
try {
const fullPath = path.resolve(process.cwd(), configFilePath);
// Throws if file does not exist:
const stats = fs.statSync(fullPath);
if (!stats.isDirectory()) {
return fullPath;
}
const inDirectoryPath = path.join(fullPath, 'tsconfig.json');
// Throws if file does not exist:
fs.accessSync(inDirectoryPath);
return inDirectoryPath;
}
catch (e) {
return null;
}
}
function getSourceFiles(configFilePath) {
const parsed = parseConfig(configFilePath);
const host = (0, typescript_1.createCompilerHost)(parsed.options, true);
const program = (0, typescript_1.createProgram)(parsed.fileNames, parsed.options, host);
return Array.from(program.getSourceFiles());
}
function parseConfig(configFilePath) {
const config = (0, typescript_1.readConfigFile)(configFilePath, typescript_1.sys.readFile.bind(typescript_1.sys));
const parseConfigHost = {
fileExists: typescript_1.sys.fileExists.bind(typescript_1.sys),
readDirectory: typescript_1.sys.readDirectory.bind(typescript_1.sys),
readFile: typescript_1.sys.readFile.bind(typescript_1.sys),
useCaseSensitiveFileNames: true
};
return (0, typescript_1.parseJsonConfigFileContent)(config.config, parseConfigHost, path.dirname(configFilePath), { noEmit: true });
}
//# sourceMappingURL=project.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/project.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,uCAAyB;AACzB,2CAA6B;AAC7B,2CAMoB;AAEpB;;;;;;GAMG;AACH,SAAgB,OAAO,CAAC,cAAsB;IAC5C,MAAM,QAAQ,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC;IAC5C,IAAI,QAAQ,EAAE;QACZ,OAAO,cAAc,CAAC,QAAQ,CAAC,CAAC;KACjC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAND,0BAMC;AAED;;;;;;GAMG;AACH,SAAgB,KAAK,CAAC,cAAsB;IAC1C,MAAM,QAAQ,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC;IAC5C,IAAI,QAAQ,EAAE;QACZ,OAAO,WAAW,CAAC,cAAc,CAAC,CAAC,SAAS,CAAC;KAC9C;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAND,sBAMC;AAED,SAAS,UAAU,CAAC,cAAsB;IACxC,IAAI;QACF,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC;QAC7D,iCAAiC;QACjC,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE;YACxB,OAAO,QAAQ,CAAC;SACjB;QACD,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;QAC7D,iCAAiC;QACjC,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;QAC/B,OAAO,eAAe,CAAC;KACxB;IAAC,OAAO,CAAC,EAAE;QACV,OAAO,IAAI,CAAC;KACb;AACH,CAAC;AAED,SAAS,cAAc,CAAC,cAAsB;IAC5C,MAAM,MAAM,GAAG,WAAW,CAAC,cAAc,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,IAAA,+BAAkB,EAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,IAAA,0BAAa,EAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAEtE,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,WAAW,CAAC,cAAsB;IACzC,MAAM,MAAM,GAAG,IAAA,2BAAc,EAAC,cAAc,EAAE,gBAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,gBAAG,CAAC,CAAC,CAAC;IAEtE,MAAM,eAAe,GAAoB;QACvC,UAAU,EAAE,gBAAG,CAAC,UAAU,CAAC,IAAI,CAAC,gBAAG,CAAC;QACpC,aAAa,EAAE,gBAAG,CAAC,aAAa,CAAC,IAAI,CAAC,gBAAG,CAAC;QAC1C,QAAQ,EAAE,gBAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,gBAAG,CAAC;QAChC,yBAAyB,EAAE,IAAI;KAChC,CAAC;IACF,OAAO,IAAA,uCAA0B,EAC/B,MAAM,CAAC,MAAM,EACb,eAAe,EACf,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,EAC5B,EAAE,MAAM,EAAE,IAAI,EAAE,CACjB,CAAC;AACJ,CAAC"}

View File

@@ -0,0 +1,13 @@
/// <reference types="esquery" />
import type { Node, ScriptKind, Selector } from './index';
/**
* @public
* Find AST `Nodes` within a given `string` of code or AST `Node` matching a `Selector`.
*
* @param code - the code to be searched. This could be a `string` of TypeScript code, a TypeScript [`SourceFile`](https://github.com/microsoft/TypeScript/blob/main/src/services/types.ts#L159), or a `Node` from a previous query.
* @param selector - a TSQuery `Selector` (using the [ESQuery selector syntax](https://github.com/estools/esquery)).
* @param scriptKind - the TypeScript [`ScriptKind`](https://github.com/microsoft/TypeScript/blob/main/src/compiler/types.ts#L7305) of the code. Only required when passing a `string` of code. Defaults to `ScriptKind.TSX`. Set this to `ScriptKind.TS` if your code uses the `<Type>` syntax for casting.
* @returns an `Array` of `Nodes` which match the `Selector`.
*/
export declare function query<T extends Node = Node>(code: string, selector: string | Selector, scriptKind?: ScriptKind): Array<T>;
export declare function query<T extends Node = Node>(code: Node, selector: string | Selector): Array<T>;

View File

@@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.query = void 0;
const index_1 = require("./index");
function query(code, selector, scriptKind) {
return (0, index_1.match)(index_1.ast.ensure(code, scriptKind), index_1.parse.ensure(selector));
}
exports.query = query;
//# sourceMappingURL=query.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"query.js","sourceRoot":"","sources":["../../src/query.ts"],"names":[],"mappings":";;;AAEA,mCAA4C;AAoB5C,SAAgB,KAAK,CACnB,IAAmB,EACnB,QAA2B,EAC3B,UAAuB;IAEvB,OAAO,IAAA,aAAK,EACV,WAAG,CAAC,MAAM,CAAC,IAAc,EAAE,UAAwB,CAAC,EACpD,aAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CACvB,CAAC;AACJ,CAAC;AATD,sBASC"}

View File

@@ -0,0 +1,13 @@
import type { StringTransformer } from './types';
import { ScriptKind } from './index';
/**
* @public
* Transform 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.
*
* @param node - the `Node` to be searched. This could be a TypeScript [`SourceFile`](https://github.com/microsoft/TypeScript/blob/main/src/services/types.ts#L159), or a Node from a previous selector.
* @param selector - a TSQuery `Selector` (using the [ESQuery selector syntax](https://github.com/estools/esquery)).
* @param stringTransformer - a function to transform any matched `Nodes`. If `null` is returned, there is no change. If a new `string` is returned, the original `Node` is replaced.
* @param scriptKind - the TypeScript [`ScriptKind`](https://github.com/microsoft/TypeScript/blob/main/src/compiler/types.ts#L7305) of the code. Defaults to `ScriptKind.TSX`. Set this to `ScriptKind.TS` if your code uses the `<Type>` syntax for casting.
* @returns a transformed `Node`.
*/
export declare function replace(source: string, selector: string, stringTransformer: StringTransformer, scriptKind?: ScriptKind): string;

View File

@@ -0,0 +1,33 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.replace = void 0;
const index_1 = require("./index");
const print_1 = require("./print");
/**
* @public
* Transform 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.
*
* @param node - the `Node` to be searched. This could be a TypeScript [`SourceFile`](https://github.com/microsoft/TypeScript/blob/main/src/services/types.ts#L159), or a Node from a previous selector.
* @param selector - a TSQuery `Selector` (using the [ESQuery selector syntax](https://github.com/estools/esquery)).
* @param stringTransformer - a function to transform any matched `Nodes`. If `null` is returned, there is no change. If a new `string` is returned, the original `Node` is replaced.
* @param scriptKind - the TypeScript [`ScriptKind`](https://github.com/microsoft/TypeScript/blob/main/src/compiler/types.ts#L7305) of the code. Defaults to `ScriptKind.TSX`. Set this to `ScriptKind.TS` if your code uses the `<Type>` syntax for casting.
* @returns a transformed `Node`.
*/
function replace(source, selector, stringTransformer, scriptKind) {
const matches = (0, index_1.query)(source, selector, scriptKind);
const replacements = matches.map((node) => stringTransformer(node));
const reversedMatches = matches.reverse();
const reversedReplacements = replacements.reverse();
let result = source;
reversedReplacements.forEach((replacement, index) => {
if (replacement != null) {
const match = reversedMatches[index];
const start = result.substring(0, match.getStart());
const end = result.substring(match.getEnd());
result = `${start}${replacement}${end}`;
}
});
return (0, print_1.print)((0, index_1.ast)(result, '', scriptKind));
}
exports.replace = replace;
//# sourceMappingURL=replace.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"replace.js","sourceRoot":"","sources":["../../src/replace.ts"],"names":[],"mappings":";;;AAEA,mCAAiD;AACjD,mCAAgC;AAEhC;;;;;;;;;GASG;AACH,SAAgB,OAAO,CACrB,MAAc,EACd,QAAgB,EAChB,iBAAoC,EACpC,UAAuB;IAEvB,MAAM,OAAO,GAAG,IAAA,aAAK,EAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;IACpD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC;IACpE,MAAM,eAAe,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAC1C,MAAM,oBAAoB,GAAG,YAAY,CAAC,OAAO,EAAE,CAAC;IAEpD,IAAI,MAAM,GAAG,MAAM,CAAC;IACpB,oBAAoB,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,KAAK,EAAE,EAAE;QAClD,IAAI,WAAW,IAAI,IAAI,EAAE;YACvB,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;YACrC,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;YACpD,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;YAC7C,MAAM,GAAG,GAAG,KAAK,GAAG,WAAW,GAAG,GAAG,EAAE,CAAC;SACzC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,IAAA,aAAK,EAAC,IAAA,WAAG,EAAC,MAAM,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC;AAC5C,CAAC;AArBD,0BAqBC"}

View File

@@ -0,0 +1,11 @@
import { SyntaxKind } from 'typescript';
/**
* @deprecated Will be removed in v7.
*
* @public
* Transform 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.
*
* @param kind - a [`SyntaxKind`](https://github.com/microsoft/TypeScript/blob/main/src/compiler/types.ts#L41) enum value.
* @returns the name of the `SyntaxKind`.
*/
export declare function syntaxKindName(kind: SyntaxKind): string;

View File

@@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.syntaxKindName = void 0;
const typescript_1 = require("typescript");
// See https://github.com/Microsoft/TypeScript/issues/18062
// Code inspired by https://github.com/fkling/astexplorer/blob/master/website/src/parsers/js/typescript.js
const SYNTAX_KIND_MAP = {};
for (const name of Object.keys(typescript_1.SyntaxKind).filter((x) => isNaN(parseInt(x, 10)))) {
const value = typescript_1.SyntaxKind[name];
if (!SYNTAX_KIND_MAP[value]) {
SYNTAX_KIND_MAP[value] = name;
}
}
/**
* @deprecated Will be removed in v7.
*
* @public
* Transform 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.
*
* @param kind - a [`SyntaxKind`](https://github.com/microsoft/TypeScript/blob/main/src/compiler/types.ts#L41) enum value.
* @returns the name of the `SyntaxKind`.
*/
function syntaxKindName(kind) {
return SYNTAX_KIND_MAP[kind];
}
exports.syntaxKindName = syntaxKindName;
//# sourceMappingURL=syntax-kind.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"syntax-kind.js","sourceRoot":"","sources":["../../src/syntax-kind.ts"],"names":[],"mappings":";;;AAAA,2CAAwC;AAExC,2DAA2D;AAC3D,0GAA0G;AAC1G,MAAM,eAAe,GAA2B,EAAE,CAAC;AAEnD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,uBAAU,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CACtD,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CACvB,EAAE;IACD,MAAM,KAAK,GAAG,uBAAU,CAAC,IAA+B,CAAC,CAAC;IAC1D,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE;QAC3B,eAAe,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;KAC/B;CACF;AAED;;;;;;;;GAQG;AACH,SAAgB,cAAc,CAAC,IAAgB;IAC7C,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC;AAFD,wCAEC"}

View File

@@ -0,0 +1,6 @@
/// <reference types="esquery" />
import type { Node, Selector } from './index';
import type { Properties } from './types';
export declare function findMatches(node: Node, selector: Selector, ancestors?: Array<Node>): boolean;
export declare function traverse(node: Node, iterator: (node: Node, ancestors: Array<Node>) => void, ancestors?: Array<Node>): void;
export declare function getProperties(node: Node): Properties;

View File

@@ -0,0 +1,81 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getProperties = exports.traverse = exports.findMatches = void 0;
const typescript_1 = require("typescript");
const syntax_kind_1 = require("./syntax-kind");
const matchers_1 = require("./matchers");
const LITERAL_KINDS = [
typescript_1.SyntaxKind.FalseKeyword,
typescript_1.SyntaxKind.NoSubstitutionTemplateLiteral,
typescript_1.SyntaxKind.NullKeyword,
typescript_1.SyntaxKind.NumericLiteral,
typescript_1.SyntaxKind.RegularExpressionLiteral,
typescript_1.SyntaxKind.StringLiteral,
typescript_1.SyntaxKind.TrueKeyword
];
const PARSERS = {
[typescript_1.SyntaxKind.FalseKeyword]: () => false,
[typescript_1.SyntaxKind.NoSubstitutionTemplateLiteral]: (properties) => properties.text,
[typescript_1.SyntaxKind.NullKeyword]: () => null,
[typescript_1.SyntaxKind.NumericLiteral]: (properties) => +properties.text,
[typescript_1.SyntaxKind.RegularExpressionLiteral]: (properties) => new RegExp(properties.text),
[typescript_1.SyntaxKind.StringLiteral]: (properties) => properties.text,
[typescript_1.SyntaxKind.TrueKeyword]: () => true
};
function findMatches(node, selector, ancestors = []) {
const matcher = matchers_1.MATCHERS[selector.type];
if (matcher) {
return matcher(node, selector, ancestors);
}
throw new SyntaxError(`Unknown selector type: ${selector.type}`);
}
exports.findMatches = findMatches;
function traverse(node, iterator, ancestors = []) {
if (node.parent != null) {
ancestors.unshift(node.parent);
}
iterator(node, ancestors);
let children = [];
try {
// We need to use `getChildren()` to traverse JSDoc nodes
children = node.getChildren();
}
catch (_a) {
// but it will fail for synthetic nodes, in which case we fall back:
node.forEachChild((child) => traverse(child, iterator, ancestors));
}
children.forEach((child) => traverse(child, iterator, ancestors));
ancestors.shift();
}
exports.traverse = traverse;
const propertiesMap = new WeakMap();
function getProperties(node) {
let properties = propertiesMap.get(node);
if (!properties) {
properties = {
kindName: (0, syntax_kind_1.syntaxKindName)(node.kind),
text: hasKey(node, 'text') ? node.text : getTextIfNotSynthesized(node)
};
if (node.kind === typescript_1.SyntaxKind.Identifier) {
properties.name = hasKey(node, 'name') ? node.name : properties.text;
}
if (LITERAL_KINDS.includes(node.kind)) {
properties.value = PARSERS[node.kind](properties);
}
propertiesMap.set(node, properties);
}
return properties;
}
exports.getProperties = getProperties;
function hasKey(node, property) {
return node[property] != null;
}
function getTextIfNotSynthesized(node) {
// getText cannot be called on synthesized nodes - those created using
// TypeScript's createXxx functions - because its implementation relies
// upon a node's position. See:
// https://github.com/microsoft/TypeScript/blob/a8bea77d1efe4984e573760770b78486a5488366/src/services/services.ts#L81-L87
// https://github.com/microsoft/TypeScript/blob/a685ac426c168a9d8734cac69202afc7cb022408/src/compiler/utilities.ts#L8169-L8173
return !(node.pos >= 0) ? '' : node.getText();
}
//# sourceMappingURL=traverse.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"traverse.js","sourceRoot":"","sources":["../../src/traverse.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,11 @@
import type { Node, VisitResult } from './index';
export type NodeTransformer = (node: Node) => VisitResult<Node | undefined>;
export type StringTransformer = (node: Node) => string | null;
export type AttributeOperatorType = 'regexp' | 'literal' | 'type';
export type AttributeOperator = (obj: unknown, value: unknown, type: AttributeOperatorType) => boolean;
export type Properties = {
kindName: string;
name?: string;
text: string;
value?: unknown;
};

View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=types.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":""}

View File

@@ -0,0 +1,4 @@
import type { Node } from 'typescript';
export declare function getPath(obj: unknown, path: string): unknown;
export declare function isNode(node: unknown): node is Node;
export declare function inPath(node: Node, ancestor: unknown, path: Array<string>): boolean;

View File

@@ -0,0 +1,42 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.inPath = exports.isNode = exports.getPath = void 0;
const traverse_1 = require("./traverse");
function getPath(obj, path) {
const keys = path.split('.');
for (const key of keys) {
if (obj == null) {
return obj;
}
const properties = isNode(obj) ? (0, traverse_1.getProperties)(obj) : {};
obj =
key in properties
? properties[key]
: obj[key];
}
return obj;
}
exports.getPath = getPath;
function isNode(node) {
return !!node.getSourceFile;
}
exports.isNode = isNode;
function inPath(node, ancestor, path) {
if (path.length === 0) {
return node === ancestor;
}
if (ancestor == null) {
return false;
}
const [first] = path;
const field = ancestor[first];
const remainingPath = path.slice(1);
if (Array.isArray(field)) {
return field.some((item) => inPath(node, item, remainingPath));
}
else {
return inPath(node, field, remainingPath);
}
}
exports.inPath = inPath;
//# sourceMappingURL=utils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":";;;AACA,yCAA2C;AAE3C,SAAgB,OAAO,CAAC,GAAY,EAAE,IAAY;IAChD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAE7B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE;QACtB,IAAI,GAAG,IAAI,IAAI,EAAE;YACf,OAAO,GAAG,CAAC;SACZ;QACD,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAA,wBAAa,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,GAAG;YACD,GAAG,IAAI,UAAU;gBACf,CAAC,CAAC,UAAU,CAAC,GAA8B,CAAC;gBAC5C,CAAC,CAAC,GAAG,CAAC,GAAuB,CAAC,CAAC;KACpC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAdD,0BAcC;AAED,SAAgB,MAAM,CAAC,IAAa;IAClC,OAAO,CAAC,CAAE,IAAa,CAAC,aAAa,CAAC;AACxC,CAAC;AAFD,wBAEC;AAED,SAAgB,MAAM,CACpB,IAAU,EACV,QAAiB,EACjB,IAAmB;IAEnB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;QACrB,OAAO,IAAI,KAAK,QAAQ,CAAC;KAC1B;IACD,IAAI,QAAQ,IAAI,IAAI,EAAE;QACpB,OAAO,KAAK,CAAC;KACd;IAED,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;IACrB,MAAM,KAAK,GAAG,QAAQ,CAAC,KAA8B,CAAY,CAAC;IAClE,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACpC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QACxB,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC;KACxE;SAAM;QACL,OAAO,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC;KAC3C;AACH,CAAC;AApBD,wBAoBC"}

62
node_modules/@phenomnomnominal/tsquery/package.json generated vendored Normal file
View File

@@ -0,0 +1,62 @@
{
"name": "@phenomnomnominal/tsquery",
"version": "6.2.0",
"description": "Query TypeScript ASTs with the esquery API!",
"main": "dist/src/index.js",
"typings": "dist/src/index.d.ts",
"author": "Craig Spence <craigspence0@gmail.com>",
"repository": {
"type": "git",
"url": "https://github.com/phenomnomnominal/tsquery"
},
"license": "MIT",
"scripts": {
"build": "npm run clean && npm run compile && npm run lint && npm run test",
"clean": "rimraf dist",
"compile": "tsc",
"lint": "npm run lint:src && npm run lint:test",
"lint:src": "eslint src/**/*.ts",
"lint:test": "eslint test/**/*.ts",
"lint:fix": "npm run lint:src:fix && npm run lint:test",
"lint:src:fix": "eslint src/**/*.ts --fix",
"lint:test:fix": "eslint test/**/*.ts --fix",
"test": "jest",
"test:debug": "node --inspect-brk ./node_modules/jest/bin/jest.js --runInBand --collectCoverage=false",
"prepublishOnly": "npm run build"
},
"dependencies": {
"@types/esquery": "^1.5.4",
"esquery": "^1.7.0"
},
"peerDependencies": {
"typescript": ">3.0.0"
},
"files": [
"dist/src"
],
"devDependencies": {
"@types/jest": "^29.5.2",
"@types/node": "^20.4.0",
"@typescript-eslint/eslint-plugin": "^5.61.0",
"@typescript-eslint/parser": "^5.61.0",
"eslint": "^8.44.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-import": "^2.26.0",
"jest": "^29.6.1",
"prettier": "^3.0.0",
"rimraf": "^3.0.2",
"ts-jest": "^29.1.1",
"typescript": "^5.1.6"
},
"jest": {
"collectCoverage": true,
"collectCoverageFrom": [
"<rootDir>/src/**"
],
"coverageDirectory": "<rootDir>/reports/coverage",
"transform": {
"\\.(ts)$": "ts-jest"
},
"testRegex": "/test/.*\\.spec\\.ts$"
}
}