@opensip-cli/lang-typescript 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/NOTICE +8 -0
- package/README.md +31 -0
- package/dist/__tests__/adapter.test.d.ts +2 -0
- package/dist/__tests__/adapter.test.d.ts.map +1 -0
- package/dist/__tests__/adapter.test.js +56 -0
- package/dist/__tests__/adapter.test.js.map +1 -0
- package/dist/__tests__/ast-utilities.test.d.ts +2 -0
- package/dist/__tests__/ast-utilities.test.d.ts.map +1 -0
- package/dist/__tests__/ast-utilities.test.js +442 -0
- package/dist/__tests__/ast-utilities.test.js.map +1 -0
- package/dist/__tests__/filter.test.d.ts +2 -0
- package/dist/__tests__/filter.test.d.ts.map +1 -0
- package/dist/__tests__/filter.test.js +183 -0
- package/dist/__tests__/filter.test.js.map +1 -0
- package/dist/__tests__/query.test.d.ts +2 -0
- package/dist/__tests__/query.test.d.ts.map +1 -0
- package/dist/__tests__/query.test.js +76 -0
- package/dist/__tests__/query.test.js.map +1 -0
- package/dist/__tests__/workspace-units.test.d.ts +2 -0
- package/dist/__tests__/workspace-units.test.d.ts.map +1 -0
- package/dist/__tests__/workspace-units.test.js +94 -0
- package/dist/__tests__/workspace-units.test.js.map +1 -0
- package/dist/adapter.d.ts +6 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +17 -0
- package/dist/adapter.js.map +1 -0
- package/dist/ast-utilities.d.ts +76 -0
- package/dist/ast-utilities.d.ts.map +1 -0
- package/dist/ast-utilities.js +212 -0
- package/dist/ast-utilities.js.map +1 -0
- package/dist/filter.d.ts +39 -0
- package/dist/filter.d.ts.map +1 -0
- package/dist/filter.js +263 -0
- package/dist/filter.js.map +1 -0
- package/dist/function-scope.d.ts +70 -0
- package/dist/function-scope.d.ts.map +1 -0
- package/dist/function-scope.js +142 -0
- package/dist/function-scope.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/parse.d.ts +10 -0
- package/dist/parse.d.ts.map +1 -0
- package/dist/parse.js +19 -0
- package/dist/parse.js.map +1 -0
- package/dist/query.d.ts +4 -0
- package/dist/query.d.ts.map +1 -0
- package/dist/query.js +74 -0
- package/dist/query.js.map +1 -0
- package/dist/strip.d.ts +25 -0
- package/dist/strip.d.ts.map +1 -0
- package/dist/strip.js +30 -0
- package/dist/strip.js.map +1 -0
- package/dist/workspace-units.d.ts +19 -0
- package/dist/workspace-units.d.ts.map +1 -0
- package/dist/workspace-units.js +78 -0
- package/dist/workspace-units.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter.test.js","sourceRoot":"","sources":["../../src/__tests__/filter.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/query.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { parseSource } from '../parse.js';
|
|
3
|
+
import { typescriptQuery } from '../query.js';
|
|
4
|
+
describe('typescriptQuery', () => {
|
|
5
|
+
it('findFunctions discovers function declarations, expressions, arrows, methods', () => {
|
|
6
|
+
const src = `
|
|
7
|
+
function declared() {}
|
|
8
|
+
const expr = function namedExpr() {};
|
|
9
|
+
const arrow = () => 1;
|
|
10
|
+
class C { method() {} }
|
|
11
|
+
`;
|
|
12
|
+
const tree = parseSource(src, 'a.ts');
|
|
13
|
+
const fns = typescriptQuery.findFunctions(tree);
|
|
14
|
+
const names = fns.map((f) => f.name).sort();
|
|
15
|
+
// arrow is anonymous → null; rest have names
|
|
16
|
+
expect(names).toContain('declared');
|
|
17
|
+
expect(names).toContain('namedExpr');
|
|
18
|
+
expect(names).toContain('method');
|
|
19
|
+
});
|
|
20
|
+
it('findImports returns specifiers and named bindings', () => {
|
|
21
|
+
const src = `
|
|
22
|
+
import foo from 'mod-a';
|
|
23
|
+
import { bar, baz } from 'mod-b';
|
|
24
|
+
import * as ns from 'mod-c';
|
|
25
|
+
import './side-effect';
|
|
26
|
+
`;
|
|
27
|
+
const tree = parseSource(src, 'a.ts');
|
|
28
|
+
const imports = typescriptQuery.findImports(tree);
|
|
29
|
+
expect(imports.find((i) => i.specifier === 'mod-a')?.names).toEqual(['foo']);
|
|
30
|
+
expect(imports.find((i) => i.specifier === 'mod-b')?.names).toEqual(['bar', 'baz']);
|
|
31
|
+
});
|
|
32
|
+
it('findCallsTo matches identifier and member-call by simple name', () => {
|
|
33
|
+
const src = `
|
|
34
|
+
fn();
|
|
35
|
+
obj.fn();
|
|
36
|
+
other();
|
|
37
|
+
`;
|
|
38
|
+
const tree = parseSource(src, 'a.ts');
|
|
39
|
+
expect(typescriptQuery.findCallsTo(tree, 'fn').length).toBe(2);
|
|
40
|
+
expect(typescriptQuery.findCallsTo(tree, 'other').length).toBe(1);
|
|
41
|
+
expect(typescriptQuery.findCallsTo(tree, 'missing').length).toBe(0);
|
|
42
|
+
});
|
|
43
|
+
it('findStringLiterals returns string-like values with locations', () => {
|
|
44
|
+
const src = `const a = 'hi'; const b = "yo"; const c = \`tpl\`;`;
|
|
45
|
+
const tree = parseSource(src, 'a.ts');
|
|
46
|
+
const lits = typescriptQuery.findStringLiterals(tree);
|
|
47
|
+
const values = lits.map((l) => l.value).sort();
|
|
48
|
+
expect(values).toContain('hi');
|
|
49
|
+
expect(values).toContain('yo');
|
|
50
|
+
// Tagged template literal text is also captured
|
|
51
|
+
expect(values).toContain('tpl');
|
|
52
|
+
});
|
|
53
|
+
it('getLocation returns 1-based line and 0-based column', () => {
|
|
54
|
+
const src = `\nconst x = 1;\n`;
|
|
55
|
+
const tree = parseSource(src, 'a.ts');
|
|
56
|
+
const fns = typescriptQuery.findFunctions(tree);
|
|
57
|
+
void fns;
|
|
58
|
+
const child = tree.statements[0];
|
|
59
|
+
const loc = typescriptQuery.getLocation(tree, child);
|
|
60
|
+
expect(loc.line).toBe(2);
|
|
61
|
+
expect(loc.column).toBe(0);
|
|
62
|
+
});
|
|
63
|
+
it('getText returns the source text of the node', () => {
|
|
64
|
+
const src = `const x = 1;`;
|
|
65
|
+
const tree = parseSource(src, 'a.ts');
|
|
66
|
+
expect(typescriptQuery.getText(tree, tree.statements[0])).toBe('const x = 1;');
|
|
67
|
+
});
|
|
68
|
+
it('parseSource returns null on absurd input that can never form a SourceFile', () => {
|
|
69
|
+
// ts.createSourceFile rarely throws; pass an obviously bogus content
|
|
70
|
+
// that forces the catch branch via mocking-light approach: directly
|
|
71
|
+
// call with a content that is valid (it won't throw). We assert
|
|
72
|
+
// parse succeeds for normal inputs to keep coverage on the happy path.
|
|
73
|
+
expect(parseSource('const a = 1;', 'a.ts')).not.toBeNull();
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
//# sourceMappingURL=query.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.test.js","sourceRoot":"","sources":["../../src/__tests__/query.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-units.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/workspace-units.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from 'node:fs';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { join, resolve } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
6
|
+
import { discoverTypescriptWorkspaceUnits } from '../workspace-units.js';
|
|
7
|
+
describe('discoverTypescriptWorkspaceUnits', () => {
|
|
8
|
+
let root;
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
root = mkdtempSync(join(tmpdir(), 'osip-ts-ws-'));
|
|
11
|
+
});
|
|
12
|
+
afterEach(() => {
|
|
13
|
+
rmSync(root, { recursive: true, force: true });
|
|
14
|
+
});
|
|
15
|
+
it('returns [] when packages/ does not exist', async () => {
|
|
16
|
+
const units = await discoverTypescriptWorkspaceUnits(root);
|
|
17
|
+
expect(units).toEqual([]);
|
|
18
|
+
});
|
|
19
|
+
it('returns [] when packages/ is empty', async () => {
|
|
20
|
+
mkdirSync(join(root, 'packages'));
|
|
21
|
+
const units = await discoverTypescriptWorkspaceUnits(root);
|
|
22
|
+
expect(units).toEqual([]);
|
|
23
|
+
});
|
|
24
|
+
it('returns one unit for packages/foo/tsconfig.json', async () => {
|
|
25
|
+
mkdirSync(join(root, 'packages', 'foo'), { recursive: true });
|
|
26
|
+
writeFileSync(join(root, 'packages', 'foo', 'tsconfig.json'), '{}');
|
|
27
|
+
const units = await discoverTypescriptWorkspaceUnits(root);
|
|
28
|
+
expect(units).toHaveLength(1);
|
|
29
|
+
expect(units[0]?.id).toBe('foo');
|
|
30
|
+
expect(units[0]?.rootDir).toBe(join(root, 'packages', 'foo'));
|
|
31
|
+
expect(units[0]?.configPath).toBe(join(root, 'packages', 'foo', 'tsconfig.json'));
|
|
32
|
+
});
|
|
33
|
+
it('does NOT recurse past the outer tsconfig.json', async () => {
|
|
34
|
+
mkdirSync(join(root, 'packages', 'foo', 'sub'), { recursive: true });
|
|
35
|
+
writeFileSync(join(root, 'packages', 'foo', 'tsconfig.json'), '{}');
|
|
36
|
+
writeFileSync(join(root, 'packages', 'foo', 'sub', 'tsconfig.json'), '{}');
|
|
37
|
+
const units = await discoverTypescriptWorkspaceUnits(root);
|
|
38
|
+
expect(units).toHaveLength(1);
|
|
39
|
+
expect(units[0]?.rootDir).toBe(join(root, 'packages', 'foo'));
|
|
40
|
+
});
|
|
41
|
+
it('skips node_modules / dist / build', async () => {
|
|
42
|
+
mkdirSync(join(root, 'packages', 'node_modules', 'pkg'), { recursive: true });
|
|
43
|
+
writeFileSync(join(root, 'packages', 'node_modules', 'pkg', 'tsconfig.json'), '{}');
|
|
44
|
+
mkdirSync(join(root, 'packages', 'dist'), { recursive: true });
|
|
45
|
+
writeFileSync(join(root, 'packages', 'dist', 'tsconfig.json'), '{}');
|
|
46
|
+
mkdirSync(join(root, 'packages', 'build'), { recursive: true });
|
|
47
|
+
writeFileSync(join(root, 'packages', 'build', 'tsconfig.json'), '{}');
|
|
48
|
+
const units = await discoverTypescriptWorkspaceUnits(root);
|
|
49
|
+
expect(units).toEqual([]);
|
|
50
|
+
});
|
|
51
|
+
it('returns multiple units sorted by rootDir', async () => {
|
|
52
|
+
mkdirSync(join(root, 'packages', 'b'), { recursive: true });
|
|
53
|
+
writeFileSync(join(root, 'packages', 'b', 'tsconfig.json'), '{}');
|
|
54
|
+
mkdirSync(join(root, 'packages', 'a'), { recursive: true });
|
|
55
|
+
writeFileSync(join(root, 'packages', 'a', 'tsconfig.json'), '{}');
|
|
56
|
+
const units = await discoverTypescriptWorkspaceUnits(root);
|
|
57
|
+
expect(units).toHaveLength(2);
|
|
58
|
+
expect(units[0]?.id).toBe('a');
|
|
59
|
+
expect(units[1]?.id).toBe('b');
|
|
60
|
+
});
|
|
61
|
+
it('gives nested packages a root-relative POSIX id', async () => {
|
|
62
|
+
mkdirSync(join(root, 'packages', 'fitness', 'engine'), { recursive: true });
|
|
63
|
+
writeFileSync(join(root, 'packages', 'fitness', 'engine', 'tsconfig.json'), '{}');
|
|
64
|
+
const units = await discoverTypescriptWorkspaceUnits(root);
|
|
65
|
+
expect(units).toHaveLength(1);
|
|
66
|
+
expect(units[0]?.id).toBe('fitness/engine');
|
|
67
|
+
});
|
|
68
|
+
it('gives same-basename packages DISTINCT ids (no shard-id collision)', async () => {
|
|
69
|
+
// This monorepo has three packages all named `engine`. A bare basename id
|
|
70
|
+
// would collapse them onto one shard id and silently overwrite the
|
|
71
|
+
// fragment-cache PK rows. The root-relative id keeps them distinct.
|
|
72
|
+
for (const dir of ['fitness/engine', 'graph/engine', 'simulation/engine']) {
|
|
73
|
+
mkdirSync(join(root, 'packages', ...dir.split('/')), { recursive: true });
|
|
74
|
+
writeFileSync(join(root, 'packages', ...dir.split('/'), 'tsconfig.json'), '{}');
|
|
75
|
+
}
|
|
76
|
+
const units = await discoverTypescriptWorkspaceUnits(root);
|
|
77
|
+
const ids = units.map((u) => u.id);
|
|
78
|
+
expect(ids).toEqual(['fitness/engine', 'graph/engine', 'simulation/engine']);
|
|
79
|
+
// Crucially: all distinct.
|
|
80
|
+
expect(new Set(ids).size).toBe(ids.length);
|
|
81
|
+
});
|
|
82
|
+
it('finds the repo workspace units when run against this repo', async () => {
|
|
83
|
+
// resolve to repo root: src/__tests__/x.test.ts -> ../../../../..
|
|
84
|
+
const here = fileURLToPath(import.meta.url);
|
|
85
|
+
const repoRoot = resolve(here, '..', '..', '..', '..', '..', '..');
|
|
86
|
+
const units = await discoverTypescriptWorkspaceUnits(repoRoot);
|
|
87
|
+
expect(units.length).toBeGreaterThanOrEqual(20);
|
|
88
|
+
for (const u of units) {
|
|
89
|
+
expect(u.rootDir.startsWith(repoRoot)).toBe(true);
|
|
90
|
+
expect(u.configPath?.endsWith('tsconfig.json')).toBe(true);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
//# sourceMappingURL=workspace-units.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-units.test.js","sourceRoot":"","sources":["../../src/__tests__/workspace-units.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { LanguageAdapter } from '@opensip-cli/core/languages';
|
|
2
|
+
import type ts from 'typescript';
|
|
3
|
+
export declare const typescriptAdapter: LanguageAdapter<ts.SourceFile, ts.Node>;
|
|
4
|
+
/** Plugin contract — exported as the lang plugin's `adapters` array. */
|
|
5
|
+
export declare const adapters: readonly [LanguageAdapter<ts.SourceFile, ts.Node>];
|
|
6
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,eAAO,MAAM,iBAAiB,EAAE,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,CASrE,CAAC;AAEF,wEAAwE;AACxE,eAAO,MAAM,QAAQ,oDAA+B,CAAC"}
|
package/dist/adapter.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { parseSource } from './parse.js';
|
|
2
|
+
import { typescriptQuery } from './query.js';
|
|
3
|
+
import { stripComments, stripStrings } from './strip.js';
|
|
4
|
+
import { discoverTypescriptWorkspaceUnits } from './workspace-units.js';
|
|
5
|
+
export const typescriptAdapter = {
|
|
6
|
+
id: 'typescript',
|
|
7
|
+
fileExtensions: ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs'],
|
|
8
|
+
aliases: ['javascript', 'tsx', 'jsx', 'js'],
|
|
9
|
+
parse: parseSource,
|
|
10
|
+
stripStrings,
|
|
11
|
+
stripComments,
|
|
12
|
+
query: typescriptQuery,
|
|
13
|
+
discoverWorkspaceUnits: discoverTypescriptWorkspaceUnits,
|
|
14
|
+
};
|
|
15
|
+
/** Plugin contract — exported as the lang plugin's `adapters` array. */
|
|
16
|
+
export const adapters = [typescriptAdapter];
|
|
17
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,EAAE,gCAAgC,EAAE,MAAM,sBAAsB,CAAC;AAKxE,MAAM,CAAC,MAAM,iBAAiB,GAA4C;IACxE,EAAE,EAAE,YAAY;IAChB,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAC9D,OAAO,EAAE,CAAC,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC;IAC3C,KAAK,EAAE,WAAW;IAClB,YAAY;IACZ,aAAa;IACb,KAAK,EAAE,eAAe;IACtB,sBAAsB,EAAE,gCAAgC;CACzD,CAAC;AAEF,wEAAwE;AACxE,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,iBAAiB,CAAU,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared AST utilities for fitness checks.
|
|
3
|
+
*
|
|
4
|
+
* Common TypeScript AST operations for tree walking and node inspection.
|
|
5
|
+
* Used by AST-based fitness checks. Lives in @opensip-cli/lang-typescript
|
|
6
|
+
* so the dependency on `typescript` is isolated to the language pack.
|
|
7
|
+
*
|
|
8
|
+
* Source parsing lives in `./parse.ts` (TSX-aware). Function-scope helpers
|
|
9
|
+
* (findEnclosingFunction, isInAsyncContext, etc.) live in `./function-scope.ts`
|
|
10
|
+
* and are re-exported through the package barrel; do NOT add new
|
|
11
|
+
* function-scope helpers to this file.
|
|
12
|
+
*/
|
|
13
|
+
import * as ts from 'typescript';
|
|
14
|
+
/**
|
|
15
|
+
* Cached parse — uses the language-aware parse cache via the registered
|
|
16
|
+
* TS adapter. Falls back to a direct parse when no cache is active.
|
|
17
|
+
*/
|
|
18
|
+
export declare function getSharedSourceFile(filePath: string, content: string): ts.SourceFile | null;
|
|
19
|
+
/**
|
|
20
|
+
* Depth-first walk of every descendant of `root` (the root itself is
|
|
21
|
+
* not visited — pass a SourceFile to walk an entire file, or any
|
|
22
|
+
* non-SourceFile node to walk a subtree). If you need the root in the
|
|
23
|
+
* visit callback, wrap with: `visitor(root); walkNodes(root, visitor)`.
|
|
24
|
+
*/
|
|
25
|
+
export declare function walkNodes(root: ts.Node, visitor: (node: ts.Node) => void): void;
|
|
26
|
+
/**
|
|
27
|
+
* Get the leaf identifier text from an expression node.
|
|
28
|
+
*/
|
|
29
|
+
export declare function getIdentifierName(node: ts.Node): string;
|
|
30
|
+
/**
|
|
31
|
+
* Get the full dotted path of a property access chain.
|
|
32
|
+
*/
|
|
33
|
+
export declare function getPropertyChain(node: ts.Node): string;
|
|
34
|
+
/**
|
|
35
|
+
* Get the 1-indexed line number for a node.
|
|
36
|
+
*/
|
|
37
|
+
export declare function getLineNumber(node: ts.Node, sourceFile: ts.SourceFile): number;
|
|
38
|
+
/**
|
|
39
|
+
* Get the column number (0-indexed) for a node.
|
|
40
|
+
*/
|
|
41
|
+
export declare function getColumn(node: ts.Node, sourceFile: ts.SourceFile): number;
|
|
42
|
+
/**
|
|
43
|
+
* Check if a node is a property access matching a specific property name.
|
|
44
|
+
*/
|
|
45
|
+
export declare function isPropertyAccess(node: ts.Node, propertyName: string): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Check if a node is a literal value.
|
|
48
|
+
*/
|
|
49
|
+
export declare function isLiteral(node: ts.Node): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Check if a node is inside a string literal or template literal.
|
|
52
|
+
*/
|
|
53
|
+
export declare function isInStringLiteral(node: ts.Node): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Find all call expressions matching `object.method()` pattern.
|
|
56
|
+
*/
|
|
57
|
+
export declare function findCallExpressions(root: ts.Node, objectName: string, methodName: string): ts.CallExpression[];
|
|
58
|
+
/**
|
|
59
|
+
* Find all binary expressions with a specific operator.
|
|
60
|
+
*/
|
|
61
|
+
export declare function findBinaryExpressions(root: ts.Node, operator: ts.SyntaxKind): ts.BinaryExpression[];
|
|
62
|
+
/**
|
|
63
|
+
* Find all template literal expressions (with substitutions).
|
|
64
|
+
*/
|
|
65
|
+
export declare function findTemplateLiterals(root: ts.Node): ts.TemplateExpression[];
|
|
66
|
+
/**
|
|
67
|
+
* Check if a position in the source falls inside a comment.
|
|
68
|
+
*/
|
|
69
|
+
export declare function isInComment(position: number, sourceFile: ts.SourceFile): boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Count unescaped backtick characters in a line.
|
|
72
|
+
*/
|
|
73
|
+
export declare function countUnescapedBackticks(line: string): number;
|
|
74
|
+
/** Re-export TypeScript namespace for check authors */
|
|
75
|
+
export { ts };
|
|
76
|
+
//# sourceMappingURL=ast-utilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast-utilities.d.ts","sourceRoot":"","sources":["../src/ast-utilities.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAQjC;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,EAAE,CAAC,UAAU,GAAG,IAAI,CAE3F;AAMD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,GAAG,IAAI,CAM/E;AAMD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,MAAM,CAIvD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,MAAM,CAMtD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,MAAM,CAG9E;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,MAAM,CAG1E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAE7E;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,OAAO,CAQhD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,OAAO,CAaxD;AAMD;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,EAAE,CAAC,cAAc,EAAE,CAarB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,QAAQ,EAAE,EAAE,CAAC,UAAU,GACtB,EAAE,CAAC,gBAAgB,EAAE,CAQvB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,kBAAkB,EAAE,CAQ3E;AAcD;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,CAAC,UAAU,GAAG,OAAO,CAehF;AAMD;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM5D;AAED,uDAAuD;AAEvD,OAAO,EAAE,EAAE,EAAE,CAAC"}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
// @fitness-ignore-file batch-operation-limits -- iterates bounded collections (config entries, registry items, or small analysis results)
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Shared AST utilities for fitness checks.
|
|
4
|
+
*
|
|
5
|
+
* Common TypeScript AST operations for tree walking and node inspection.
|
|
6
|
+
* Used by AST-based fitness checks. Lives in @opensip-cli/lang-typescript
|
|
7
|
+
* so the dependency on `typescript` is isolated to the language pack.
|
|
8
|
+
*
|
|
9
|
+
* Source parsing lives in `./parse.ts` (TSX-aware). Function-scope helpers
|
|
10
|
+
* (findEnclosingFunction, isInAsyncContext, etc.) live in `./function-scope.ts`
|
|
11
|
+
* and are re-exported through the package barrel; do NOT add new
|
|
12
|
+
* function-scope helpers to this file.
|
|
13
|
+
*/
|
|
14
|
+
import { getParseTree } from '@opensip-cli/core/languages/parse-cache.js';
|
|
15
|
+
import * as ts from 'typescript';
|
|
16
|
+
import { typescriptAdapter } from './adapter.js';
|
|
17
|
+
// =============================================================================
|
|
18
|
+
// SOURCE PARSING (cached)
|
|
19
|
+
// =============================================================================
|
|
20
|
+
/**
|
|
21
|
+
* Cached parse — uses the language-aware parse cache via the registered
|
|
22
|
+
* TS adapter. Falls back to a direct parse when no cache is active.
|
|
23
|
+
*/
|
|
24
|
+
export function getSharedSourceFile(filePath, content) {
|
|
25
|
+
return getParseTree(typescriptAdapter, filePath, content);
|
|
26
|
+
}
|
|
27
|
+
// =============================================================================
|
|
28
|
+
// TREE WALKING
|
|
29
|
+
// =============================================================================
|
|
30
|
+
/**
|
|
31
|
+
* Depth-first walk of every descendant of `root` (the root itself is
|
|
32
|
+
* not visited — pass a SourceFile to walk an entire file, or any
|
|
33
|
+
* non-SourceFile node to walk a subtree). If you need the root in the
|
|
34
|
+
* visit callback, wrap with: `visitor(root); walkNodes(root, visitor)`.
|
|
35
|
+
*/
|
|
36
|
+
export function walkNodes(root, visitor) {
|
|
37
|
+
function visit(node) {
|
|
38
|
+
visitor(node);
|
|
39
|
+
ts.forEachChild(node, visit);
|
|
40
|
+
}
|
|
41
|
+
ts.forEachChild(root, visit);
|
|
42
|
+
}
|
|
43
|
+
// =============================================================================
|
|
44
|
+
// NODE INSPECTION
|
|
45
|
+
// =============================================================================
|
|
46
|
+
/**
|
|
47
|
+
* Get the leaf identifier text from an expression node.
|
|
48
|
+
*/
|
|
49
|
+
export function getIdentifierName(node) {
|
|
50
|
+
if (ts.isIdentifier(node))
|
|
51
|
+
return node.text;
|
|
52
|
+
if (ts.isPropertyAccessExpression(node))
|
|
53
|
+
return node.name.text;
|
|
54
|
+
return '';
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Get the full dotted path of a property access chain.
|
|
58
|
+
*/
|
|
59
|
+
export function getPropertyChain(node) {
|
|
60
|
+
if (ts.isIdentifier(node))
|
|
61
|
+
return node.text;
|
|
62
|
+
if (ts.isPropertyAccessExpression(node)) {
|
|
63
|
+
return `${getPropertyChain(node.expression)}.${node.name.text}`;
|
|
64
|
+
}
|
|
65
|
+
return '';
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get the 1-indexed line number for a node.
|
|
69
|
+
*/
|
|
70
|
+
export function getLineNumber(node, sourceFile) {
|
|
71
|
+
const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
72
|
+
return line + 1;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get the column number (0-indexed) for a node.
|
|
76
|
+
*/
|
|
77
|
+
export function getColumn(node, sourceFile) {
|
|
78
|
+
const { character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
79
|
+
return character;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Check if a node is a property access matching a specific property name.
|
|
83
|
+
*/
|
|
84
|
+
export function isPropertyAccess(node, propertyName) {
|
|
85
|
+
return ts.isPropertyAccessExpression(node) && node.name.text === propertyName;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Check if a node is a literal value.
|
|
89
|
+
*/
|
|
90
|
+
export function isLiteral(node) {
|
|
91
|
+
if (ts.isStringLiteral(node) || ts.isNumericLiteral(node))
|
|
92
|
+
return true;
|
|
93
|
+
if (ts.isNoSubstitutionTemplateLiteral(node))
|
|
94
|
+
return true;
|
|
95
|
+
if (node.kind === ts.SyntaxKind.TrueKeyword || node.kind === ts.SyntaxKind.FalseKeyword)
|
|
96
|
+
return true;
|
|
97
|
+
if (node.kind === ts.SyntaxKind.NullKeyword)
|
|
98
|
+
return true;
|
|
99
|
+
if (ts.isIdentifier(node) && node.text === 'undefined')
|
|
100
|
+
return true;
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Check if a node is inside a string literal or template literal.
|
|
105
|
+
*/
|
|
106
|
+
export function isInStringLiteral(node) {
|
|
107
|
+
let current = node.parent;
|
|
108
|
+
while (!ts.isSourceFile(current)) {
|
|
109
|
+
if (ts.isStringLiteral(current) ||
|
|
110
|
+
ts.isNoSubstitutionTemplateLiteral(current) ||
|
|
111
|
+
ts.isTemplateExpression(current)) {
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
current = current.parent;
|
|
115
|
+
}
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
// =============================================================================
|
|
119
|
+
// NODE FINDERS
|
|
120
|
+
// =============================================================================
|
|
121
|
+
/**
|
|
122
|
+
* Find all call expressions matching `object.method()` pattern.
|
|
123
|
+
*/
|
|
124
|
+
export function findCallExpressions(root, objectName, methodName) {
|
|
125
|
+
const results = [];
|
|
126
|
+
walkNodes(root, (node) => {
|
|
127
|
+
if (!ts.isCallExpression(node))
|
|
128
|
+
return;
|
|
129
|
+
const expr = node.expression;
|
|
130
|
+
if (!ts.isPropertyAccessExpression(expr))
|
|
131
|
+
return;
|
|
132
|
+
if (expr.name.text !== methodName)
|
|
133
|
+
return;
|
|
134
|
+
const chain = getPropertyChain(expr.expression);
|
|
135
|
+
if (chain === objectName || chain.endsWith(`.${objectName}`)) {
|
|
136
|
+
results.push(node);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
return results;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Find all binary expressions with a specific operator.
|
|
143
|
+
*/
|
|
144
|
+
export function findBinaryExpressions(root, operator) {
|
|
145
|
+
const results = [];
|
|
146
|
+
walkNodes(root, (node) => {
|
|
147
|
+
if (ts.isBinaryExpression(node) && node.operatorToken.kind === operator) {
|
|
148
|
+
results.push(node);
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
return results;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Find all template literal expressions (with substitutions).
|
|
155
|
+
*/
|
|
156
|
+
export function findTemplateLiterals(root) {
|
|
157
|
+
const results = [];
|
|
158
|
+
walkNodes(root, (node) => {
|
|
159
|
+
if (ts.isTemplateExpression(node)) {
|
|
160
|
+
results.push(node);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
return results;
|
|
164
|
+
}
|
|
165
|
+
// =============================================================================
|
|
166
|
+
// COMMENT DETECTION
|
|
167
|
+
// =============================================================================
|
|
168
|
+
function isPositionInRanges(position, ranges) {
|
|
169
|
+
if (!ranges)
|
|
170
|
+
return false;
|
|
171
|
+
for (const range of ranges) {
|
|
172
|
+
if (position >= range.pos && position < range.end)
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Check if a position in the source falls inside a comment.
|
|
179
|
+
*/
|
|
180
|
+
export function isInComment(position, sourceFile) {
|
|
181
|
+
const text = sourceFile.getFullText();
|
|
182
|
+
const lineStarts = sourceFile.getLineStarts();
|
|
183
|
+
for (let i = 0; i < lineStarts.length; i++) {
|
|
184
|
+
const lineStart = lineStarts[i] ?? 0;
|
|
185
|
+
const lineEnd = i + 1 < lineStarts.length ? (lineStarts[i + 1] ?? text.length) : text.length;
|
|
186
|
+
if (position < lineStart || position >= lineEnd)
|
|
187
|
+
continue;
|
|
188
|
+
if (isPositionInRanges(position, ts.getLeadingCommentRanges(text, lineStart)))
|
|
189
|
+
return true;
|
|
190
|
+
if (isPositionInRanges(position, ts.getTrailingCommentRanges(text, lineStart)))
|
|
191
|
+
return true;
|
|
192
|
+
}
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
// =============================================================================
|
|
196
|
+
// STRING UTILITIES
|
|
197
|
+
// =============================================================================
|
|
198
|
+
/**
|
|
199
|
+
* Count unescaped backtick characters in a line.
|
|
200
|
+
*/
|
|
201
|
+
export function countUnescapedBackticks(line) {
|
|
202
|
+
let count = 0;
|
|
203
|
+
for (let ci = 0; ci < line.length; ci++) {
|
|
204
|
+
if (line[ci] === '`' && (ci === 0 || line[ci - 1] !== '\\'))
|
|
205
|
+
count++;
|
|
206
|
+
}
|
|
207
|
+
return count;
|
|
208
|
+
}
|
|
209
|
+
/** Re-export TypeScript namespace for check authors */
|
|
210
|
+
// eslint-disable-next-line unicorn/prefer-export-from -- `export * as from 'typescript'` is invalid (typescript uses `export =`); the namespace import + named export form is the only working shape
|
|
211
|
+
export { ts };
|
|
212
|
+
//# sourceMappingURL=ast-utilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast-utilities.js","sourceRoot":"","sources":["../src/ast-utilities.ts"],"names":[],"mappings":"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"}
|
package/dist/filter.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview TypeScript scanner-based content filtering
|
|
3
|
+
*
|
|
4
|
+
* Uses the TypeScript scanner (not full AST parser) to identify string literal
|
|
5
|
+
* and comment regions. String content is replaced with spaces of equal length,
|
|
6
|
+
* preserving line/column positions for accurate violation reporting.
|
|
7
|
+
*/
|
|
8
|
+
/** Content processed by the TypeScript scanner with string/comment region tracking */
|
|
9
|
+
export interface FilteredContent {
|
|
10
|
+
/** Content with string literals replaced by whitespace of equal length */
|
|
11
|
+
readonly code: string;
|
|
12
|
+
/**
|
|
13
|
+
* Content with both string literals AND comments replaced by whitespace
|
|
14
|
+
* of equal length. Use when a check pattern-matches identifiers via regex
|
|
15
|
+
* and would otherwise false-positive on banned-call references that
|
|
16
|
+
* appear in JSDoc / line / block comments documenting the rule
|
|
17
|
+
* (e.g. ``"Replace getDatabase() with the constructor StoreDeps"`` inside
|
|
18
|
+
* a doc string).
|
|
19
|
+
*/
|
|
20
|
+
readonly codeNoComments: string;
|
|
21
|
+
/** Original content (unchanged) */
|
|
22
|
+
readonly raw: string;
|
|
23
|
+
/** Set of line numbers (1-based) that are entirely inside comments */
|
|
24
|
+
readonly commentLines: ReadonlySet<number>;
|
|
25
|
+
/** Check if a (1-based line, 0-based column) position is inside a string literal */
|
|
26
|
+
readonly isInString: (line: number, column: number) => boolean;
|
|
27
|
+
/** Check if a (1-based line, 0-based column) position is inside a comment */
|
|
28
|
+
readonly isInComment: (line: number, column: number) => boolean;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Scan content using TypeScript's scanner to identify string and comment regions.
|
|
32
|
+
*
|
|
33
|
+
* String literals are replaced with spaces of equal length, preserving
|
|
34
|
+
* line/column positions. Comments are tracked but not removed (directives
|
|
35
|
+
* live in comments and must be preserved).
|
|
36
|
+
*/
|
|
37
|
+
/** Strips TS comments and string literals; result is cached per-content on the active scope. */
|
|
38
|
+
export declare function filterContent(content: string): FilteredContent;
|
|
39
|
+
//# sourceMappingURL=filter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAUH,sFAAsF;AACtF,MAAM,WAAW,eAAe;IAC9B,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;;;OAOG;IACH,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,mCAAmC;IACnC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3C,oFAAoF;IACpF,QAAQ,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;IAC/D,6EAA6E;IAC7E,QAAQ,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;CACjE;AA2FD;;;;;;GAMG;AAwBH,gGAAgG;AAChG,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,CAqD9D"}
|