ts-unused 1.0.3 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,4 +10,4 @@ export interface AnalyzeProjectOptions {
10
10
  */
11
11
  isTestFile?: IsTestFileFn;
12
12
  }
13
- export declare function analyzeProject(tsConfigPath: string, onProgress?: (current: number, total: number, filePath: string) => void, targetFilePath?: string, isTestFileOrOptions?: IsTestFileFn | AnalyzeProjectOptions): AnalysisResults;
13
+ export declare function analyzeProject(tsConfigPath: string, onProgress?: (current: number, total: number, filePath: string) => void, targetFilePath?: string, isTestFileOrOptions?: IsTestFileFn | AnalyzeProjectOptions): Promise<AnalysisResults>;
@@ -1,13 +1,14 @@
1
1
  import path from "node:path";
2
- import { Project } from "ts-morph";
2
+ import { Project, SyntaxKind } from "ts-morph";
3
+ import { analyzeFunctionReturnTypes } from "./analyzeFunctionReturnTypes";
4
+ import { analyzeInterfaces } from "./analyzeInterfaces";
5
+ import { analyzeTypeAliases } from "./analyzeTypeAliases";
6
+ import { checkExportUsage } from "./checkExportUsage";
3
7
  import { defaultConfig } from "./config";
4
- import { findNeverReturnedTypes } from "./findNeverReturnedTypes";
5
- import { findUnusedExports } from "./findUnusedExports";
6
- import { findUnusedProperties } from "./findUnusedProperties";
7
8
  import { hasNoCheck } from "./hasNoCheck";
8
9
  import { createIsTestFile, isTestFile as defaultIsTestFile } from "./isTestFile";
9
10
  import { matchesFilePattern } from "./patternMatcher";
10
- export function analyzeProject(tsConfigPath, onProgress, targetFilePath, isTestFileOrOptions) {
11
+ export async function analyzeProject(tsConfigPath, onProgress, targetFilePath, isTestFileOrOptions) {
11
12
  // Handle backward compatibility: can pass IsTestFileFn directly or options object
12
13
  let options = {};
13
14
  if (typeof isTestFileOrOptions === "function") {
@@ -50,41 +51,52 @@ export function analyzeProject(tsConfigPath, onProgress, targetFilePath, isTestF
50
51
  });
51
52
  const totalFiles = filesToAnalyze.length;
52
53
  let currentFile = 0;
53
- const filesProcessed = new Set();
54
- const progressCallback = onProgress
55
- ? (filePath) => {
56
- // Only increment once per file (called from both exports and properties analysis)
57
- if (!filesProcessed.has(filePath)) {
58
- filesProcessed.add(filePath);
59
- currentFile++;
60
- onProgress(currentFile, totalFiles, filePath);
61
- }
62
- }
63
- : undefined;
64
- // Build options for child functions
65
- const exportOptions = {
66
- ignoreFilePatterns: config.ignoreFilePatterns,
54
+ // Build options for analysis
55
+ const exportCheckOptions = {
67
56
  ignoreExports: config.ignoreExports,
68
57
  ignoreModuleAugmentations: config.ignoreModuleAugmentations,
69
58
  };
70
- const propertyOptions = {
71
- ignoreFilePatterns: config.ignoreFilePatterns,
59
+ const propertyAnalyzeOptions = {
72
60
  ignoreProperties: config.ignoreProperties,
73
61
  ignoreTypes: config.ignoreTypes,
74
62
  };
75
- const neverReturnedOptions = {
76
- ignoreFilePatterns: config.ignoreFilePatterns,
77
- };
78
- // Analyze based on config flags
79
- const unusedExports = config.analyzeExports
80
- ? findUnusedExports(project, tsConfigDir, isTestFile, progressCallback, targetFilePath, exportOptions)
81
- : [];
82
- const unusedProperties = config.analyzeProperties
83
- ? findUnusedProperties(project, tsConfigDir, isTestFile, progressCallback, targetFilePath, propertyOptions)
84
- : [];
85
- const neverReturnedTypes = config.analyzeNeverReturnedTypes
86
- ? findNeverReturnedTypes(project, tsConfigDir, isTestFile, progressCallback, targetFilePath, neverReturnedOptions)
87
- : [];
63
+ // Results arrays
64
+ const unusedExports = [];
65
+ const unusedProperties = [];
66
+ const neverReturnedTypes = [];
67
+ // Single pass over all files - much more efficient than 3 separate passes
68
+ for (const sourceFile of filesToAnalyze) {
69
+ const filePath = sourceFile.getFilePath();
70
+ const relativePath = path.relative(tsConfigDir, filePath);
71
+ // Report progress
72
+ if (onProgress) {
73
+ currentFile++;
74
+ onProgress(currentFile, totalFiles, relativePath);
75
+ }
76
+ // Analyze exports
77
+ if (config.analyzeExports) {
78
+ const exports = sourceFile.getExportedDeclarations();
79
+ for (const [exportName, declarations] of exports.entries()) {
80
+ const unusedExport = checkExportUsage(exportName, declarations, sourceFile, tsConfigDir, isTestFile, exportCheckOptions);
81
+ if (unusedExport) {
82
+ unusedExports.push(unusedExport);
83
+ }
84
+ }
85
+ }
86
+ // Analyze properties
87
+ if (config.analyzeProperties) {
88
+ analyzeInterfaces(sourceFile, tsConfigDir, isTestFile, unusedProperties, project, propertyAnalyzeOptions);
89
+ analyzeTypeAliases(sourceFile, tsConfigDir, isTestFile, unusedProperties, project, propertyAnalyzeOptions);
90
+ }
91
+ // Analyze never-returned types
92
+ if (config.analyzeNeverReturnedTypes) {
93
+ const functions = sourceFile.getDescendantsOfKind(SyntaxKind.FunctionDeclaration);
94
+ for (const func of functions) {
95
+ const funcResults = analyzeFunctionReturnTypes(func, sourceFile, tsConfigDir);
96
+ neverReturnedTypes.push(...funcResults);
97
+ }
98
+ }
99
+ }
88
100
  // Identify completely unused files (where all exports are unused)
89
101
  const unusedFiles = [];
90
102
  if (config.detectUnusedFiles) {