@ts-stack/cycle-detector 1.0.4 → 1.1.1
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/README.md +80 -16
- package/dist/index.js +225 -82
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +253 -116
package/README.md
CHANGED
|
@@ -1,20 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Execution-Aware Circular Dependency Detector for TypeScript
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`@ts-stack/cycle-detector` - this is a high-performance static analysis utility powered by the native TypeScript Compiler API. Unlike generic dependency visualizers, this tool evaluates the **runtime execution risk** of circular dependencies in monorepos and complex TypeScript applications, isolating architectural flaws from safe, deferred imports.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
## Features
|
|
8
|
-
|
|
9
|
-
- ⚡ **Blazing Fast**: Uses static AST parsing without full type-checking overhead.
|
|
10
|
-
- 🧠 **Smart Resolution**: Fully supports `tsconfig.json` `paths`, path mappings, and ESM extensions out of the box.
|
|
11
|
-
- 🧱 **Monorepo & Glob Support**: Can check multiple packages at once using wildcards.
|
|
12
|
-
- 🛑 **Type-Safe**: Intelligently skips `import type` and type-only named bindings.
|
|
13
|
-
- 🤖 **CI/CD Ready**: Returns non-zero exit codes when cycles are found.
|
|
14
|
-
|
|
15
|
-
Note: required Node.js >= v22.0.0.
|
|
16
|
-
|
|
17
|
-
## Installation
|
|
5
|
+
## Installation & Usage
|
|
18
6
|
|
|
19
7
|
You don't even need to install it! Just run it via `npx`:
|
|
20
8
|
|
|
@@ -24,7 +12,7 @@ npx @ts-stack/cycle-detector src/index.ts
|
|
|
24
12
|
npx @ts-stack/cycle-detector packages/*/src/index.ts
|
|
25
13
|
```
|
|
26
14
|
|
|
27
|
-
|
|
15
|
+
But you can install it locally:
|
|
28
16
|
|
|
29
17
|
```bash
|
|
30
18
|
npm install -D @ts-stack/cycle-detector
|
|
@@ -44,3 +32,79 @@ And then:
|
|
|
44
32
|
```bash
|
|
45
33
|
npm run lint:cycles
|
|
46
34
|
```
|
|
35
|
+
|
|
36
|
+
### Arguments & Flags
|
|
37
|
+
|
|
38
|
+
* `<entry-patterns>`: Glob patterns or paths to entry point files (e.g., `packages/*/src/index.ts`).
|
|
39
|
+
* `-p, --project <path>`: Path to your root or fallback `tsconfig.json`.
|
|
40
|
+
|
|
41
|
+
## Interpreting Diagnostics
|
|
42
|
+
|
|
43
|
+
When a breaking circular dependency is detected, the script identifies exactly **which file executes the token prematurely**, leaving non-blocking files clearly marked.
|
|
44
|
+
|
|
45
|
+
```txt
|
|
46
|
+
❌ [/packages/rest/src/index.ts] — Found 1 critical circular dependencies:
|
|
47
|
+
1) --------------------------------------------------------------------------------
|
|
48
|
+
⏳ [Lazy] /srv/git/ditsmod/ditsmod/packages/rest/src/extensions/routes.extension.ts
|
|
49
|
+
⏳ [Lazy] /srv/git/ditsmod/ditsmod/packages/rest/src/decorators/rest-init-hooks-and-metadata.ts
|
|
50
|
+
💥 [Top-level] /srv/git/ditsmod/ditsmod/packages/rest/src/init/rest.module.ts
|
|
51
|
+
|
|
52
|
+
💥 Validation failed. Critical circular dependencies detected.
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### How to Refactor Based on the Log Above:
|
|
56
|
+
|
|
57
|
+
The log indicates that `/packages/rest/src/init/rest.module.ts` contains an immediate top-level expression (such as an active decorator evaluation or configuration factory instantiation) that forces the evaluation of `routes.extension.ts` before the module evaluation of `rest.module.ts` is complete. To fix this, extract the shared configuration metadata or decorator targets into a dedicated initialization file positioned lower in the dependency hierarchy.
|
|
58
|
+
|
|
59
|
+
## Exit Codes
|
|
60
|
+
|
|
61
|
+
* `0`: Success. Clean graph or only safe, runtime-deferred cyclic references found.
|
|
62
|
+
* `1`: Critical Top-level execution loops found. Build terminated.
|
|
63
|
+
|
|
64
|
+
## Why Use This Over Existing Solutions?
|
|
65
|
+
|
|
66
|
+
Popular tools like `madge` or generic ESLint rules (`eslint-plugin-import`) operate solely at the graph-theory level: if **File A** imports **File B** and **File B** imports **File A**, an error is flagged.
|
|
67
|
+
|
|
68
|
+
In large-scale TypeScript applications (especially those utilizing Dependency Injection, Decorators, or Monorepo structures like NestJS or Ditsmod), this naive approach leads to massive friction:
|
|
69
|
+
|
|
70
|
+
1. **False Positives:** JavaScript runtimes can perfectly handle circular references if the imported symbol is evaluated lazily (inside a function, class method, or non-static property). Standard tools cannot distinguish between a benign lazy cycle and a critical runtime failure.
|
|
71
|
+
2. **Monorepo Resolution Breakdown:** Tools often stumble when traversing internal monorepo dependencies, resolving to compiled `.d.ts` declarations or `dist/` artifacts instead of tracking back to the original `.ts` source code.
|
|
72
|
+
|
|
73
|
+
### Technical Differentiators
|
|
74
|
+
|
|
75
|
+
| Feature | @ts-stack/cycle-detector | Traditional Tools (e.g., Madge) | ESLint Rules |
|
|
76
|
+
| --- | --- | --- | --- |
|
|
77
|
+
| **Analysis Scope** | Execution-aware (Top-level vs. Lazy) | Pure Import Graph Topology | Token-based / File Boundary |
|
|
78
|
+
| **TypeScript Engine** | Native `typescript` Compiler API | Pre-bundled bundlers / Regex | AST Walkers (without Full Type Context) |
|
|
79
|
+
| **Monorepo Mapping** | Dynamic `package.json` -> `src` tracking | Requires complex path mapping config | Scoped only to single-package roots |
|
|
80
|
+
| **Signal-to-Noise Ratio** | High (Flags only breaking cycles) | Low (Floods with safe runtime loops) | High overhead / Slow parsing |
|
|
81
|
+
|
|
82
|
+
## Core Architecture & Technical Details
|
|
83
|
+
|
|
84
|
+
### 1. Execution-Scoped Risk Assessment
|
|
85
|
+
|
|
86
|
+
The analyzer parses the AST (Abstract Syntax Tree) to track not just *what* is imported, but *where* it is used:
|
|
87
|
+
|
|
88
|
+
* **Top-level Scope (`💥 [Top-level]`)**: The imported symbol is executed immediately during module evaluation (e.g., in a decorator declaration, global constant assignment, or class static property). This causes immediate runtime initialization crashes (`ReferenceError: Cannot access ... before initialization`).
|
|
89
|
+
* **Lazy Scope (`⏳ [Lazy]`)**: The symbol is referenced inside class methods, standard functions, constructor bodies, or non-static properties. Runtimes resolve these safely.
|
|
90
|
+
|
|
91
|
+
**`@ts-stack/cycle-detector` filters out 100% lazy loops and only fails the build if a cycle contains at least one critical Top-level trigger.**
|
|
92
|
+
|
|
93
|
+
### 2. Monorepo Source-to-Dist Tracking
|
|
94
|
+
|
|
95
|
+
In monorepos, internal package dependencies often resolve to `node_modules/<local-package>/dist/index.d.ts`. This utility hooks into `ts.resolveModuleName` and reads local `package.json` manifests dynamically. If an import points to an internal distribution directory, it computes the structural alignment and remaps the graph back into the actual uncompiled source file (`/src/.../.ts`), maintaining a clean, unbroken dependency graph across package boundaries.
|
|
96
|
+
|
|
97
|
+
### 3. Canonical Cycle Deduplication
|
|
98
|
+
|
|
99
|
+
To prevent log flooding from deeply nested structural loops, the DFS (Depth-First Search) cycle collector normalizes all found paths into a canonical key based on lexicographical rotation. You see each unique cycle exactly once, regardless of which file initiated the traversal.
|
|
100
|
+
|
|
101
|
+
## How It Works Under the Hood
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
[Entry Points] ──> [ts.resolveModuleName] ──> [AST Parsing] ──> [DFS Cycle Detection] ──> [Top-level Scope Validation] ──> [Targeted Diagnostic Report]
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
1. **Phase 1: Parse & Resolve:** Reads inputs, loads the closest `tsconfig.json` compiler options, and builds a strict runtime import graph.
|
|
108
|
+
2. **Phase 2: Graph Traversal:** Runs a non-recursive path collector detecting back-edges.
|
|
109
|
+
3. **Phase 3: Scope Validation:** For every edge in a detected cycle, it inspects whether the consumer node executes the imported token outside an execution-deferred scope block.
|
|
110
|
+
4. **Phase 4: Targeted Diagnostics:** Groups and outputs anomalies based on the entry point package context.
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,10 @@ const allUniqueCycles = [];
|
|
|
8
8
|
const globalDetectedCycles = new Set();
|
|
9
9
|
const packageMetaCache = new Map();
|
|
10
10
|
const compilerOptionsCache = new Map();
|
|
11
|
+
// Caches for AST and analysis results to prevent bottlenecks
|
|
12
|
+
const sourceFileCache = new Map();
|
|
13
|
+
const topLevelUsageCache = new Map();
|
|
14
|
+
const exportedHoistedFunctionsCache = new Map();
|
|
11
15
|
let globalProjectPath;
|
|
12
16
|
function parseArgs() {
|
|
13
17
|
const args = [...process.argv.slice(2)];
|
|
@@ -31,13 +35,21 @@ function isRuntimeImport(node) {
|
|
|
31
35
|
return !node.isTypeOnly;
|
|
32
36
|
}
|
|
33
37
|
if (ts.isImportDeclaration(node)) {
|
|
38
|
+
if (node.importClause?.phaseModifier)
|
|
39
|
+
return false;
|
|
34
40
|
if (!node.importClause)
|
|
35
|
-
return true;
|
|
41
|
+
return true; // Side-effect import
|
|
36
42
|
if (node.importClause.phaseModifier)
|
|
37
43
|
return false;
|
|
44
|
+
if (node.importClause.name)
|
|
45
|
+
return true; // Default import present
|
|
38
46
|
const namedBindings = node.importClause.namedBindings;
|
|
39
|
-
if (namedBindings
|
|
40
|
-
|
|
47
|
+
if (namedBindings) {
|
|
48
|
+
if (ts.isNamespaceImport(namedBindings))
|
|
49
|
+
return true;
|
|
50
|
+
if (ts.isNamedImports(namedBindings)) {
|
|
51
|
+
return !namedBindings.elements.every((el) => el.isTypeOnly);
|
|
52
|
+
}
|
|
41
53
|
}
|
|
42
54
|
return true;
|
|
43
55
|
}
|
|
@@ -46,9 +58,8 @@ function isRuntimeImport(node) {
|
|
|
46
58
|
function getCompilerOptionsForFile(filePath) {
|
|
47
59
|
const currentDir = path.dirname(filePath);
|
|
48
60
|
const cachedOptions = compilerOptionsCache.get(currentDir);
|
|
49
|
-
if (cachedOptions !== undefined)
|
|
61
|
+
if (cachedOptions !== undefined)
|
|
50
62
|
return cachedOptions;
|
|
51
|
-
}
|
|
52
63
|
const configPath = ts.findConfigFile(currentDir, ts.sys.fileExists, 'tsconfig.json') || globalProjectPath;
|
|
53
64
|
if (configPath) {
|
|
54
65
|
const resolvedConfigPath = path.resolve(configPath);
|
|
@@ -89,15 +100,39 @@ function getPackageMeta(filePath) {
|
|
|
89
100
|
const pkg = JSON.parse(content);
|
|
90
101
|
let outDirName = 'dist';
|
|
91
102
|
const mainField = pkg.main || pkg.types || pkg.typings || '';
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if (
|
|
95
|
-
|
|
103
|
+
let exportsMain = '';
|
|
104
|
+
if (pkg.exports) {
|
|
105
|
+
if (typeof pkg.exports === 'string') {
|
|
106
|
+
exportsMain = pkg.exports;
|
|
107
|
+
}
|
|
108
|
+
else if (typeof pkg.exports === 'object') {
|
|
109
|
+
const dotExport = pkg.exports['.'];
|
|
110
|
+
if (dotExport) {
|
|
111
|
+
if (typeof dotExport === 'string') {
|
|
112
|
+
exportsMain = dotExport;
|
|
113
|
+
}
|
|
114
|
+
else if (typeof dotExport === 'object') {
|
|
115
|
+
exportsMain = dotExport.import || dotExport.require || dotExport.default || '';
|
|
116
|
+
}
|
|
117
|
+
}
|
|
96
118
|
}
|
|
97
|
-
|
|
98
|
-
|
|
119
|
+
}
|
|
120
|
+
const targetField = mainField || exportsMain;
|
|
121
|
+
if (targetField) {
|
|
122
|
+
const parts = path.normalize(targetField).split(path.sep);
|
|
123
|
+
const cleanParts = parts.filter((p) => p !== '.' && p !== '..');
|
|
124
|
+
if (cleanParts.length > 0) {
|
|
125
|
+
outDirName = cleanParts[0];
|
|
99
126
|
}
|
|
100
127
|
}
|
|
128
|
+
else {
|
|
129
|
+
if (fs.existsSync(path.join(currentDir, 'dist')))
|
|
130
|
+
outDirName = 'dist';
|
|
131
|
+
else if (fs.existsSync(path.join(currentDir, 'build')))
|
|
132
|
+
outDirName = 'build';
|
|
133
|
+
else if (fs.existsSync(path.join(currentDir, 'out')))
|
|
134
|
+
outDirName = 'out';
|
|
135
|
+
}
|
|
101
136
|
let srcDirName = 'src';
|
|
102
137
|
if (fs.existsSync(path.join(currentDir, 'source')))
|
|
103
138
|
srcDirName = 'source';
|
|
@@ -126,16 +161,14 @@ function resolveModule(moduleName, containingFile, options) {
|
|
|
126
161
|
if (!result.resolvedModule)
|
|
127
162
|
return null;
|
|
128
163
|
const resolvedFileName = path.resolve(result.resolvedModule.resolvedFileName);
|
|
129
|
-
if (resolvedFileName.includes(`${path.sep}node_modules${path.sep}`))
|
|
164
|
+
if (resolvedFileName.includes(`${path.sep}node_modules${path.sep}`))
|
|
130
165
|
return null;
|
|
131
|
-
}
|
|
132
166
|
const meta = getPackageMeta(resolvedFileName);
|
|
133
167
|
if (meta) {
|
|
134
168
|
const { pkgDir, srcDirName, outDirName } = meta;
|
|
135
169
|
const srcDirPath = path.join(pkgDir, srcDirName);
|
|
136
|
-
if (resolvedFileName.startsWith(srcDirPath + path.sep))
|
|
170
|
+
if (resolvedFileName.startsWith(srcDirPath + path.sep))
|
|
137
171
|
return resolvedFileName;
|
|
138
|
-
}
|
|
139
172
|
const outDirPath = path.join(pkgDir, outDirName);
|
|
140
173
|
if (resolvedFileName.startsWith(outDirPath + path.sep) || resolvedFileName === outDirPath) {
|
|
141
174
|
const relativeToOut = path.relative(outDirPath, resolvedFileName);
|
|
@@ -157,16 +190,12 @@ function resolveModule(moduleName, containingFile, options) {
|
|
|
157
190
|
const extensions = ['.ts', '.tsx', '.mts', '.cts'];
|
|
158
191
|
for (const ext of extensions) {
|
|
159
192
|
const targetSrcFile = path.join(srcDirPath, baseName + ext);
|
|
160
|
-
if (fs.existsSync(targetSrcFile))
|
|
193
|
+
if (fs.existsSync(targetSrcFile))
|
|
161
194
|
return targetSrcFile;
|
|
162
|
-
}
|
|
163
195
|
}
|
|
164
196
|
}
|
|
165
197
|
}
|
|
166
|
-
|
|
167
|
-
return null;
|
|
168
|
-
}
|
|
169
|
-
return resolvedFileName;
|
|
198
|
+
return result.resolvedModule.isExternalLibraryImport ? null : resolvedFileName;
|
|
170
199
|
}
|
|
171
200
|
function getCanonicalCycleKey(cycle) {
|
|
172
201
|
const nodes = cycle.slice(0, -1);
|
|
@@ -174,9 +203,8 @@ function getCanonicalCycleKey(cycle) {
|
|
|
174
203
|
return '';
|
|
175
204
|
let minIdx = 0;
|
|
176
205
|
for (let i = 1; i < nodes.length; i++) {
|
|
177
|
-
if (nodes[i] < nodes[minIdx])
|
|
206
|
+
if (nodes[i] < nodes[minIdx])
|
|
178
207
|
minIdx = i;
|
|
179
|
-
}
|
|
180
208
|
}
|
|
181
209
|
const rotated = [...nodes.slice(minIdx), ...nodes.slice(0, minIdx)];
|
|
182
210
|
rotated.push(rotated[0]);
|
|
@@ -187,8 +215,12 @@ function parseFile(filePath) {
|
|
|
187
215
|
return;
|
|
188
216
|
graph.set(filePath, []);
|
|
189
217
|
const options = getCompilerOptionsForFile(filePath);
|
|
190
|
-
|
|
191
|
-
|
|
218
|
+
let sourceFile = sourceFileCache.get(filePath);
|
|
219
|
+
if (!sourceFile) {
|
|
220
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
221
|
+
sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);
|
|
222
|
+
sourceFileCache.set(filePath, sourceFile);
|
|
223
|
+
}
|
|
192
224
|
const imports = [];
|
|
193
225
|
function walk(node) {
|
|
194
226
|
if (ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) {
|
|
@@ -208,18 +240,99 @@ function parseFile(filePath) {
|
|
|
208
240
|
for (const dep of imports)
|
|
209
241
|
parseFile(dep);
|
|
210
242
|
}
|
|
243
|
+
/**
|
|
244
|
+
* Analyzes a file and extracts the names of all exported functions that are hoisted.
|
|
245
|
+
*/
|
|
246
|
+
function getExportedHoistedFunctions(filePath) {
|
|
247
|
+
if (exportedHoistedFunctionsCache.has(filePath)) {
|
|
248
|
+
return exportedHoistedFunctionsCache.get(filePath);
|
|
249
|
+
}
|
|
250
|
+
const hoisted = new Set();
|
|
251
|
+
if (!fs.existsSync(filePath)) {
|
|
252
|
+
exportedHoistedFunctionsCache.set(filePath, hoisted);
|
|
253
|
+
return hoisted;
|
|
254
|
+
}
|
|
255
|
+
let sourceFile = sourceFileCache.get(filePath);
|
|
256
|
+
if (!sourceFile) {
|
|
257
|
+
try {
|
|
258
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
259
|
+
sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);
|
|
260
|
+
sourceFileCache.set(filePath, sourceFile);
|
|
261
|
+
}
|
|
262
|
+
catch {
|
|
263
|
+
exportedHoistedFunctionsCache.set(filePath, hoisted);
|
|
264
|
+
return hoisted;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
const localHoistedFuncs = new Set();
|
|
268
|
+
// Pass 1: Find all top-level function declarations and direct export modifiers
|
|
269
|
+
for (const statement of sourceFile.statements) {
|
|
270
|
+
if (ts.isFunctionDeclaration(statement)) {
|
|
271
|
+
if (statement.name) {
|
|
272
|
+
localHoistedFuncs.add(statement.name.text);
|
|
273
|
+
}
|
|
274
|
+
const hasExport = statement.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword);
|
|
275
|
+
const hasDefault = statement.modifiers?.some((m) => m.kind === ts.SyntaxKind.DefaultKeyword);
|
|
276
|
+
if (hasExport) {
|
|
277
|
+
if (hasDefault)
|
|
278
|
+
hoisted.add('default');
|
|
279
|
+
else if (statement.name)
|
|
280
|
+
hoisted.add(statement.name.text);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
// Pass 2: Look for independent export declarations or export assignments mapping to local functions
|
|
285
|
+
for (const statement of sourceFile.statements) {
|
|
286
|
+
if (ts.isExportDeclaration(statement)) {
|
|
287
|
+
if (!statement.moduleSpecifier && statement.exportClause && ts.isNamedExports(statement.exportClause)) {
|
|
288
|
+
for (const el of statement.exportClause.elements) {
|
|
289
|
+
const localName = el.propertyName ? el.propertyName.text : el.name.text;
|
|
290
|
+
const exportedName = el.name.text;
|
|
291
|
+
if (localHoistedFuncs.has(localName)) {
|
|
292
|
+
hoisted.add(exportedName);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
else if (ts.isExportAssignment(statement)) {
|
|
298
|
+
if (!statement.isExportEquals && ts.isIdentifier(statement.expression)) {
|
|
299
|
+
if (localHoistedFuncs.has(statement.expression.text)) {
|
|
300
|
+
hoisted.add('default');
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
exportedHoistedFunctionsCache.set(filePath, hoisted);
|
|
306
|
+
return hoisted;
|
|
307
|
+
}
|
|
211
308
|
/**
|
|
212
309
|
* Checks if a specific file import creates an immediate execution (top-level) risk.
|
|
213
310
|
*/
|
|
214
311
|
function hasTopLevelUsage(fromFile, toFile) {
|
|
215
312
|
if (!fs.existsSync(fromFile))
|
|
216
313
|
return false;
|
|
314
|
+
const cacheKey = `${fromFile}-->${toFile}`;
|
|
315
|
+
if (topLevelUsageCache.has(cacheKey))
|
|
316
|
+
return topLevelUsageCache.get(cacheKey);
|
|
217
317
|
const options = getCompilerOptionsForFile(fromFile);
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
318
|
+
let sourceFile = sourceFileCache.get(fromFile);
|
|
319
|
+
if (!sourceFile) {
|
|
320
|
+
try {
|
|
321
|
+
const content = fs.readFileSync(fromFile, 'utf8');
|
|
322
|
+
sourceFile = ts.createSourceFile(fromFile, content, ts.ScriptTarget.Latest, true);
|
|
323
|
+
sourceFileCache.set(fromFile, sourceFile);
|
|
324
|
+
}
|
|
325
|
+
catch {
|
|
326
|
+
topLevelUsageCache.set(cacheKey, false);
|
|
327
|
+
return false;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
// Get all safe hoisted exports from the target file
|
|
331
|
+
const hoistedExports = getExportedHoistedFunctions(toFile);
|
|
332
|
+
// Maps local import identifier to its original exported symbol name
|
|
333
|
+
const localToExportedName = new Map();
|
|
334
|
+
let namespaceImportName = null;
|
|
221
335
|
let hasSideEffectOrReExport = false;
|
|
222
|
-
// 1. Collect all names imported from 'toFile'
|
|
223
336
|
function findImports(node) {
|
|
224
337
|
if (ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) {
|
|
225
338
|
if (isRuntimeImport(node)) {
|
|
@@ -229,22 +342,22 @@ function hasTopLevelUsage(fromFile, toFile) {
|
|
|
229
342
|
if (resolved === toFile) {
|
|
230
343
|
if (ts.isImportDeclaration(node) && node.importClause) {
|
|
231
344
|
const clause = node.importClause;
|
|
232
|
-
if (clause.name)
|
|
233
|
-
|
|
345
|
+
if (clause.name) {
|
|
346
|
+
localToExportedName.set(clause.name.text, 'default');
|
|
347
|
+
}
|
|
234
348
|
if (clause.namedBindings) {
|
|
235
349
|
if (ts.isNamespaceImport(clause.namedBindings)) {
|
|
236
|
-
|
|
350
|
+
namespaceImportName = clause.namedBindings.name.text;
|
|
237
351
|
}
|
|
238
352
|
else if (ts.isNamedImports(clause.namedBindings)) {
|
|
239
353
|
for (const el of clause.namedBindings.elements) {
|
|
240
|
-
|
|
354
|
+
const exportedName = el.propertyName ? el.propertyName.text : el.name.text;
|
|
355
|
+
localToExportedName.set(el.name.text, exportedName);
|
|
241
356
|
}
|
|
242
357
|
}
|
|
243
358
|
}
|
|
244
359
|
}
|
|
245
360
|
else {
|
|
246
|
-
// Re-exports (export * from...) or side-effect imports (import './file')
|
|
247
|
-
// trigger top-level evaluation instantly.
|
|
248
361
|
hasSideEffectOrReExport = true;
|
|
249
362
|
}
|
|
250
363
|
}
|
|
@@ -254,12 +367,15 @@ function hasTopLevelUsage(fromFile, toFile) {
|
|
|
254
367
|
ts.forEachChild(node, findImports);
|
|
255
368
|
}
|
|
256
369
|
findImports(sourceFile);
|
|
257
|
-
if (hasSideEffectOrReExport)
|
|
370
|
+
if (hasSideEffectOrReExport) {
|
|
371
|
+
topLevelUsageCache.set(cacheKey, true);
|
|
258
372
|
return true;
|
|
259
|
-
|
|
373
|
+
}
|
|
374
|
+
if (localToExportedName.size === 0 && !namespaceImportName) {
|
|
375
|
+
topLevelUsageCache.set(cacheKey, false);
|
|
260
376
|
return false;
|
|
377
|
+
}
|
|
261
378
|
let dangerousTopLevelUsage = false;
|
|
262
|
-
// 2. Check if collected symbols are used outside of lazy blocks (functions/methods)
|
|
263
379
|
function checkNodeUsage(node, isInsideLazyScope) {
|
|
264
380
|
if (dangerousTopLevelUsage)
|
|
265
381
|
return;
|
|
@@ -274,42 +390,76 @@ function hasTopLevelUsage(fromFile, toFile) {
|
|
|
274
390
|
currentScopeLazy = true;
|
|
275
391
|
}
|
|
276
392
|
if (ts.isPropertyDeclaration(node)) {
|
|
277
|
-
const isStatic = node.modifiers?.some(m => m.kind === ts.SyntaxKind.StaticKeyword);
|
|
278
|
-
if (!isStatic)
|
|
393
|
+
const isStatic = node.modifiers?.some((m) => m.kind === ts.SyntaxKind.StaticKeyword);
|
|
394
|
+
if (!isStatic)
|
|
279
395
|
currentScopeLazy = true;
|
|
280
|
-
}
|
|
281
396
|
}
|
|
282
397
|
if (!currentScopeLazy && ts.isIdentifier(node)) {
|
|
283
|
-
|
|
398
|
+
const isImportedSymbol = localToExportedName.has(node.text);
|
|
399
|
+
const isNamespaceReference = namespaceImportName && node.text === namespaceImportName;
|
|
400
|
+
if (isImportedSymbol || isNamespaceReference) {
|
|
284
401
|
const parent = node.parent;
|
|
285
|
-
//
|
|
286
|
-
const
|
|
402
|
+
// Protection 1: Skip metadata/declarations references
|
|
403
|
+
const isImportOrExportDeclarationRef = ts.isImportSpecifier(parent) ||
|
|
287
404
|
ts.isImportClause(parent) ||
|
|
288
|
-
ts.isNamespaceImport(parent)
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
405
|
+
ts.isNamespaceImport(parent) ||
|
|
406
|
+
ts.isExportSpecifier(parent);
|
|
407
|
+
if (isImportOrExportDeclarationRef)
|
|
408
|
+
return;
|
|
409
|
+
// Protection 2: Avoid object property name access False Positives (obj.foo)
|
|
410
|
+
if (ts.isPropertyAccessExpression(parent) && parent.name === node)
|
|
411
|
+
return;
|
|
412
|
+
// Protection 3: Avoid object assignment keys False Positives ({ foo: 123 })
|
|
413
|
+
if (ts.isPropertyAssignment(parent) && parent.name === node)
|
|
414
|
+
return;
|
|
415
|
+
// Protection 4: Avoid shadow declarations with matching names
|
|
416
|
+
if ((ts.isMethodDeclaration(parent) ||
|
|
417
|
+
ts.isPropertyDeclaration(parent) ||
|
|
418
|
+
ts.isClassDeclaration(parent) ||
|
|
419
|
+
ts.isInterfaceDeclaration(parent) ||
|
|
420
|
+
ts.isFunctionDeclaration(parent)) &&
|
|
421
|
+
parent.name === node) {
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
// (Hoisting check 1): Direct or renamed named/default import usage
|
|
425
|
+
if (isImportedSymbol) {
|
|
426
|
+
const exportedName = localToExportedName.get(node.text);
|
|
427
|
+
if (hoistedExports.has(exportedName)) {
|
|
428
|
+
return; // Perfectly safe hoisted function call/reference!
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
// (Hoisting check 2): Namespace import property access usage (ns.foo())
|
|
432
|
+
if (isNamespaceReference) {
|
|
433
|
+
if (ts.isPropertyAccessExpression(parent) && parent.expression === node) {
|
|
434
|
+
const propName = parent.name.text;
|
|
435
|
+
if (hoistedExports.has(propName)) {
|
|
436
|
+
return; // Perfectly safe property from namespace!
|
|
300
437
|
}
|
|
301
|
-
checkParent = checkParent.parent;
|
|
302
438
|
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
439
|
+
}
|
|
440
|
+
// Protection 5: Type contexts checks
|
|
441
|
+
let isInTypeContext = false;
|
|
442
|
+
let checkParent = parent;
|
|
443
|
+
while (checkParent && checkParent !== sourceFile) {
|
|
444
|
+
if (ts.isTypeNode(checkParent) ||
|
|
445
|
+
ts.isTypeReferenceNode(checkParent) ||
|
|
446
|
+
ts.isTypeAliasDeclaration(checkParent) ||
|
|
447
|
+
ts.isInterfaceDeclaration(checkParent)) {
|
|
448
|
+
isInTypeContext = true;
|
|
449
|
+
break;
|
|
306
450
|
}
|
|
451
|
+
checkParent = checkParent.parent;
|
|
452
|
+
}
|
|
453
|
+
if (!isInTypeContext) {
|
|
454
|
+
dangerousTopLevelUsage = true;
|
|
455
|
+
return;
|
|
307
456
|
}
|
|
308
457
|
}
|
|
309
458
|
}
|
|
310
459
|
ts.forEachChild(node, (n) => checkNodeUsage(n, currentScopeLazy));
|
|
311
460
|
}
|
|
312
461
|
checkNodeUsage(sourceFile, false);
|
|
462
|
+
topLevelUsageCache.set(cacheKey, dangerousTopLevelUsage);
|
|
313
463
|
return dangerousTopLevelUsage;
|
|
314
464
|
}
|
|
315
465
|
function canReach(start, target) {
|
|
@@ -323,9 +473,8 @@ function canReach(start, target) {
|
|
|
323
473
|
continue;
|
|
324
474
|
seen.add(current);
|
|
325
475
|
const deps = graph.get(current) || [];
|
|
326
|
-
for (const dep of deps)
|
|
476
|
+
for (const dep of deps)
|
|
327
477
|
stack.push(dep);
|
|
328
|
-
}
|
|
329
478
|
}
|
|
330
479
|
return false;
|
|
331
480
|
}
|
|
@@ -356,11 +505,9 @@ function main() {
|
|
|
356
505
|
process.exit(1);
|
|
357
506
|
}
|
|
358
507
|
console.log(`🔍 Found ${entryPoints.length} entry point(s) for analysis. Building graph...\n`);
|
|
359
|
-
// Phase 1: Deep parse all files globally across all entry points
|
|
360
508
|
for (const entryPoint of entryPoints) {
|
|
361
509
|
parseFile(entryPoint);
|
|
362
510
|
}
|
|
363
|
-
// Phase 2: Traverse the global graph to discover all unique cycles
|
|
364
511
|
const visited = new Map();
|
|
365
512
|
const currentStack = [];
|
|
366
513
|
function findCycles(node) {
|
|
@@ -386,30 +533,24 @@ function main() {
|
|
|
386
533
|
visited.set(node, 'VISITED');
|
|
387
534
|
}
|
|
388
535
|
for (const entryPoint of entryPoints) {
|
|
389
|
-
if (!visited.has(entryPoint))
|
|
536
|
+
if (!visited.has(entryPoint))
|
|
390
537
|
findCycles(entryPoint);
|
|
391
|
-
}
|
|
392
538
|
}
|
|
393
|
-
// Phase 2.5: Smart AST Filtering (Filter out runtime-safe / lazy cycles)
|
|
394
539
|
const criticalCycles = [];
|
|
395
540
|
for (const cycle of allUniqueCycles) {
|
|
396
541
|
let isHarmfulCycle = false;
|
|
397
|
-
// A cycle is harmful if AT LEAST ONE link in it uses imports on top-level
|
|
398
542
|
for (let i = 0; i < cycle.length - 1; i++) {
|
|
399
543
|
if (hasTopLevelUsage(cycle[i], cycle[i + 1])) {
|
|
400
544
|
isHarmfulCycle = true;
|
|
401
545
|
break;
|
|
402
546
|
}
|
|
403
547
|
}
|
|
404
|
-
if (isHarmfulCycle)
|
|
548
|
+
if (isHarmfulCycle)
|
|
405
549
|
criticalCycles.push(cycle);
|
|
406
|
-
}
|
|
407
550
|
}
|
|
408
|
-
// Phase 3: Intelligently distribute critical cycles to their native entry points
|
|
409
551
|
const entryPointCycles = new Map();
|
|
410
|
-
for (const ep of entryPoints)
|
|
552
|
+
for (const ep of entryPoints)
|
|
411
553
|
entryPointCycles.set(ep, []);
|
|
412
|
-
}
|
|
413
554
|
for (const cycle of criticalCycles) {
|
|
414
555
|
const firstFile = cycle[0];
|
|
415
556
|
const matchedEp = entryPoints.find((ep) => {
|
|
@@ -421,30 +562,32 @@ function main() {
|
|
|
421
562
|
}
|
|
422
563
|
else {
|
|
423
564
|
const reachingEp = entryPoints.find((ep) => canReach(ep, firstFile));
|
|
424
|
-
if (reachingEp)
|
|
565
|
+
if (reachingEp)
|
|
425
566
|
entryPointCycles.get(reachingEp).push(cycle);
|
|
426
|
-
|
|
427
|
-
else {
|
|
567
|
+
else
|
|
428
568
|
entryPointCycles.get(entryPoints[0]).push(cycle);
|
|
429
|
-
}
|
|
430
569
|
}
|
|
431
570
|
}
|
|
432
|
-
// Phase 4: Output the clean, perfectly targeted report
|
|
433
571
|
let globalHasCycles = false;
|
|
434
572
|
for (const entryPoint of entryPoints) {
|
|
435
573
|
const absoluteEntry = path.resolve(entryPoint);
|
|
436
574
|
const cycles = entryPointCycles.get(entryPoint) || [];
|
|
437
575
|
if (cycles.length > 0) {
|
|
438
576
|
globalHasCycles = true;
|
|
439
|
-
console.error(`❌
|
|
577
|
+
console.error(`❌ ${absoluteEntry} — Found ${cycles.length} critical circular dependencies:`);
|
|
440
578
|
cycles.forEach((cycle, index) => {
|
|
441
|
-
|
|
442
|
-
|
|
579
|
+
console.error(` ${index + 1})`, '-'.repeat(80));
|
|
580
|
+
for (let i = 1; i < cycle.length; i++) {
|
|
581
|
+
const nextFile = i === cycle.length - 1 ? cycle[1] : cycle[i + 1];
|
|
582
|
+
const isTopLevel = hasTopLevelUsage(cycle[i], nextFile);
|
|
583
|
+
const prefix = isTopLevel ? ' 💥 [Top-level] ' : ' ⏳ [Lazy] ';
|
|
584
|
+
console.error(`${prefix}${path.resolve(cycle[i])}`);
|
|
585
|
+
}
|
|
443
586
|
});
|
|
444
587
|
console.error('');
|
|
445
588
|
}
|
|
446
589
|
else {
|
|
447
|
-
console.log(`✅
|
|
590
|
+
console.log(`✅ ${absoluteEntry}`);
|
|
448
591
|
}
|
|
449
592
|
}
|
|
450
593
|
if (globalHasCycles || criticalCycles.length > 0) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -11,9 +11,14 @@ const graph = new Map<string, string[]>();
|
|
|
11
11
|
const allUniqueCycles: string[][] = [];
|
|
12
12
|
const globalDetectedCycles = new Set<string>();
|
|
13
13
|
|
|
14
|
-
const packageMetaCache = new Map<string, { pkgDir: string; srcDirName: string; outDirName: string
|
|
14
|
+
const packageMetaCache = new Map<string, { pkgDir: string; srcDirName: string; outDirName: string } | null>();
|
|
15
15
|
const compilerOptionsCache = new Map<string, ts.CompilerOptions>();
|
|
16
16
|
|
|
17
|
+
// Caches for AST and analysis results to prevent bottlenecks
|
|
18
|
+
const sourceFileCache = new Map<string, ts.SourceFile>();
|
|
19
|
+
const topLevelUsageCache = new Map<string, boolean>();
|
|
20
|
+
const exportedHoistedFunctionsCache = new Map<string, Set<string>>();
|
|
21
|
+
|
|
17
22
|
let globalProjectPath: string | undefined;
|
|
18
23
|
|
|
19
24
|
function parseArgs() {
|
|
@@ -40,12 +45,18 @@ function isRuntimeImport(node: ts.ImportDeclaration | ts.ExportDeclaration): boo
|
|
|
40
45
|
}
|
|
41
46
|
|
|
42
47
|
if (ts.isImportDeclaration(node)) {
|
|
43
|
-
if (
|
|
48
|
+
if (node.importClause?.phaseModifier) return false;
|
|
49
|
+
if (!node.importClause) return true; // Side-effect import
|
|
44
50
|
if (node.importClause.phaseModifier) return false;
|
|
45
51
|
|
|
52
|
+
if (node.importClause.name) return true; // Default import present
|
|
53
|
+
|
|
46
54
|
const namedBindings = node.importClause.namedBindings;
|
|
47
|
-
if (namedBindings
|
|
48
|
-
|
|
55
|
+
if (namedBindings) {
|
|
56
|
+
if (ts.isNamespaceImport(namedBindings)) return true;
|
|
57
|
+
if (ts.isNamedImports(namedBindings)) {
|
|
58
|
+
return !namedBindings.elements.every((el) => el.isTypeOnly);
|
|
59
|
+
}
|
|
49
60
|
}
|
|
50
61
|
return true;
|
|
51
62
|
}
|
|
@@ -55,18 +66,14 @@ function isRuntimeImport(node: ts.ImportDeclaration | ts.ExportDeclaration): boo
|
|
|
55
66
|
|
|
56
67
|
function getCompilerOptionsForFile(filePath: string): ts.CompilerOptions {
|
|
57
68
|
const currentDir = path.dirname(filePath);
|
|
58
|
-
|
|
59
69
|
const cachedOptions = compilerOptionsCache.get(currentDir);
|
|
60
|
-
if (cachedOptions !== undefined)
|
|
61
|
-
return cachedOptions;
|
|
62
|
-
}
|
|
70
|
+
if (cachedOptions !== undefined) return cachedOptions;
|
|
63
71
|
|
|
64
72
|
const configPath = ts.findConfigFile(currentDir, ts.sys.fileExists, 'tsconfig.json') || globalProjectPath;
|
|
65
73
|
|
|
66
74
|
if (configPath) {
|
|
67
75
|
const resolvedConfigPath = path.resolve(configPath);
|
|
68
76
|
const configDir = path.dirname(resolvedConfigPath);
|
|
69
|
-
|
|
70
77
|
const cachedConfig = compilerOptionsCache.get(resolvedConfigPath);
|
|
71
78
|
if (cachedConfig !== undefined) {
|
|
72
79
|
compilerOptionsCache.set(currentDir, cachedConfig);
|
|
@@ -77,7 +84,6 @@ function getCompilerOptionsForFile(filePath: string): ts.CompilerOptions {
|
|
|
77
84
|
const configFile = ts.readConfigFile(resolvedConfigPath, ts.sys.readFile);
|
|
78
85
|
const parsedConfig = ts.parseJsonConfigFileContent(configFile.config, ts.sys, configDir);
|
|
79
86
|
const options = parsedConfig.options || {};
|
|
80
|
-
|
|
81
87
|
compilerOptionsCache.set(resolvedConfigPath, options);
|
|
82
88
|
compilerOptionsCache.set(currentDir, options);
|
|
83
89
|
return options;
|
|
@@ -108,13 +114,34 @@ function getPackageMeta(filePath: string) {
|
|
|
108
114
|
|
|
109
115
|
let outDirName = 'dist';
|
|
110
116
|
const mainField = pkg.main || pkg.types || pkg.typings || '';
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
+
|
|
118
|
+
let exportsMain = '';
|
|
119
|
+
if (pkg.exports) {
|
|
120
|
+
if (typeof pkg.exports === 'string') {
|
|
121
|
+
exportsMain = pkg.exports;
|
|
122
|
+
} else if (typeof pkg.exports === 'object') {
|
|
123
|
+
const dotExport = pkg.exports['.'];
|
|
124
|
+
if (dotExport) {
|
|
125
|
+
if (typeof dotExport === 'string') {
|
|
126
|
+
exportsMain = dotExport;
|
|
127
|
+
} else if (typeof dotExport === 'object') {
|
|
128
|
+
exportsMain = dotExport.import || dotExport.require || dotExport.default || '';
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const targetField = mainField || exportsMain;
|
|
135
|
+
if (targetField) {
|
|
136
|
+
const parts = path.normalize(targetField).split(path.sep);
|
|
137
|
+
const cleanParts = parts.filter((p) => p !== '.' && p !== '..');
|
|
138
|
+
if (cleanParts.length > 0) {
|
|
139
|
+
outDirName = cleanParts[0];
|
|
117
140
|
}
|
|
141
|
+
} else {
|
|
142
|
+
if (fs.existsSync(path.join(currentDir, 'dist'))) outDirName = 'dist';
|
|
143
|
+
else if (fs.existsSync(path.join(currentDir, 'build'))) outDirName = 'build';
|
|
144
|
+
else if (fs.existsSync(path.join(currentDir, 'out'))) outDirName = 'out';
|
|
118
145
|
}
|
|
119
146
|
|
|
120
147
|
let srcDirName = 'src';
|
|
@@ -144,19 +171,14 @@ function resolveModule(moduleName: string, containingFile: string, options: ts.C
|
|
|
144
171
|
if (!result.resolvedModule) return null;
|
|
145
172
|
|
|
146
173
|
const resolvedFileName = path.resolve(result.resolvedModule.resolvedFileName);
|
|
147
|
-
|
|
148
|
-
if (resolvedFileName.includes(`${path.sep}node_modules${path.sep}`)) {
|
|
149
|
-
return null;
|
|
150
|
-
}
|
|
174
|
+
if (resolvedFileName.includes(`${path.sep}node_modules${path.sep}`)) return null;
|
|
151
175
|
|
|
152
176
|
const meta = getPackageMeta(resolvedFileName);
|
|
153
177
|
if (meta) {
|
|
154
178
|
const { pkgDir, srcDirName, outDirName } = meta;
|
|
155
179
|
const srcDirPath = path.join(pkgDir, srcDirName);
|
|
156
180
|
|
|
157
|
-
if (resolvedFileName.startsWith(srcDirPath + path.sep))
|
|
158
|
-
return resolvedFileName;
|
|
159
|
-
}
|
|
181
|
+
if (resolvedFileName.startsWith(srcDirPath + path.sep)) return resolvedFileName;
|
|
160
182
|
|
|
161
183
|
const outDirPath = path.join(pkgDir, outDirName);
|
|
162
184
|
if (resolvedFileName.startsWith(outDirPath + path.sep) || resolvedFileName === outDirPath) {
|
|
@@ -174,18 +196,12 @@ function resolveModule(moduleName: string, containingFile: string, options: ts.C
|
|
|
174
196
|
const extensions = ['.ts', '.tsx', '.mts', '.cts'];
|
|
175
197
|
for (const ext of extensions) {
|
|
176
198
|
const targetSrcFile = path.join(srcDirPath, baseName + ext);
|
|
177
|
-
if (fs.existsSync(targetSrcFile))
|
|
178
|
-
return targetSrcFile;
|
|
179
|
-
}
|
|
199
|
+
if (fs.existsSync(targetSrcFile)) return targetSrcFile;
|
|
180
200
|
}
|
|
181
201
|
}
|
|
182
202
|
}
|
|
183
203
|
|
|
184
|
-
|
|
185
|
-
return null;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
return resolvedFileName;
|
|
204
|
+
return result.resolvedModule.isExternalLibraryImport ? null : resolvedFileName;
|
|
189
205
|
}
|
|
190
206
|
|
|
191
207
|
function getCanonicalCycleKey(cycle: string[]): string {
|
|
@@ -194,9 +210,7 @@ function getCanonicalCycleKey(cycle: string[]): string {
|
|
|
194
210
|
|
|
195
211
|
let minIdx = 0;
|
|
196
212
|
for (let i = 1; i < nodes.length; i++) {
|
|
197
|
-
if (nodes[i] < nodes[minIdx])
|
|
198
|
-
minIdx = i;
|
|
199
|
-
}
|
|
213
|
+
if (nodes[i] < nodes[minIdx]) minIdx = i;
|
|
200
214
|
}
|
|
201
215
|
|
|
202
216
|
const rotated = [...nodes.slice(minIdx), ...nodes.slice(0, minIdx)];
|
|
@@ -209,8 +223,14 @@ function parseFile(filePath: string) {
|
|
|
209
223
|
graph.set(filePath, []);
|
|
210
224
|
|
|
211
225
|
const options = getCompilerOptionsForFile(filePath);
|
|
212
|
-
|
|
213
|
-
|
|
226
|
+
|
|
227
|
+
let sourceFile = sourceFileCache.get(filePath);
|
|
228
|
+
if (!sourceFile) {
|
|
229
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
230
|
+
sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);
|
|
231
|
+
sourceFileCache.set(filePath, sourceFile);
|
|
232
|
+
}
|
|
233
|
+
|
|
214
234
|
const imports: string[] = [];
|
|
215
235
|
|
|
216
236
|
function walk(node: ts.Node) {
|
|
@@ -232,20 +252,106 @@ function parseFile(filePath: string) {
|
|
|
232
252
|
for (const dep of imports) parseFile(dep);
|
|
233
253
|
}
|
|
234
254
|
|
|
255
|
+
/**
|
|
256
|
+
* Analyzes a file and extracts the names of all exported functions that are hoisted.
|
|
257
|
+
*/
|
|
258
|
+
function getExportedHoistedFunctions(filePath: string): Set<string> {
|
|
259
|
+
if (exportedHoistedFunctionsCache.has(filePath)) {
|
|
260
|
+
return exportedHoistedFunctionsCache.get(filePath)!;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const hoisted = new Set<string>();
|
|
264
|
+
if (!fs.existsSync(filePath)) {
|
|
265
|
+
exportedHoistedFunctionsCache.set(filePath, hoisted);
|
|
266
|
+
return hoisted;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
let sourceFile = sourceFileCache.get(filePath);
|
|
270
|
+
if (!sourceFile) {
|
|
271
|
+
try {
|
|
272
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
273
|
+
sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);
|
|
274
|
+
sourceFileCache.set(filePath, sourceFile);
|
|
275
|
+
} catch {
|
|
276
|
+
exportedHoistedFunctionsCache.set(filePath, hoisted);
|
|
277
|
+
return hoisted;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const localHoistedFuncs = new Set<string>();
|
|
282
|
+
|
|
283
|
+
// Pass 1: Find all top-level function declarations and direct export modifiers
|
|
284
|
+
for (const statement of sourceFile.statements) {
|
|
285
|
+
if (ts.isFunctionDeclaration(statement)) {
|
|
286
|
+
if (statement.name) {
|
|
287
|
+
localHoistedFuncs.add(statement.name.text);
|
|
288
|
+
}
|
|
289
|
+
const hasExport = statement.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword);
|
|
290
|
+
const hasDefault = statement.modifiers?.some((m) => m.kind === ts.SyntaxKind.DefaultKeyword);
|
|
291
|
+
|
|
292
|
+
if (hasExport) {
|
|
293
|
+
if (hasDefault) hoisted.add('default');
|
|
294
|
+
else if (statement.name) hoisted.add(statement.name.text);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Pass 2: Look for independent export declarations or export assignments mapping to local functions
|
|
300
|
+
for (const statement of sourceFile.statements) {
|
|
301
|
+
if (ts.isExportDeclaration(statement)) {
|
|
302
|
+
if (!statement.moduleSpecifier && statement.exportClause && ts.isNamedExports(statement.exportClause)) {
|
|
303
|
+
for (const el of statement.exportClause.elements) {
|
|
304
|
+
const localName = el.propertyName ? el.propertyName.text : el.name.text;
|
|
305
|
+
const exportedName = el.name.text;
|
|
306
|
+
if (localHoistedFuncs.has(localName)) {
|
|
307
|
+
hoisted.add(exportedName);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
} else if (ts.isExportAssignment(statement)) {
|
|
312
|
+
if (!statement.isExportEquals && ts.isIdentifier(statement.expression)) {
|
|
313
|
+
if (localHoistedFuncs.has(statement.expression.text)) {
|
|
314
|
+
hoisted.add('default');
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
exportedHoistedFunctionsCache.set(filePath, hoisted);
|
|
321
|
+
return hoisted;
|
|
322
|
+
}
|
|
323
|
+
|
|
235
324
|
/**
|
|
236
325
|
* Checks if a specific file import creates an immediate execution (top-level) risk.
|
|
237
326
|
*/
|
|
238
327
|
function hasTopLevelUsage(fromFile: string, toFile: string): boolean {
|
|
239
328
|
if (!fs.existsSync(fromFile)) return false;
|
|
240
329
|
|
|
330
|
+
const cacheKey = `${fromFile}-->${toFile}`;
|
|
331
|
+
if (topLevelUsageCache.has(cacheKey)) return topLevelUsageCache.get(cacheKey)!;
|
|
332
|
+
|
|
241
333
|
const options = getCompilerOptionsForFile(fromFile);
|
|
242
|
-
const content = fs.readFileSync(fromFile, 'utf8');
|
|
243
|
-
const sourceFile = ts.createSourceFile(fromFile, content, ts.ScriptTarget.Latest, true);
|
|
244
334
|
|
|
245
|
-
|
|
335
|
+
let sourceFile = sourceFileCache.get(fromFile);
|
|
336
|
+
if (!sourceFile) {
|
|
337
|
+
try {
|
|
338
|
+
const content = fs.readFileSync(fromFile, 'utf8');
|
|
339
|
+
sourceFile = ts.createSourceFile(fromFile, content, ts.ScriptTarget.Latest, true);
|
|
340
|
+
sourceFileCache.set(fromFile, sourceFile);
|
|
341
|
+
} catch {
|
|
342
|
+
topLevelUsageCache.set(cacheKey, false);
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Get all safe hoisted exports from the target file
|
|
348
|
+
const hoistedExports = getExportedHoistedFunctions(toFile);
|
|
349
|
+
|
|
350
|
+
// Maps local import identifier to its original exported symbol name
|
|
351
|
+
const localToExportedName = new Map<string, string>();
|
|
352
|
+
let namespaceImportName: string | null = null;
|
|
246
353
|
let hasSideEffectOrReExport = false;
|
|
247
354
|
|
|
248
|
-
// 1. Collect all names imported from 'toFile'
|
|
249
355
|
function findImports(node: ts.Node) {
|
|
250
356
|
if (ts.isImportDeclaration(node) || ts.isExportDeclaration(node)) {
|
|
251
357
|
if (isRuntimeImport(node)) {
|
|
@@ -255,19 +361,20 @@ function hasTopLevelUsage(fromFile: string, toFile: string): boolean {
|
|
|
255
361
|
if (resolved === toFile) {
|
|
256
362
|
if (ts.isImportDeclaration(node) && node.importClause) {
|
|
257
363
|
const clause = node.importClause;
|
|
258
|
-
if (clause.name)
|
|
364
|
+
if (clause.name) {
|
|
365
|
+
localToExportedName.set(clause.name.text, 'default');
|
|
366
|
+
}
|
|
259
367
|
if (clause.namedBindings) {
|
|
260
368
|
if (ts.isNamespaceImport(clause.namedBindings)) {
|
|
261
|
-
|
|
369
|
+
namespaceImportName = clause.namedBindings.name.text;
|
|
262
370
|
} else if (ts.isNamedImports(clause.namedBindings)) {
|
|
263
371
|
for (const el of clause.namedBindings.elements) {
|
|
264
|
-
|
|
372
|
+
const exportedName = el.propertyName ? el.propertyName.text : el.name.text;
|
|
373
|
+
localToExportedName.set(el.name.text, exportedName);
|
|
265
374
|
}
|
|
266
375
|
}
|
|
267
376
|
}
|
|
268
377
|
} else {
|
|
269
|
-
// Re-exports (export * from...) or side-effect imports (import './file')
|
|
270
|
-
// trigger top-level evaluation instantly.
|
|
271
378
|
hasSideEffectOrReExport = true;
|
|
272
379
|
}
|
|
273
380
|
}
|
|
@@ -279,55 +386,99 @@ function hasTopLevelUsage(fromFile: string, toFile: string): boolean {
|
|
|
279
386
|
|
|
280
387
|
findImports(sourceFile);
|
|
281
388
|
|
|
282
|
-
if (hasSideEffectOrReExport)
|
|
283
|
-
|
|
389
|
+
if (hasSideEffectOrReExport) {
|
|
390
|
+
topLevelUsageCache.set(cacheKey, true);
|
|
391
|
+
return true;
|
|
392
|
+
}
|
|
393
|
+
if (localToExportedName.size === 0 && !namespaceImportName) {
|
|
394
|
+
topLevelUsageCache.set(cacheKey, false);
|
|
395
|
+
return false;
|
|
396
|
+
}
|
|
284
397
|
|
|
285
398
|
let dangerousTopLevelUsage = false;
|
|
286
399
|
|
|
287
|
-
// 2. Check if collected symbols are used outside of lazy blocks (functions/methods)
|
|
288
400
|
function checkNodeUsage(node: ts.Node, isInsideLazyScope: boolean) {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
401
|
+
if (dangerousTopLevelUsage) return;
|
|
402
|
+
|
|
403
|
+
let currentScopeLazy = isInsideLazyScope;
|
|
404
|
+
|
|
405
|
+
if (
|
|
406
|
+
ts.isFunctionDeclaration(node) ||
|
|
407
|
+
ts.isFunctionExpression(node) ||
|
|
408
|
+
ts.isArrowFunction(node) ||
|
|
409
|
+
ts.isMethodDeclaration(node) ||
|
|
410
|
+
ts.isConstructorDeclaration(node) ||
|
|
411
|
+
ts.isGetAccessorDeclaration(node) ||
|
|
412
|
+
ts.isSetAccessorDeclaration(node)
|
|
413
|
+
) {
|
|
414
|
+
currentScopeLazy = true;
|
|
415
|
+
}
|
|
304
416
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
currentScopeLazy = true;
|
|
417
|
+
if (ts.isPropertyDeclaration(node)) {
|
|
418
|
+
const isStatic = node.modifiers?.some((m) => m.kind === ts.SyntaxKind.StaticKeyword);
|
|
419
|
+
if (!isStatic) currentScopeLazy = true;
|
|
309
420
|
}
|
|
310
|
-
}
|
|
311
421
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
const
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
422
|
+
if (!currentScopeLazy && ts.isIdentifier(node)) {
|
|
423
|
+
const isImportedSymbol = localToExportedName.has(node.text);
|
|
424
|
+
const isNamespaceReference = namespaceImportName && node.text === namespaceImportName;
|
|
425
|
+
|
|
426
|
+
if (isImportedSymbol || isNamespaceReference) {
|
|
427
|
+
const parent = node.parent;
|
|
428
|
+
|
|
429
|
+
// Protection 1: Skip metadata/declarations references
|
|
430
|
+
const isImportOrExportDeclarationRef =
|
|
431
|
+
ts.isImportSpecifier(parent) ||
|
|
432
|
+
ts.isImportClause(parent) ||
|
|
433
|
+
ts.isNamespaceImport(parent) ||
|
|
434
|
+
ts.isExportSpecifier(parent);
|
|
435
|
+
|
|
436
|
+
if (isImportOrExportDeclarationRef) return;
|
|
437
|
+
|
|
438
|
+
// Protection 2: Avoid object property name access False Positives (obj.foo)
|
|
439
|
+
if (ts.isPropertyAccessExpression(parent) && parent.name === node) return;
|
|
440
|
+
|
|
441
|
+
// Protection 3: Avoid object assignment keys False Positives ({ foo: 123 })
|
|
442
|
+
if (ts.isPropertyAssignment(parent) && parent.name === node) return;
|
|
443
|
+
|
|
444
|
+
// Protection 4: Avoid shadow declarations with matching names
|
|
445
|
+
if (
|
|
446
|
+
(ts.isMethodDeclaration(parent) ||
|
|
447
|
+
ts.isPropertyDeclaration(parent) ||
|
|
448
|
+
ts.isClassDeclaration(parent) ||
|
|
449
|
+
ts.isInterfaceDeclaration(parent) ||
|
|
450
|
+
ts.isFunctionDeclaration(parent)) &&
|
|
451
|
+
parent.name === node
|
|
452
|
+
) {
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// (Hoisting check 1): Direct or renamed named/default import usage
|
|
457
|
+
if (isImportedSymbol) {
|
|
458
|
+
const exportedName = localToExportedName.get(node.text)!;
|
|
459
|
+
if (hoistedExports.has(exportedName)) {
|
|
460
|
+
return; // Perfectly safe hoisted function call/reference!
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// (Hoisting check 2): Namespace import property access usage (ns.foo())
|
|
465
|
+
if (isNamespaceReference) {
|
|
466
|
+
if (ts.isPropertyAccessExpression(parent) && parent.expression === node) {
|
|
467
|
+
const propName = parent.name.text;
|
|
468
|
+
if (hoistedExports.has(propName)) {
|
|
469
|
+
return; // Perfectly safe property from namespace!
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// Protection 5: Type contexts checks
|
|
324
475
|
let isInTypeContext = false;
|
|
325
476
|
let checkParent: ts.Node | undefined = parent;
|
|
326
477
|
while (checkParent && checkParent !== sourceFile) {
|
|
327
478
|
if (
|
|
328
|
-
ts.isTypeNode(checkParent) ||
|
|
329
|
-
ts.isTypeReferenceNode(checkParent) ||
|
|
330
|
-
ts.isTypeAliasDeclaration(checkParent) ||
|
|
479
|
+
ts.isTypeNode(checkParent) ||
|
|
480
|
+
ts.isTypeReferenceNode(checkParent) ||
|
|
481
|
+
ts.isTypeAliasDeclaration(checkParent) ||
|
|
331
482
|
ts.isInterfaceDeclaration(checkParent)
|
|
332
483
|
) {
|
|
333
484
|
isInTypeContext = true;
|
|
@@ -342,12 +493,12 @@ function hasTopLevelUsage(fromFile: string, toFile: string): boolean {
|
|
|
342
493
|
}
|
|
343
494
|
}
|
|
344
495
|
}
|
|
345
|
-
}
|
|
346
496
|
|
|
347
|
-
|
|
348
|
-
}
|
|
497
|
+
ts.forEachChild(node, (n) => checkNodeUsage(n, currentScopeLazy));
|
|
498
|
+
}
|
|
349
499
|
|
|
350
500
|
checkNodeUsage(sourceFile, false);
|
|
501
|
+
topLevelUsageCache.set(cacheKey, dangerousTopLevelUsage);
|
|
351
502
|
return dangerousTopLevelUsage;
|
|
352
503
|
}
|
|
353
504
|
|
|
@@ -362,9 +513,7 @@ function canReach(start: string, target: string): boolean {
|
|
|
362
513
|
seen.add(current);
|
|
363
514
|
|
|
364
515
|
const deps = graph.get(current) || [];
|
|
365
|
-
for (const dep of deps)
|
|
366
|
-
stack.push(dep);
|
|
367
|
-
}
|
|
516
|
+
for (const dep of deps) stack.push(dep);
|
|
368
517
|
}
|
|
369
518
|
return false;
|
|
370
519
|
}
|
|
@@ -405,12 +554,10 @@ function main() {
|
|
|
405
554
|
|
|
406
555
|
console.log(`🔍 Found ${entryPoints.length} entry point(s) for analysis. Building graph...\n`);
|
|
407
556
|
|
|
408
|
-
// Phase 1: Deep parse all files globally across all entry points
|
|
409
557
|
for (const entryPoint of entryPoints) {
|
|
410
558
|
parseFile(entryPoint);
|
|
411
559
|
}
|
|
412
560
|
|
|
413
|
-
// Phase 2: Traverse the global graph to discover all unique cycles
|
|
414
561
|
const visited = new Map<string, NodeState>();
|
|
415
562
|
const currentStack: string[] = [];
|
|
416
563
|
|
|
@@ -440,39 +587,27 @@ function main() {
|
|
|
440
587
|
}
|
|
441
588
|
|
|
442
589
|
for (const entryPoint of entryPoints) {
|
|
443
|
-
if (!visited.has(entryPoint))
|
|
444
|
-
findCycles(entryPoint);
|
|
445
|
-
}
|
|
590
|
+
if (!visited.has(entryPoint)) findCycles(entryPoint);
|
|
446
591
|
}
|
|
447
592
|
|
|
448
|
-
// Phase 2.5: Smart AST Filtering (Filter out runtime-safe / lazy cycles)
|
|
449
593
|
const criticalCycles: string[][] = [];
|
|
450
594
|
|
|
451
595
|
for (const cycle of allUniqueCycles) {
|
|
452
596
|
let isHarmfulCycle = false;
|
|
453
|
-
|
|
454
|
-
// A cycle is harmful if AT LEAST ONE link in it uses imports on top-level
|
|
455
597
|
for (let i = 0; i < cycle.length - 1; i++) {
|
|
456
598
|
if (hasTopLevelUsage(cycle[i], cycle[i + 1])) {
|
|
457
599
|
isHarmfulCycle = true;
|
|
458
600
|
break;
|
|
459
601
|
}
|
|
460
602
|
}
|
|
461
|
-
|
|
462
|
-
if (isHarmfulCycle) {
|
|
463
|
-
criticalCycles.push(cycle);
|
|
464
|
-
}
|
|
603
|
+
if (isHarmfulCycle) criticalCycles.push(cycle);
|
|
465
604
|
}
|
|
466
605
|
|
|
467
|
-
// Phase 3: Intelligently distribute critical cycles to their native entry points
|
|
468
606
|
const entryPointCycles = new Map<string, string[][]>();
|
|
469
|
-
for (const ep of entryPoints)
|
|
470
|
-
entryPointCycles.set(ep, []);
|
|
471
|
-
}
|
|
607
|
+
for (const ep of entryPoints) entryPointCycles.set(ep, []);
|
|
472
608
|
|
|
473
609
|
for (const cycle of criticalCycles) {
|
|
474
610
|
const firstFile = cycle[0];
|
|
475
|
-
|
|
476
611
|
const matchedEp = entryPoints.find((ep) => {
|
|
477
612
|
const epDir = path.dirname(ep);
|
|
478
613
|
return firstFile.startsWith(epDir + path.sep) || firstFile === ep;
|
|
@@ -482,15 +617,11 @@ function main() {
|
|
|
482
617
|
entryPointCycles.get(matchedEp)!.push(cycle);
|
|
483
618
|
} else {
|
|
484
619
|
const reachingEp = entryPoints.find((ep) => canReach(ep, firstFile));
|
|
485
|
-
if (reachingEp)
|
|
486
|
-
|
|
487
|
-
} else {
|
|
488
|
-
entryPointCycles.get(entryPoints[0])!.push(cycle);
|
|
489
|
-
}
|
|
620
|
+
if (reachingEp) entryPointCycles.get(reachingEp)!.push(cycle);
|
|
621
|
+
else entryPointCycles.get(entryPoints[0])!.push(cycle);
|
|
490
622
|
}
|
|
491
623
|
}
|
|
492
624
|
|
|
493
|
-
// Phase 4: Output the clean, perfectly targeted report
|
|
494
625
|
let globalHasCycles = false;
|
|
495
626
|
|
|
496
627
|
for (const entryPoint of entryPoints) {
|
|
@@ -499,14 +630,20 @@ function main() {
|
|
|
499
630
|
|
|
500
631
|
if (cycles.length > 0) {
|
|
501
632
|
globalHasCycles = true;
|
|
502
|
-
console.error(`❌
|
|
633
|
+
console.error(`❌ ${absoluteEntry} — Found ${cycles.length} critical circular dependencies:`);
|
|
634
|
+
|
|
503
635
|
cycles.forEach((cycle, index) => {
|
|
504
|
-
|
|
505
|
-
|
|
636
|
+
console.error(` ${index + 1})`, '-'.repeat(80));
|
|
637
|
+
for (let i = 1; i < cycle.length; i++) {
|
|
638
|
+
const nextFile = i === cycle.length - 1 ? cycle[1] : cycle[i + 1];
|
|
639
|
+
const isTopLevel = hasTopLevelUsage(cycle[i], nextFile);
|
|
640
|
+
const prefix = isTopLevel ? ' 💥 [Top-level] ' : ' ⏳ [Lazy] ';
|
|
641
|
+
console.error(`${prefix}${path.resolve(cycle[i])}`);
|
|
642
|
+
}
|
|
506
643
|
});
|
|
507
644
|
console.error('');
|
|
508
645
|
} else {
|
|
509
|
-
console.log(`✅
|
|
646
|
+
console.log(`✅ ${absoluteEntry}`);
|
|
510
647
|
}
|
|
511
648
|
}
|
|
512
649
|
|