@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 CHANGED
@@ -1,20 +1,8 @@
1
- # @ts-stack/cycle-detector
1
+ # Execution-Aware Circular Dependency Detector for TypeScript
2
2
 
3
- A blistering fast, lightweight, zero-dependency CLI utility designed to detect circular dependencies in TypeScript (ESM) projects.
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
- Unlike other tools, it uses the native TypeScript Compiler API for smart path resolution (respecting your `tsconfig.json` paths/aliases) and **completely ignores type-only imports** (`import type`), as they don't cause actual runtime issues in Node.js.
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
- Also you can install this utility locally:
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 && ts.isNamedImports(namedBindings)) {
40
- return !namedBindings.elements.every((el) => el.isTypeOnly);
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
- if (mainField) {
93
- const parts = path.normalize(mainField).split(path.sep);
94
- if (parts.length > 1 && parts[0] !== '.' && parts[0] !== '..') {
95
- outDirName = parts[0];
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
- else if (parts.length > 2 && (parts[0] === '.' || parts[0] === '..')) {
98
- outDirName = parts[1];
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
- if (result.resolvedModule.isExternalLibraryImport) {
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
- const content = fs.readFileSync(filePath, 'utf8');
191
- const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);
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
- const content = fs.readFileSync(fromFile, 'utf8');
219
- const sourceFile = ts.createSourceFile(fromFile, content, ts.ScriptTarget.Latest, true);
220
- const importedSymbols = new Set();
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
- importedSymbols.add(clause.name.text); // default import
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
- importedSymbols.add(clause.namedBindings.name.text); // import * as namespace
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
- importedSymbols.add(el.name.text); // named imports
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
- if (importedSymbols.size === 0)
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
- if (importedSymbols.has(node.text)) {
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
- // Verify it's an actual usage reference, not the import clause definition itself
286
- const isImportDeclarationRef = ts.isImportSpecifier(parent) ||
402
+ // Protection 1: Skip metadata/declarations references
403
+ const isImportOrExportDeclarationRef = ts.isImportSpecifier(parent) ||
287
404
  ts.isImportClause(parent) ||
288
- ts.isNamespaceImport(parent);
289
- if (!isImportDeclarationRef) {
290
- // Verify it's not just a TypeScript Type usage context (which is safe in runtime)
291
- let isInTypeContext = false;
292
- let checkParent = parent;
293
- while (checkParent && checkParent !== sourceFile) {
294
- if (ts.isTypeNode(checkParent) ||
295
- ts.isTypeReferenceNode(checkParent) ||
296
- ts.isTypeAliasDeclaration(checkParent) ||
297
- ts.isInterfaceDeclaration(checkParent)) {
298
- isInTypeContext = true;
299
- break;
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
- if (!isInTypeContext) {
304
- dangerousTopLevelUsage = true;
305
- return;
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(`❌ [${absoluteEntry}] — Found ${cycles.length} critical circular dependencies:`);
577
+ console.error(`❌ ${absoluteEntry} — Found ${cycles.length} critical circular dependencies:`);
440
578
  cycles.forEach((cycle, index) => {
441
- const readableCycle = cycle.map((p) => path.resolve(p)).join('\n -> ');
442
- console.error(` ${index + 1}) ${readableCycle}`);
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(`✅ [${absoluteEntry}] — Clean!`);
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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ts-stack/cycle-detector",
3
3
  "type": "module",
4
- "version": "1.0.4",
4
+ "version": "1.1.1",
5
5
  "bin": {
6
6
  "cycle-detector": "./dist/index.js"
7
7
  },
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; } | null>();
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 (!node.importClause) return true;
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 && ts.isNamedImports(namedBindings)) {
48
- return !namedBindings.elements.every((el) => el.isTypeOnly);
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
- if (mainField) {
112
- const parts = path.normalize(mainField).split(path.sep);
113
- if (parts.length > 1 && parts[0] !== '.' && parts[0] !== '..') {
114
- outDirName = parts[0];
115
- } else if (parts.length > 2 && (parts[0] === '.' || parts[0] === '..')) {
116
- outDirName = parts[1];
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
- if (result.resolvedModule.isExternalLibraryImport) {
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
- const content = fs.readFileSync(filePath, 'utf8');
213
- const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);
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
- const importedSymbols = new Set<string>();
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) importedSymbols.add(clause.name.text); // default import
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
- importedSymbols.add(clause.namedBindings.name.text); // import * as namespace
369
+ namespaceImportName = clause.namedBindings.name.text;
262
370
  } else if (ts.isNamedImports(clause.namedBindings)) {
263
371
  for (const el of clause.namedBindings.elements) {
264
- importedSymbols.add(el.name.text); // named imports
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) return true;
283
- if (importedSymbols.size === 0) return false;
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
- if (dangerousTopLevelUsage) return;
290
-
291
- let currentScopeLazy = isInsideLazyScope;
292
-
293
- if (
294
- ts.isFunctionDeclaration(node) ||
295
- ts.isFunctionExpression(node) ||
296
- ts.isArrowFunction(node) ||
297
- ts.isMethodDeclaration(node) ||
298
- ts.isConstructorDeclaration(node) ||
299
- ts.isGetAccessorDeclaration(node) ||
300
- ts.isSetAccessorDeclaration(node)
301
- ) {
302
- currentScopeLazy = true;
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
- if (ts.isPropertyDeclaration(node)) {
306
- const isStatic = node.modifiers?.some(m => m.kind === ts.SyntaxKind.StaticKeyword);
307
- if (!isStatic) {
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
- if (!currentScopeLazy && ts.isIdentifier(node)) {
313
- if (importedSymbols.has(node.text)) {
314
- const parent = node.parent;
315
-
316
- // Verify it's an actual usage reference, not the import clause definition itself
317
- const isImportDeclarationRef =
318
- ts.isImportSpecifier(parent) ||
319
- ts.isImportClause(parent) ||
320
- ts.isNamespaceImport(parent);
321
-
322
- if (!isImportDeclarationRef) {
323
- // Verify it's not just a TypeScript Type usage context (which is safe in runtime)
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
- ts.forEachChild(node, (n) => checkNodeUsage(n, currentScopeLazy));
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
- entryPointCycles.get(reachingEp)!.push(cycle);
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(`❌ [${absoluteEntry}] — Found ${cycles.length} critical circular dependencies:`);
633
+ console.error(`❌ ${absoluteEntry} — Found ${cycles.length} critical circular dependencies:`);
634
+
503
635
  cycles.forEach((cycle, index) => {
504
- const readableCycle = cycle.map((p) => path.resolve(p)).join('\n -> ');
505
- console.error(` ${index + 1}) ${readableCycle}`);
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(`✅ [${absoluteEntry}] — Clean!`);
646
+ console.log(`✅ ${absoluteEntry}`);
510
647
  }
511
648
  }
512
649