@bfra.me/workspace-analyzer 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +402 -0
- package/lib/chunk-4LSFAAZW.js +1 -0
- package/lib/chunk-JDF7DQ4V.js +27 -0
- package/lib/chunk-WOJ4C7N7.js +7122 -0
- package/lib/cli.d.ts +1 -0
- package/lib/cli.js +318 -0
- package/lib/index.d.ts +3701 -0
- package/lib/index.js +1262 -0
- package/lib/types/index.d.ts +146 -0
- package/lib/types/index.js +28 -0
- package/package.json +89 -0
- package/src/analyzers/analyzer.ts +201 -0
- package/src/analyzers/architectural-analyzer.ts +304 -0
- package/src/analyzers/build-config-analyzer.ts +334 -0
- package/src/analyzers/circular-import-analyzer.ts +463 -0
- package/src/analyzers/config-consistency-analyzer.ts +335 -0
- package/src/analyzers/dead-code-analyzer.ts +565 -0
- package/src/analyzers/duplicate-code-analyzer.ts +626 -0
- package/src/analyzers/duplicate-dependency-analyzer.ts +381 -0
- package/src/analyzers/eslint-config-analyzer.ts +281 -0
- package/src/analyzers/exports-field-analyzer.ts +324 -0
- package/src/analyzers/index.ts +388 -0
- package/src/analyzers/large-dependency-analyzer.ts +535 -0
- package/src/analyzers/package-json-analyzer.ts +349 -0
- package/src/analyzers/peer-dependency-analyzer.ts +275 -0
- package/src/analyzers/tree-shaking-analyzer.ts +623 -0
- package/src/analyzers/tsconfig-analyzer.ts +382 -0
- package/src/analyzers/unused-dependency-analyzer.ts +356 -0
- package/src/analyzers/version-alignment-analyzer.ts +308 -0
- package/src/api/analyze-workspace.ts +245 -0
- package/src/api/index.ts +11 -0
- package/src/cache/cache-manager.ts +495 -0
- package/src/cache/cache-schema.ts +247 -0
- package/src/cache/change-detector.ts +169 -0
- package/src/cache/file-hasher.ts +65 -0
- package/src/cache/index.ts +47 -0
- package/src/cli/commands/analyze.ts +240 -0
- package/src/cli/commands/index.ts +5 -0
- package/src/cli/index.ts +61 -0
- package/src/cli/types.ts +65 -0
- package/src/cli/ui.ts +213 -0
- package/src/cli.ts +9 -0
- package/src/config/defaults.ts +183 -0
- package/src/config/index.ts +81 -0
- package/src/config/loader.ts +270 -0
- package/src/config/merger.ts +229 -0
- package/src/config/schema.ts +263 -0
- package/src/core/incremental-analyzer.ts +462 -0
- package/src/core/index.ts +34 -0
- package/src/core/orchestrator.ts +416 -0
- package/src/graph/dependency-graph.ts +408 -0
- package/src/graph/index.ts +19 -0
- package/src/index.ts +417 -0
- package/src/parser/config-parser.ts +491 -0
- package/src/parser/import-extractor.ts +340 -0
- package/src/parser/index.ts +54 -0
- package/src/parser/typescript-parser.ts +95 -0
- package/src/performance/bundle-estimator.ts +444 -0
- package/src/performance/index.ts +27 -0
- package/src/reporters/console-reporter.ts +355 -0
- package/src/reporters/index.ts +49 -0
- package/src/reporters/json-reporter.ts +273 -0
- package/src/reporters/markdown-reporter.ts +349 -0
- package/src/reporters/reporter.ts +399 -0
- package/src/rules/builtin-rules.ts +709 -0
- package/src/rules/index.ts +52 -0
- package/src/rules/rule-engine.ts +409 -0
- package/src/scanner/index.ts +18 -0
- package/src/scanner/workspace-scanner.ts +403 -0
- package/src/types/index.ts +176 -0
- package/src/types/result.ts +19 -0
- package/src/utils/index.ts +7 -0
- package/src/utils/pattern-matcher.ts +48 -0
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,3701 @@
|
|
|
1
|
+
import { Result } from '@bfra.me/es/result';
|
|
2
|
+
export { Err, Ok, Result, err, flatMap, fromPromise, fromThrowable, isErr, isOk, map, mapErr, ok, unwrap, unwrapOr } from '@bfra.me/es/result';
|
|
3
|
+
import { IssueCategory, Severity, Issue, IssueLocation, AnalysisProgress, AnalysisResult } from './types/index.js';
|
|
4
|
+
export { AnalysisError, AnalysisResultType, AnalysisSummary, AnalyzeWorkspaceOptions, AnalyzerConfig } from './types/index.js';
|
|
5
|
+
import { SourceFile, Project } from 'ts-morph';
|
|
6
|
+
import { ChangeDetectorOptions, ChangeDetector, FileHasher } from '@bfra.me/es/watcher';
|
|
7
|
+
export { ChangeDetector, ChangeDetectorOptions, FileHasher, createChangeDetector, createFileHasher } from '@bfra.me/es/watcher';
|
|
8
|
+
import { z } from 'zod';
|
|
9
|
+
import { ParseError } from '@bfra.me/doc-sync/types';
|
|
10
|
+
export { ParseError, ParseErrorCode } from '@bfra.me/doc-sync/types';
|
|
11
|
+
export { TypeScriptParserOptions, createProject, parseSourceContent, parseSourceFile } from '@bfra.me/doc-sync/parsers';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Workspace scanner for discovering and analyzing packages in a monorepo.
|
|
15
|
+
*
|
|
16
|
+
* Adapts the createPackageScanner() pattern from @bfra.me/doc-sync for workspace analysis.
|
|
17
|
+
* Uses fs.readdir pattern (not fast-glob) for better control over directory traversal.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Options for configuring the workspace scanner.
|
|
22
|
+
*/
|
|
23
|
+
interface WorkspaceScannerOptions {
|
|
24
|
+
/** Root directory of the workspace/monorepo */
|
|
25
|
+
readonly rootDir: string;
|
|
26
|
+
/** Glob patterns for package locations (e.g., ['packages/*', 'apps/*']) */
|
|
27
|
+
readonly includePatterns?: readonly string[];
|
|
28
|
+
/** Package names to exclude from scanning */
|
|
29
|
+
readonly excludePackages?: readonly string[];
|
|
30
|
+
/** File extensions to include in source file collection */
|
|
31
|
+
readonly sourceExtensions?: readonly string[];
|
|
32
|
+
/** Directories to skip during source file collection */
|
|
33
|
+
readonly excludeDirs?: readonly string[];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Minimal package.json structure for workspace analysis.
|
|
37
|
+
*/
|
|
38
|
+
interface WorkspacePackageJson {
|
|
39
|
+
readonly name: string;
|
|
40
|
+
readonly version: string;
|
|
41
|
+
readonly description?: string;
|
|
42
|
+
readonly main?: string;
|
|
43
|
+
readonly module?: string;
|
|
44
|
+
readonly types?: string;
|
|
45
|
+
readonly exports?: Record<string, unknown>;
|
|
46
|
+
readonly dependencies?: Readonly<Record<string, string>>;
|
|
47
|
+
readonly devDependencies?: Readonly<Record<string, string>>;
|
|
48
|
+
readonly peerDependencies?: Readonly<Record<string, string>>;
|
|
49
|
+
readonly optionalDependencies?: Readonly<Record<string, string>>;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Information about a discovered workspace package.
|
|
53
|
+
*/
|
|
54
|
+
interface WorkspacePackage {
|
|
55
|
+
/** Package name from package.json */
|
|
56
|
+
readonly name: string;
|
|
57
|
+
/** Package version from package.json */
|
|
58
|
+
readonly version: string;
|
|
59
|
+
/** Absolute path to the package directory */
|
|
60
|
+
readonly packagePath: string;
|
|
61
|
+
/** Absolute path to package.json */
|
|
62
|
+
readonly packageJsonPath: string;
|
|
63
|
+
/** Absolute path to source directory (if exists) */
|
|
64
|
+
readonly srcPath: string;
|
|
65
|
+
/** Parsed package.json content */
|
|
66
|
+
readonly packageJson: WorkspacePackageJson;
|
|
67
|
+
/** List of source file paths in the package */
|
|
68
|
+
readonly sourceFiles: readonly string[];
|
|
69
|
+
/** Whether the package has a tsconfig.json */
|
|
70
|
+
readonly hasTsConfig: boolean;
|
|
71
|
+
/** Whether the package has an eslint config */
|
|
72
|
+
readonly hasEslintConfig: boolean;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Error that occurred during workspace scanning.
|
|
76
|
+
*/
|
|
77
|
+
interface ScanError {
|
|
78
|
+
/** Error code for programmatic handling */
|
|
79
|
+
readonly code: 'INVALID_PATH' | 'NO_PACKAGE_JSON' | 'INVALID_PACKAGE_JSON' | 'READ_ERROR';
|
|
80
|
+
/** Human-readable error message */
|
|
81
|
+
readonly message: string;
|
|
82
|
+
/** Path where the error occurred */
|
|
83
|
+
readonly path: string;
|
|
84
|
+
/** Underlying error cause */
|
|
85
|
+
readonly cause?: unknown;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Result of a workspace scan operation.
|
|
89
|
+
*/
|
|
90
|
+
interface WorkspaceScanResult {
|
|
91
|
+
/** All discovered packages */
|
|
92
|
+
readonly packages: readonly WorkspacePackage[];
|
|
93
|
+
/** Root workspace path */
|
|
94
|
+
readonly workspacePath: string;
|
|
95
|
+
/** Errors encountered during scanning */
|
|
96
|
+
readonly errors: readonly ScanError[];
|
|
97
|
+
/** Duration of scan in milliseconds */
|
|
98
|
+
readonly durationMs: number;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Creates a workspace scanner for discovering and analyzing packages.
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```ts
|
|
105
|
+
* const scanner = createWorkspaceScanner({rootDir: '/path/to/monorepo'})
|
|
106
|
+
* const result = await scanner.scan()
|
|
107
|
+
*
|
|
108
|
+
* for (const pkg of result.packages) {
|
|
109
|
+
* console.log(`Found package: ${pkg.name}`)
|
|
110
|
+
* }
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
declare function createWorkspaceScanner(options: WorkspaceScannerOptions): {
|
|
114
|
+
/** Scan the entire workspace for packages */
|
|
115
|
+
readonly scan: () => Promise<WorkspaceScanResult>;
|
|
116
|
+
/** Scan a single package directory */
|
|
117
|
+
readonly scanPackage: (packagePath: string) => Promise<Result<WorkspacePackage, ScanError>>;
|
|
118
|
+
/** Collect source files from a directory */
|
|
119
|
+
readonly collectSourceFiles: (dir: string) => Promise<readonly string[]>;
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* Filter packages by name pattern.
|
|
123
|
+
*/
|
|
124
|
+
declare function filterPackagesByPattern(packages: readonly WorkspacePackage[], pattern: string): WorkspacePackage[];
|
|
125
|
+
/**
|
|
126
|
+
* Group packages by their npm scope.
|
|
127
|
+
*/
|
|
128
|
+
declare function groupPackagesByScope(packages: readonly WorkspacePackage[]): Map<string, WorkspacePackage[]>;
|
|
129
|
+
/**
|
|
130
|
+
* Extract the scope from a scoped package name.
|
|
131
|
+
*/
|
|
132
|
+
declare function getPackageScope(packageName: string): string | undefined;
|
|
133
|
+
/**
|
|
134
|
+
* Get the unscoped name from a package name.
|
|
135
|
+
*/
|
|
136
|
+
declare function getUnscopedName(packageName: string): string;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Core analyzer interface and types for workspace analysis.
|
|
140
|
+
*
|
|
141
|
+
* Defines the plugin architecture contract that all analyzers must implement,
|
|
142
|
+
* enabling extensible and composable analysis pipelines.
|
|
143
|
+
*/
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Context provided to analyzers during analysis runs.
|
|
147
|
+
* Contains all information needed to perform analysis without side effects.
|
|
148
|
+
*/
|
|
149
|
+
interface AnalysisContext$1 {
|
|
150
|
+
/** Root path of the workspace being analyzed */
|
|
151
|
+
readonly workspacePath: string;
|
|
152
|
+
/** All packages discovered in the workspace */
|
|
153
|
+
readonly packages: readonly WorkspacePackage[];
|
|
154
|
+
/** Analyzer-specific configuration options */
|
|
155
|
+
readonly config: AnalyzerOptions;
|
|
156
|
+
/** Report progress during long-running analysis */
|
|
157
|
+
readonly reportProgress?: (message: string) => void;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Options for configuring analyzer behavior.
|
|
161
|
+
*/
|
|
162
|
+
interface AnalyzerOptions {
|
|
163
|
+
/** Glob patterns for files to include */
|
|
164
|
+
readonly include?: readonly string[];
|
|
165
|
+
/** Glob patterns for files to exclude */
|
|
166
|
+
readonly exclude?: readonly string[];
|
|
167
|
+
/** Minimum severity level to report */
|
|
168
|
+
readonly minSeverity?: Severity;
|
|
169
|
+
/** Categories to analyze (empty means all) */
|
|
170
|
+
readonly categories?: readonly IssueCategory[];
|
|
171
|
+
/** Analyzer-specific rule configurations */
|
|
172
|
+
readonly rules?: Readonly<Record<string, unknown>>;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Error that can occur during analysis.
|
|
176
|
+
*/
|
|
177
|
+
interface AnalyzerError {
|
|
178
|
+
/** Error code for programmatic handling */
|
|
179
|
+
readonly code: string;
|
|
180
|
+
/** Human-readable error message */
|
|
181
|
+
readonly message: string;
|
|
182
|
+
/** Additional context about the error */
|
|
183
|
+
readonly context?: Readonly<Record<string, unknown>>;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Metadata describing an analyzer implementation.
|
|
187
|
+
*/
|
|
188
|
+
interface AnalyzerMetadata {
|
|
189
|
+
/** Unique identifier for this analyzer */
|
|
190
|
+
readonly id: string;
|
|
191
|
+
/** Human-readable name */
|
|
192
|
+
readonly name: string;
|
|
193
|
+
/** Description of what this analyzer checks */
|
|
194
|
+
readonly description: string;
|
|
195
|
+
/** Categories of issues this analyzer can detect */
|
|
196
|
+
readonly categories: readonly IssueCategory[];
|
|
197
|
+
/** Default severity for issues from this analyzer */
|
|
198
|
+
readonly defaultSeverity: Severity;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Core interface that all analyzers must implement.
|
|
202
|
+
*
|
|
203
|
+
* @example
|
|
204
|
+
* ```ts
|
|
205
|
+
* const myAnalyzer: Analyzer = {
|
|
206
|
+
* metadata: {
|
|
207
|
+
* id: 'my-analyzer',
|
|
208
|
+
* name: 'My Custom Analyzer',
|
|
209
|
+
* description: 'Checks for custom patterns',
|
|
210
|
+
* categories: ['architecture'],
|
|
211
|
+
* defaultSeverity: 'warning',
|
|
212
|
+
* },
|
|
213
|
+
* async analyze(context) {
|
|
214
|
+
* const issues: Issue[] = []
|
|
215
|
+
* // Perform analysis...
|
|
216
|
+
* return ok(issues)
|
|
217
|
+
* },
|
|
218
|
+
* }
|
|
219
|
+
* ```
|
|
220
|
+
*/
|
|
221
|
+
interface Analyzer {
|
|
222
|
+
/** Metadata describing this analyzer */
|
|
223
|
+
readonly metadata: AnalyzerMetadata;
|
|
224
|
+
/**
|
|
225
|
+
* Perform analysis and return discovered issues.
|
|
226
|
+
*
|
|
227
|
+
* @param context - Analysis context with workspace information
|
|
228
|
+
* @returns Result containing issues found or an error
|
|
229
|
+
*/
|
|
230
|
+
readonly analyze: (context: AnalysisContext$1) => Promise<Result<readonly Issue[], AnalyzerError>>;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Factory function signature for creating analyzers.
|
|
234
|
+
*/
|
|
235
|
+
type AnalyzerFactory = (options?: AnalyzerOptions) => Analyzer;
|
|
236
|
+
/**
|
|
237
|
+
* Configuration for a single analyzer in the registry.
|
|
238
|
+
*/
|
|
239
|
+
interface AnalyzerRegistration {
|
|
240
|
+
/** The analyzer instance or factory */
|
|
241
|
+
readonly analyzer: Analyzer | AnalyzerFactory;
|
|
242
|
+
/** Whether this analyzer is enabled by default */
|
|
243
|
+
readonly enabled: boolean;
|
|
244
|
+
/** Priority for execution order (lower runs first) */
|
|
245
|
+
readonly priority: number;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Creates an issue with consistent defaults.
|
|
249
|
+
*
|
|
250
|
+
* @example
|
|
251
|
+
* ```ts
|
|
252
|
+
* const issue = createIssue({
|
|
253
|
+
* id: 'missing-types',
|
|
254
|
+
* title: 'Missing types field',
|
|
255
|
+
* description: 'package.json should declare a types entry point',
|
|
256
|
+
* severity: 'warning',
|
|
257
|
+
* category: 'configuration',
|
|
258
|
+
* location: {filePath: '/path/to/package.json'},
|
|
259
|
+
* })
|
|
260
|
+
* ```
|
|
261
|
+
*/
|
|
262
|
+
declare function createIssue(params: Omit<Issue, 'relatedLocations' | 'suggestion' | 'metadata'> & {
|
|
263
|
+
relatedLocations?: Issue['relatedLocations'];
|
|
264
|
+
suggestion?: Issue['suggestion'];
|
|
265
|
+
metadata?: Issue['metadata'];
|
|
266
|
+
}): Issue;
|
|
267
|
+
/**
|
|
268
|
+
* Helper to check if an analyzer should skip a category based on configuration.
|
|
269
|
+
*/
|
|
270
|
+
declare function shouldAnalyzeCategory(category: IssueCategory, options: AnalyzerOptions | undefined): boolean;
|
|
271
|
+
/**
|
|
272
|
+
* Helper to check if an issue meets minimum severity threshold.
|
|
273
|
+
*/
|
|
274
|
+
declare function meetsMinSeverity(severity: Severity, minSeverity: Severity | undefined): boolean;
|
|
275
|
+
/**
|
|
276
|
+
* Filters issues based on configuration options.
|
|
277
|
+
*/
|
|
278
|
+
declare function filterIssues(issues: readonly Issue[], options: AnalyzerOptions): readonly Issue[];
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Architectural rule engine for validating code patterns and enforcing best practices.
|
|
282
|
+
*
|
|
283
|
+
* Provides a plugin architecture for extensible analysis rules that detect
|
|
284
|
+
* architectural violations, anti-patterns, and best practice deviations.
|
|
285
|
+
*/
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Context provided to rules during evaluation.
|
|
289
|
+
*/
|
|
290
|
+
interface RuleContext {
|
|
291
|
+
/** The source file being evaluated */
|
|
292
|
+
readonly sourceFile: SourceFile;
|
|
293
|
+
/** The package containing the source file */
|
|
294
|
+
readonly pkg: WorkspacePackage;
|
|
295
|
+
/** Root path of the workspace */
|
|
296
|
+
readonly workspacePath: string;
|
|
297
|
+
/** All packages in the workspace for cross-package analysis */
|
|
298
|
+
readonly allPackages: readonly WorkspacePackage[];
|
|
299
|
+
/** Resolved tsconfig paths for alias validation */
|
|
300
|
+
readonly tsconfigPaths?: Readonly<Record<string, readonly string[]>>;
|
|
301
|
+
/** Layer configuration for architectural validation */
|
|
302
|
+
readonly layerConfig?: LayerConfiguration;
|
|
303
|
+
/** Report progress during evaluation */
|
|
304
|
+
readonly reportProgress?: (message: string) => void;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Layer configuration for enforcing architectural boundaries.
|
|
308
|
+
*/
|
|
309
|
+
interface LayerConfiguration {
|
|
310
|
+
/** Layer definitions with allowed dependencies */
|
|
311
|
+
readonly layers: readonly LayerDefinition[];
|
|
312
|
+
/** File patterns to layer mapping */
|
|
313
|
+
readonly patterns: readonly LayerPattern[];
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Defines an architectural layer with its allowed dependencies.
|
|
317
|
+
*/
|
|
318
|
+
interface LayerDefinition {
|
|
319
|
+
/** Layer name (e.g., 'domain', 'application', 'infrastructure') */
|
|
320
|
+
readonly name: string;
|
|
321
|
+
/** Other layers this layer can import from */
|
|
322
|
+
readonly allowedDependencies: readonly string[];
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Maps file patterns to architectural layers.
|
|
326
|
+
*/
|
|
327
|
+
interface LayerPattern {
|
|
328
|
+
/** Glob pattern to match files */
|
|
329
|
+
readonly pattern: string;
|
|
330
|
+
/** Layer this pattern belongs to */
|
|
331
|
+
readonly layer: string;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Result of a single rule violation.
|
|
335
|
+
*/
|
|
336
|
+
interface RuleViolation {
|
|
337
|
+
/** Rule that was violated */
|
|
338
|
+
readonly ruleId: string;
|
|
339
|
+
/** Location of the violation */
|
|
340
|
+
readonly location: IssueLocation;
|
|
341
|
+
/** Human-readable message explaining the violation */
|
|
342
|
+
readonly message: string;
|
|
343
|
+
/** Suggested fix for the violation */
|
|
344
|
+
readonly suggestion?: string;
|
|
345
|
+
/** Related locations (e.g., the imported module) */
|
|
346
|
+
readonly relatedLocations?: readonly IssueLocation[];
|
|
347
|
+
/** Additional metadata for machine processing */
|
|
348
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Result of evaluating a rule on a source file.
|
|
352
|
+
*/
|
|
353
|
+
interface RuleResult {
|
|
354
|
+
/** Violations found */
|
|
355
|
+
readonly violations: readonly RuleViolation[];
|
|
356
|
+
/** Whether the evaluation completed successfully */
|
|
357
|
+
readonly success: boolean;
|
|
358
|
+
/** Error message if evaluation failed */
|
|
359
|
+
readonly error?: string;
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Metadata describing a rule.
|
|
363
|
+
*/
|
|
364
|
+
interface RuleMetadata {
|
|
365
|
+
/** Unique identifier for the rule */
|
|
366
|
+
readonly id: string;
|
|
367
|
+
/** Human-readable name */
|
|
368
|
+
readonly name: string;
|
|
369
|
+
/** Description of what the rule checks */
|
|
370
|
+
readonly description: string;
|
|
371
|
+
/** Default severity for violations */
|
|
372
|
+
readonly defaultSeverity: Severity;
|
|
373
|
+
/** Category for grouping */
|
|
374
|
+
readonly category: 'layer-violation' | 'barrel-export' | 'public-api' | 'side-effect' | 'boundary';
|
|
375
|
+
/** Documentation URL */
|
|
376
|
+
readonly docsUrl?: string;
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Configuration options for a rule.
|
|
380
|
+
*/
|
|
381
|
+
interface RuleOptions {
|
|
382
|
+
/** Whether the rule is enabled */
|
|
383
|
+
readonly enabled?: boolean;
|
|
384
|
+
/** Severity override */
|
|
385
|
+
readonly severity?: Severity;
|
|
386
|
+
/** File patterns to include */
|
|
387
|
+
readonly include?: readonly string[];
|
|
388
|
+
/** File patterns to exclude */
|
|
389
|
+
readonly exclude?: readonly string[];
|
|
390
|
+
/** Rule-specific options */
|
|
391
|
+
readonly options?: Readonly<Record<string, unknown>>;
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Core interface that all architectural rules must implement.
|
|
395
|
+
*/
|
|
396
|
+
interface Rule {
|
|
397
|
+
/** Metadata describing the rule */
|
|
398
|
+
readonly metadata: RuleMetadata;
|
|
399
|
+
/**
|
|
400
|
+
* Evaluate the rule against a source file.
|
|
401
|
+
*
|
|
402
|
+
* @param context - Rule evaluation context
|
|
403
|
+
* @returns Result containing violations found
|
|
404
|
+
*/
|
|
405
|
+
readonly evaluate: (context: RuleContext) => Promise<RuleResult>;
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Factory function signature for creating rules.
|
|
409
|
+
*/
|
|
410
|
+
type RuleFactory = (options?: RuleOptions) => Rule;
|
|
411
|
+
/**
|
|
412
|
+
* Registration entry for a rule in the engine.
|
|
413
|
+
*/
|
|
414
|
+
interface RuleRegistration {
|
|
415
|
+
/** The rule instance or factory */
|
|
416
|
+
readonly rule: Rule | RuleFactory;
|
|
417
|
+
/** Whether the rule is enabled */
|
|
418
|
+
readonly enabled: boolean;
|
|
419
|
+
/** Priority for execution order (lower runs first) */
|
|
420
|
+
readonly priority: number;
|
|
421
|
+
/** Configuration options */
|
|
422
|
+
readonly options?: RuleOptions;
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Rule engine for managing and executing architectural rules.
|
|
426
|
+
*/
|
|
427
|
+
interface RuleEngine {
|
|
428
|
+
/** Register a rule */
|
|
429
|
+
readonly register: (id: string, registration: RuleRegistration) => void;
|
|
430
|
+
/** Unregister a rule */
|
|
431
|
+
readonly unregister: (id: string) => boolean;
|
|
432
|
+
/** Get a registered rule */
|
|
433
|
+
readonly get: (id: string) => RuleRegistration | undefined;
|
|
434
|
+
/** Get all registered rules */
|
|
435
|
+
readonly getAll: () => Map<string, RuleRegistration>;
|
|
436
|
+
/** Get enabled rules sorted by priority */
|
|
437
|
+
readonly getEnabled: () => Rule[];
|
|
438
|
+
/** Check if a rule is registered */
|
|
439
|
+
readonly has: (id: string) => boolean;
|
|
440
|
+
/** Evaluate all enabled rules against a source file */
|
|
441
|
+
readonly evaluateFile: (context: RuleContext) => Promise<Result<readonly Issue[], RuleEngineError>>;
|
|
442
|
+
/** Evaluate all enabled rules against multiple source files */
|
|
443
|
+
readonly evaluateFiles: (contexts: readonly RuleContext[]) => Promise<Result<readonly Issue[], RuleEngineError>>;
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Error from rule engine operations.
|
|
447
|
+
*/
|
|
448
|
+
interface RuleEngineError {
|
|
449
|
+
/** Error code for programmatic handling */
|
|
450
|
+
readonly code: 'RULE_EXECUTION_ERROR' | 'RULE_NOT_FOUND' | 'INVALID_CONFIGURATION';
|
|
451
|
+
/** Human-readable error message */
|
|
452
|
+
readonly message: string;
|
|
453
|
+
/** Rule ID that caused the error (if applicable) */
|
|
454
|
+
readonly ruleId?: string;
|
|
455
|
+
/** Additional context about the error */
|
|
456
|
+
readonly context?: Readonly<Record<string, unknown>>;
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Creates a new rule engine instance.
|
|
460
|
+
*
|
|
461
|
+
* @example
|
|
462
|
+
* ```ts
|
|
463
|
+
* const engine = createRuleEngine()
|
|
464
|
+
*
|
|
465
|
+
* engine.register('no-barrel-exports', {
|
|
466
|
+
* rule: createBarrelExportRule(),
|
|
467
|
+
* enabled: true,
|
|
468
|
+
* priority: 10,
|
|
469
|
+
* })
|
|
470
|
+
*
|
|
471
|
+
* const issues = await engine.evaluateFile(context)
|
|
472
|
+
* ```
|
|
473
|
+
*/
|
|
474
|
+
declare function createRuleEngine(): RuleEngine;
|
|
475
|
+
/**
|
|
476
|
+
* Default layer configuration for typical TypeScript projects.
|
|
477
|
+
*/
|
|
478
|
+
declare const DEFAULT_LAYER_CONFIG: LayerConfiguration;
|
|
479
|
+
/**
|
|
480
|
+
* Determines the architectural layer for a file path based on patterns.
|
|
481
|
+
*
|
|
482
|
+
* @param filePath - File path to check
|
|
483
|
+
* @param config - Layer configuration
|
|
484
|
+
* @returns Layer name or undefined if no match
|
|
485
|
+
*/
|
|
486
|
+
declare function getFileLayer(filePath: string, config: LayerConfiguration): string | undefined;
|
|
487
|
+
/**
|
|
488
|
+
* Checks if an import from one layer to another is allowed.
|
|
489
|
+
*
|
|
490
|
+
* @param sourceLayer - Layer of the importing file
|
|
491
|
+
* @param targetLayer - Layer of the imported module
|
|
492
|
+
* @param config - Layer configuration
|
|
493
|
+
* @returns Whether the import is allowed
|
|
494
|
+
*/
|
|
495
|
+
declare function isLayerImportAllowed(sourceLayer: string, targetLayer: string, config: LayerConfiguration): boolean;
|
|
496
|
+
/**
|
|
497
|
+
* Built-in rule IDs.
|
|
498
|
+
*/
|
|
499
|
+
declare const BUILTIN_RULE_IDS: {
|
|
500
|
+
readonly LAYER_VIOLATION: "layer-violation";
|
|
501
|
+
readonly BARREL_EXPORT: "barrel-export";
|
|
502
|
+
readonly PUBLIC_API: "public-api";
|
|
503
|
+
readonly SIDE_EFFECT: "side-effect";
|
|
504
|
+
readonly PATH_ALIAS: "path-alias";
|
|
505
|
+
readonly PACKAGE_BOUNDARY: "package-boundary";
|
|
506
|
+
};
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
* ArchitecturalAnalyzer - Validates architectural patterns and enforces best practices.
|
|
510
|
+
*
|
|
511
|
+
* Integrates multiple architectural rules to detect:
|
|
512
|
+
* - Layer boundary violations
|
|
513
|
+
* - Barrel export (export *) misuse
|
|
514
|
+
* - Public API surface issues
|
|
515
|
+
* - Side effects in module initialization
|
|
516
|
+
* - Import path alias violations
|
|
517
|
+
* - Monorepo package boundary violations
|
|
518
|
+
*/
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* Configuration options for the ArchitecturalAnalyzer.
|
|
522
|
+
*/
|
|
523
|
+
interface ArchitecturalAnalyzerOptions extends AnalyzerOptions {
|
|
524
|
+
/** Layer configuration for architectural boundary enforcement */
|
|
525
|
+
readonly layerConfig?: LayerConfiguration;
|
|
526
|
+
/** tsconfig.json paths for alias validation */
|
|
527
|
+
readonly tsconfigPaths?: Readonly<Record<string, readonly string[]>>;
|
|
528
|
+
/** Enable layer violation detection */
|
|
529
|
+
readonly checkLayerViolations?: boolean;
|
|
530
|
+
/** Enable barrel export detection */
|
|
531
|
+
readonly checkBarrelExports?: boolean;
|
|
532
|
+
/** Enable public API validation */
|
|
533
|
+
readonly checkPublicApi?: boolean;
|
|
534
|
+
/** Enable side effect detection */
|
|
535
|
+
readonly checkSideEffects?: boolean;
|
|
536
|
+
/** Enable path alias validation */
|
|
537
|
+
readonly checkPathAliases?: boolean;
|
|
538
|
+
/** Enable package boundary enforcement */
|
|
539
|
+
readonly checkPackageBoundaries?: boolean;
|
|
540
|
+
/** File patterns for entry points */
|
|
541
|
+
readonly entryPointPatterns?: readonly string[];
|
|
542
|
+
/** Patterns allowed for barrel exports */
|
|
543
|
+
readonly allowedBarrelPatterns?: readonly string[];
|
|
544
|
+
/** Shared packages that can be imported from anywhere */
|
|
545
|
+
readonly sharedPackages?: readonly string[];
|
|
546
|
+
/** Severity for layer violations */
|
|
547
|
+
readonly layerViolationSeverity?: Severity;
|
|
548
|
+
/** Severity for barrel export issues */
|
|
549
|
+
readonly barrelExportSeverity?: Severity;
|
|
550
|
+
/** Severity for public API issues */
|
|
551
|
+
readonly publicApiSeverity?: Severity;
|
|
552
|
+
/** Severity for side effect issues */
|
|
553
|
+
readonly sideEffectSeverity?: Severity;
|
|
554
|
+
}
|
|
555
|
+
declare const architecturalAnalyzerMetadata: AnalyzerMetadata;
|
|
556
|
+
/**
|
|
557
|
+
* Creates an ArchitecturalAnalyzer instance with all built-in rules.
|
|
558
|
+
*
|
|
559
|
+
* @example
|
|
560
|
+
* ```ts
|
|
561
|
+
* const analyzer = createArchitecturalAnalyzer({
|
|
562
|
+
* checkLayerViolations: true,
|
|
563
|
+
* checkBarrelExports: true,
|
|
564
|
+
* layerConfig: {
|
|
565
|
+
* layers: [
|
|
566
|
+
* {name: 'domain', allowedDependencies: []},
|
|
567
|
+
* {name: 'application', allowedDependencies: ['domain']},
|
|
568
|
+
* ],
|
|
569
|
+
* patterns: [
|
|
570
|
+
* {pattern: '**\/domain\/**', layer: 'domain'},
|
|
571
|
+
* {pattern: '**\/application\/**', layer: 'application'},
|
|
572
|
+
* ],
|
|
573
|
+
* },
|
|
574
|
+
* })
|
|
575
|
+
*
|
|
576
|
+
* const result = await analyzer.analyze(context)
|
|
577
|
+
* ```
|
|
578
|
+
*/
|
|
579
|
+
declare function createArchitecturalAnalyzer(options?: ArchitecturalAnalyzerOptions): Analyzer;
|
|
580
|
+
|
|
581
|
+
/**
|
|
582
|
+
* BuildConfigAnalyzer - Validates build configuration (tsup) for consistency and best practices.
|
|
583
|
+
*
|
|
584
|
+
* Detects issues such as:
|
|
585
|
+
* - Missing build configuration for publishable packages
|
|
586
|
+
* - Inconsistent build settings
|
|
587
|
+
* - Missing entry points
|
|
588
|
+
* - Format mismatches with package.json
|
|
589
|
+
*/
|
|
590
|
+
|
|
591
|
+
/**
|
|
592
|
+
* Configuration options specific to BuildConfigAnalyzer.
|
|
593
|
+
*/
|
|
594
|
+
interface BuildConfigAnalyzerOptions {
|
|
595
|
+
/** Whether to require build config for packages with build scripts */
|
|
596
|
+
readonly requireConfig?: boolean;
|
|
597
|
+
/** Expected config file pattern (e.g., 'tsup.config.ts') */
|
|
598
|
+
readonly expectedConfigFile?: string;
|
|
599
|
+
/** Whether to check for DTS generation */
|
|
600
|
+
readonly requireDts?: boolean;
|
|
601
|
+
/** Package names exempt from checks */
|
|
602
|
+
readonly exemptPackages?: readonly string[];
|
|
603
|
+
}
|
|
604
|
+
declare const METADATA$6: AnalyzerMetadata;
|
|
605
|
+
/**
|
|
606
|
+
* Creates a BuildConfigAnalyzer instance.
|
|
607
|
+
*/
|
|
608
|
+
declare function createBuildConfigAnalyzer(options?: BuildConfigAnalyzerOptions): Analyzer;
|
|
609
|
+
|
|
610
|
+
/**
|
|
611
|
+
* Import statement extractor for analyzing module dependencies.
|
|
612
|
+
*
|
|
613
|
+
* Extracts static imports, dynamic imports, and require() calls from TypeScript/JavaScript
|
|
614
|
+
* source files for dependency analysis.
|
|
615
|
+
*
|
|
616
|
+
* Uses ts-morph types (SourceFile, SyntaxKind) which are provided as a peer dependency
|
|
617
|
+
* via @bfra.me/doc-sync's transitive dependency on ts-morph.
|
|
618
|
+
*/
|
|
619
|
+
|
|
620
|
+
/**
|
|
621
|
+
* Type of import statement.
|
|
622
|
+
*/
|
|
623
|
+
type ImportType = 'static' | 'dynamic' | 'require' | 'type-only';
|
|
624
|
+
/**
|
|
625
|
+
* Represents an extracted import statement.
|
|
626
|
+
*/
|
|
627
|
+
interface ExtractedImport {
|
|
628
|
+
/** The module specifier (path or package name) */
|
|
629
|
+
readonly moduleSpecifier: string;
|
|
630
|
+
/** Type of import */
|
|
631
|
+
readonly type: ImportType;
|
|
632
|
+
/** Imported names (for named imports) */
|
|
633
|
+
readonly importedNames?: readonly string[];
|
|
634
|
+
/** Default import name (if present) */
|
|
635
|
+
readonly defaultImport?: string;
|
|
636
|
+
/** Namespace import name (if present) */
|
|
637
|
+
readonly namespaceImport?: string;
|
|
638
|
+
/** Whether this is a side-effect only import */
|
|
639
|
+
readonly isSideEffectOnly: boolean;
|
|
640
|
+
/** Whether the import is from a relative path */
|
|
641
|
+
readonly isRelative: boolean;
|
|
642
|
+
/** Whether the import is from a workspace package */
|
|
643
|
+
readonly isWorkspacePackage: boolean;
|
|
644
|
+
/** Line number in the source file */
|
|
645
|
+
readonly line: number;
|
|
646
|
+
/** Column number in the source file */
|
|
647
|
+
readonly column: number;
|
|
648
|
+
}
|
|
649
|
+
/**
|
|
650
|
+
* Result of extracting imports from a source file.
|
|
651
|
+
*/
|
|
652
|
+
interface ImportExtractionResult {
|
|
653
|
+
/** All extracted imports */
|
|
654
|
+
readonly imports: readonly ExtractedImport[];
|
|
655
|
+
/** The source file path */
|
|
656
|
+
readonly filePath: string;
|
|
657
|
+
/** External package dependencies (non-relative, non-workspace) */
|
|
658
|
+
readonly externalDependencies: readonly string[];
|
|
659
|
+
/** Workspace package dependencies */
|
|
660
|
+
readonly workspaceDependencies: readonly string[];
|
|
661
|
+
/** Relative imports within the package */
|
|
662
|
+
readonly relativeImports: readonly string[];
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* Options for import extraction.
|
|
666
|
+
*/
|
|
667
|
+
interface ImportExtractorOptions {
|
|
668
|
+
/** Workspace package name prefixes (e.g., ['@bfra.me/']) */
|
|
669
|
+
readonly workspacePrefixes?: readonly string[];
|
|
670
|
+
/** Include type-only imports */
|
|
671
|
+
readonly includeTypeImports?: boolean;
|
|
672
|
+
/** Include dynamic imports */
|
|
673
|
+
readonly includeDynamicImports?: boolean;
|
|
674
|
+
/** Include require() calls */
|
|
675
|
+
readonly includeRequireCalls?: boolean;
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* Extracts all imports from a TypeScript/JavaScript source file.
|
|
679
|
+
*
|
|
680
|
+
* @example
|
|
681
|
+
* ```ts
|
|
682
|
+
* const project = createProject()
|
|
683
|
+
* const sourceFile = project.addSourceFileAtPath('./src/index.ts')
|
|
684
|
+
* const result = extractImports(sourceFile)
|
|
685
|
+
*
|
|
686
|
+
* for (const imp of result.imports) {
|
|
687
|
+
* console.log(`Import: ${imp.moduleSpecifier} (${imp.type})`)
|
|
688
|
+
* }
|
|
689
|
+
* ```
|
|
690
|
+
*/
|
|
691
|
+
declare function extractImports(sourceFile: SourceFile, options?: ImportExtractorOptions): ImportExtractionResult;
|
|
692
|
+
/**
|
|
693
|
+
* Checks if a module specifier is a relative import.
|
|
694
|
+
*/
|
|
695
|
+
declare function isRelativeImport(moduleSpecifier: string): boolean;
|
|
696
|
+
/**
|
|
697
|
+
* Checks if a module specifier is a workspace package import.
|
|
698
|
+
*/
|
|
699
|
+
declare function isWorkspacePackageImport(moduleSpecifier: string, workspacePrefixes: readonly string[]): boolean;
|
|
700
|
+
/**
|
|
701
|
+
* Extracts the package name from a module specifier.
|
|
702
|
+
*
|
|
703
|
+
* For scoped packages like '@scope/pkg/path', returns '@scope/pkg'.
|
|
704
|
+
* For unscoped packages like 'lodash/fp', returns 'lodash'.
|
|
705
|
+
*/
|
|
706
|
+
declare function getPackageNameFromSpecifier(moduleSpecifier: string): string;
|
|
707
|
+
/**
|
|
708
|
+
* Resolves a relative import to an absolute file path.
|
|
709
|
+
*/
|
|
710
|
+
declare function resolveRelativeImport(fromFile: string, moduleSpecifier: string): string;
|
|
711
|
+
/**
|
|
712
|
+
* Gets unique package dependencies from imports.
|
|
713
|
+
*/
|
|
714
|
+
declare function getUniqueDependencies(results: readonly ImportExtractionResult[]): {
|
|
715
|
+
readonly external: readonly string[];
|
|
716
|
+
readonly workspace: readonly string[];
|
|
717
|
+
};
|
|
718
|
+
|
|
719
|
+
/**
|
|
720
|
+
* Dependency graph builder for tracking import relationships.
|
|
721
|
+
*
|
|
722
|
+
* Builds an adjacency list representation of module dependencies
|
|
723
|
+
* for cycle detection and dependency analysis using Tarjan's algorithm.
|
|
724
|
+
*
|
|
725
|
+
* This module uses types from import-extractor.ts which depends on ts-morph
|
|
726
|
+
* (provided as a peer dependency via @bfra.me/doc-sync).
|
|
727
|
+
*/
|
|
728
|
+
|
|
729
|
+
/**
|
|
730
|
+
* A node in the dependency graph representing a module.
|
|
731
|
+
*/
|
|
732
|
+
interface DependencyNode {
|
|
733
|
+
/** Unique identifier (typically the file path) */
|
|
734
|
+
readonly id: string;
|
|
735
|
+
/** Display name for the node */
|
|
736
|
+
readonly name: string;
|
|
737
|
+
/** File path of the module */
|
|
738
|
+
readonly filePath: string;
|
|
739
|
+
/** Package name if this is the root of a package */
|
|
740
|
+
readonly packageName?: string;
|
|
741
|
+
/** Outgoing edges (modules this node imports from) */
|
|
742
|
+
readonly imports: readonly string[];
|
|
743
|
+
/** Incoming edges (modules that import this node) */
|
|
744
|
+
readonly importedBy: readonly string[];
|
|
745
|
+
/** All import details for this node */
|
|
746
|
+
readonly importDetails: readonly ExtractedImport[];
|
|
747
|
+
}
|
|
748
|
+
/**
|
|
749
|
+
* An edge in the dependency graph representing an import relationship.
|
|
750
|
+
*/
|
|
751
|
+
interface DependencyEdge {
|
|
752
|
+
/** Source node (the importing module) */
|
|
753
|
+
readonly from: string;
|
|
754
|
+
/** Target node (the imported module) */
|
|
755
|
+
readonly to: string;
|
|
756
|
+
/** Import type */
|
|
757
|
+
readonly type: ExtractedImport['type'];
|
|
758
|
+
/** Whether this is a type-only import */
|
|
759
|
+
readonly isTypeOnly: boolean;
|
|
760
|
+
}
|
|
761
|
+
/**
|
|
762
|
+
* A cycle detected in the dependency graph.
|
|
763
|
+
*/
|
|
764
|
+
interface DependencyCycle {
|
|
765
|
+
/** Nodes in the cycle, in order */
|
|
766
|
+
readonly nodes: readonly string[];
|
|
767
|
+
/** Edges forming the cycle */
|
|
768
|
+
readonly edges: readonly DependencyEdge[];
|
|
769
|
+
/** Human-readable representation of the cycle */
|
|
770
|
+
readonly description: string;
|
|
771
|
+
}
|
|
772
|
+
/**
|
|
773
|
+
* The complete dependency graph.
|
|
774
|
+
*/
|
|
775
|
+
interface DependencyGraph {
|
|
776
|
+
/** All nodes in the graph */
|
|
777
|
+
readonly nodes: ReadonlyMap<string, DependencyNode>;
|
|
778
|
+
/** All edges in the graph */
|
|
779
|
+
readonly edges: readonly DependencyEdge[];
|
|
780
|
+
/** Root workspace path */
|
|
781
|
+
readonly rootPath: string;
|
|
782
|
+
/** Total number of modules */
|
|
783
|
+
readonly moduleCount: number;
|
|
784
|
+
/** Total number of edges (import relationships) */
|
|
785
|
+
readonly edgeCount: number;
|
|
786
|
+
}
|
|
787
|
+
/**
|
|
788
|
+
* Statistics about the dependency graph.
|
|
789
|
+
*/
|
|
790
|
+
interface GraphStatistics {
|
|
791
|
+
/** Total number of nodes */
|
|
792
|
+
readonly nodeCount: number;
|
|
793
|
+
/** Total number of edges */
|
|
794
|
+
readonly edgeCount: number;
|
|
795
|
+
/** Number of external dependencies */
|
|
796
|
+
readonly externalDependencies: number;
|
|
797
|
+
/** Number of workspace dependencies */
|
|
798
|
+
readonly workspaceDependencies: number;
|
|
799
|
+
/** Most imported modules (by incoming edge count) */
|
|
800
|
+
readonly mostImported: readonly {
|
|
801
|
+
readonly id: string;
|
|
802
|
+
readonly count: number;
|
|
803
|
+
}[];
|
|
804
|
+
/** Modules with most imports (by outgoing edge count) */
|
|
805
|
+
readonly mostImporting: readonly {
|
|
806
|
+
readonly id: string;
|
|
807
|
+
readonly count: number;
|
|
808
|
+
}[];
|
|
809
|
+
}
|
|
810
|
+
/**
|
|
811
|
+
* Options for building a dependency graph.
|
|
812
|
+
*/
|
|
813
|
+
interface DependencyGraphOptions {
|
|
814
|
+
/** Root path of the workspace */
|
|
815
|
+
readonly rootPath: string;
|
|
816
|
+
/** Include type-only imports in the graph */
|
|
817
|
+
readonly includeTypeImports?: boolean;
|
|
818
|
+
/** Resolve relative imports to absolute paths */
|
|
819
|
+
readonly resolveRelativeImports?: boolean;
|
|
820
|
+
}
|
|
821
|
+
/**
|
|
822
|
+
* Builds a dependency graph from import extraction results.
|
|
823
|
+
*
|
|
824
|
+
* @example
|
|
825
|
+
* ```ts
|
|
826
|
+
* const results: ImportExtractionResult[] = [...]
|
|
827
|
+
* const graph = buildDependencyGraph(results, {rootPath: '/workspace'})
|
|
828
|
+
*
|
|
829
|
+
* for (const [id, node] of graph.nodes) {
|
|
830
|
+
* console.log(`${node.name} imports ${node.imports.length} modules`)
|
|
831
|
+
* }
|
|
832
|
+
* ```
|
|
833
|
+
*/
|
|
834
|
+
declare function buildDependencyGraph(results: readonly ImportExtractionResult[], options: DependencyGraphOptions): DependencyGraph;
|
|
835
|
+
/**
|
|
836
|
+
* Finds all cycles in a dependency graph using Tarjan's algorithm.
|
|
837
|
+
*
|
|
838
|
+
* @example
|
|
839
|
+
* ```ts
|
|
840
|
+
* const cycles = findCycles(graph)
|
|
841
|
+
* for (const cycle of cycles) {
|
|
842
|
+
* console.log(`Cycle detected: ${cycle.description}`)
|
|
843
|
+
* }
|
|
844
|
+
* ```
|
|
845
|
+
*/
|
|
846
|
+
declare function findCycles(graph: DependencyGraph): readonly DependencyCycle[];
|
|
847
|
+
/**
|
|
848
|
+
* Computes statistics about the dependency graph.
|
|
849
|
+
*/
|
|
850
|
+
declare function computeGraphStatistics(graph: DependencyGraph, topN?: number): GraphStatistics;
|
|
851
|
+
/**
|
|
852
|
+
* Gets all transitive dependencies of a node.
|
|
853
|
+
*/
|
|
854
|
+
declare function getTransitiveDependencies(graph: DependencyGraph, nodeId: string): readonly string[];
|
|
855
|
+
/**
|
|
856
|
+
* Gets all modules that transitively depend on a node.
|
|
857
|
+
*/
|
|
858
|
+
declare function getTransitiveDependents(graph: DependencyGraph, nodeId: string): readonly string[];
|
|
859
|
+
|
|
860
|
+
/**
|
|
861
|
+
* CircularImportAnalyzer - Detects circular import chains in workspace packages.
|
|
862
|
+
*
|
|
863
|
+
* Uses the dependency graph builder and Tarjan's algorithm to identify
|
|
864
|
+
* circular dependencies, providing full path reporting and cycle visualization.
|
|
865
|
+
*
|
|
866
|
+
* Reports:
|
|
867
|
+
* - Direct cycles (A → B → A)
|
|
868
|
+
* - Transitive cycles (A → B → C → A)
|
|
869
|
+
* - Self-imports (A → A)
|
|
870
|
+
* - Cycle severity based on depth and involvement
|
|
871
|
+
*/
|
|
872
|
+
|
|
873
|
+
/**
|
|
874
|
+
* Configuration options specific to CircularImportAnalyzer.
|
|
875
|
+
*/
|
|
876
|
+
interface CircularImportAnalyzerOptions {
|
|
877
|
+
/** Maximum cycle length to report (helps avoid reporting very large cycles) */
|
|
878
|
+
readonly maxCycleLength?: number;
|
|
879
|
+
/** Whether to include type-only imports in cycle detection */
|
|
880
|
+
readonly includeTypeImports?: boolean;
|
|
881
|
+
/** Severity for direct (2-node) cycles */
|
|
882
|
+
readonly directCycleSeverity?: Severity;
|
|
883
|
+
/** Severity for transitive cycles */
|
|
884
|
+
readonly transitiveCycleSeverity?: Severity;
|
|
885
|
+
/** File patterns to exclude from analysis */
|
|
886
|
+
readonly excludePatterns?: readonly string[];
|
|
887
|
+
/** Workspace package prefixes */
|
|
888
|
+
readonly workspacePrefixes?: readonly string[];
|
|
889
|
+
}
|
|
890
|
+
declare const circularImportAnalyzerMetadata: AnalyzerMetadata;
|
|
891
|
+
/**
|
|
892
|
+
* Creates a CircularImportAnalyzer instance.
|
|
893
|
+
*
|
|
894
|
+
* @example
|
|
895
|
+
* ```ts
|
|
896
|
+
* const analyzer = createCircularImportAnalyzer({
|
|
897
|
+
* maxCycleLength: 10,
|
|
898
|
+
* directCycleSeverity: 'error',
|
|
899
|
+
* })
|
|
900
|
+
* const result = await analyzer.analyze(context)
|
|
901
|
+
* ```
|
|
902
|
+
*/
|
|
903
|
+
declare function createCircularImportAnalyzer(options?: CircularImportAnalyzerOptions): Analyzer;
|
|
904
|
+
/**
|
|
905
|
+
* Visualization data for a detected cycle.
|
|
906
|
+
*/
|
|
907
|
+
interface CycleVisualization {
|
|
908
|
+
/** Nodes in the cycle with display names */
|
|
909
|
+
readonly nodes: readonly CycleNode[];
|
|
910
|
+
/** Edges in the cycle */
|
|
911
|
+
readonly edges: readonly CycleEdge[];
|
|
912
|
+
/** ASCII art representation of the cycle */
|
|
913
|
+
readonly ascii: string;
|
|
914
|
+
/** Mermaid diagram code for rendering */
|
|
915
|
+
readonly mermaid: string;
|
|
916
|
+
}
|
|
917
|
+
/**
|
|
918
|
+
* A node in the cycle visualization.
|
|
919
|
+
*/
|
|
920
|
+
interface CycleNode {
|
|
921
|
+
/** Unique identifier */
|
|
922
|
+
readonly id: string;
|
|
923
|
+
/** Display name */
|
|
924
|
+
readonly name: string;
|
|
925
|
+
/** Full file path */
|
|
926
|
+
readonly filePath: string;
|
|
927
|
+
/** Whether this node starts the cycle */
|
|
928
|
+
readonly isStart: boolean;
|
|
929
|
+
}
|
|
930
|
+
/**
|
|
931
|
+
* An edge in the cycle visualization.
|
|
932
|
+
*/
|
|
933
|
+
interface CycleEdge {
|
|
934
|
+
/** Source node ID */
|
|
935
|
+
readonly from: string;
|
|
936
|
+
/** Target node ID */
|
|
937
|
+
readonly to: string;
|
|
938
|
+
/** Import type */
|
|
939
|
+
readonly importType: string;
|
|
940
|
+
}
|
|
941
|
+
/**
|
|
942
|
+
* Generates visualization data for a cycle.
|
|
943
|
+
*/
|
|
944
|
+
declare function generateCycleVisualization(cycle: DependencyCycle, _graph: DependencyGraph, workspacePath: string): CycleVisualization;
|
|
945
|
+
/**
|
|
946
|
+
* Statistics about circular imports in a package.
|
|
947
|
+
*/
|
|
948
|
+
interface CircularImportStats {
|
|
949
|
+
/** Total number of cycles detected */
|
|
950
|
+
readonly totalCycles: number;
|
|
951
|
+
/** Number of direct (2-node) cycles */
|
|
952
|
+
readonly directCycles: number;
|
|
953
|
+
/** Number of transitive cycles */
|
|
954
|
+
readonly transitiveCycles: number;
|
|
955
|
+
/** Files involved in cycles */
|
|
956
|
+
readonly affectedFiles: readonly string[];
|
|
957
|
+
/** Average cycle length */
|
|
958
|
+
readonly averageCycleLength: number;
|
|
959
|
+
/** Maximum cycle length found */
|
|
960
|
+
readonly maxCycleLength: number;
|
|
961
|
+
}
|
|
962
|
+
/**
|
|
963
|
+
* Computes statistics about detected cycles.
|
|
964
|
+
*/
|
|
965
|
+
declare function computeCycleStats(cycles: readonly DependencyCycle[]): CircularImportStats;
|
|
966
|
+
|
|
967
|
+
/**
|
|
968
|
+
* ConfigConsistencyAnalyzer - Cross-validates configuration across multiple config files.
|
|
969
|
+
*
|
|
970
|
+
* Detects issues such as:
|
|
971
|
+
* - Mismatches between package.json exports and tsconfig outDir
|
|
972
|
+
* - TypeScript target/module inconsistencies with package.json type
|
|
973
|
+
* - Build output directory mismatches
|
|
974
|
+
* - Inconsistent configurations across workspace packages
|
|
975
|
+
*/
|
|
976
|
+
|
|
977
|
+
/**
|
|
978
|
+
* Configuration options specific to ConfigConsistencyAnalyzer.
|
|
979
|
+
*/
|
|
980
|
+
interface ConfigConsistencyAnalyzerOptions {
|
|
981
|
+
/** Whether to check tsconfig/package.json consistency */
|
|
982
|
+
readonly checkTsconfigPackageJson?: boolean;
|
|
983
|
+
/** Whether to check cross-package consistency */
|
|
984
|
+
readonly checkCrossPackage?: boolean;
|
|
985
|
+
/** Package names exempt from checks */
|
|
986
|
+
readonly exemptPackages?: readonly string[];
|
|
987
|
+
}
|
|
988
|
+
declare const METADATA$5: AnalyzerMetadata;
|
|
989
|
+
/**
|
|
990
|
+
* Creates a ConfigConsistencyAnalyzer instance.
|
|
991
|
+
*/
|
|
992
|
+
declare function createConfigConsistencyAnalyzer(options?: ConfigConsistencyAnalyzerOptions): Analyzer;
|
|
993
|
+
|
|
994
|
+
/**
|
|
995
|
+
* DeadCodeAnalyzer - Detects unreachable exports and unused code.
|
|
996
|
+
*
|
|
997
|
+
* Identifies code that is exported but never imported or used:
|
|
998
|
+
* - Exported functions never imported anywhere
|
|
999
|
+
* - Exported classes never instantiated or extended
|
|
1000
|
+
* - Exported constants never referenced
|
|
1001
|
+
* - Public API surface that could be reduced
|
|
1002
|
+
*
|
|
1003
|
+
* This helps identify code that can be safely removed to reduce bundle size
|
|
1004
|
+
* and maintenance burden.
|
|
1005
|
+
*/
|
|
1006
|
+
|
|
1007
|
+
/**
|
|
1008
|
+
* Configuration options for DeadCodeAnalyzer.
|
|
1009
|
+
*/
|
|
1010
|
+
interface DeadCodeAnalyzerOptions {
|
|
1011
|
+
/** Check for unused exports */
|
|
1012
|
+
readonly checkUnusedExports?: boolean;
|
|
1013
|
+
/** Check for unreachable code paths */
|
|
1014
|
+
readonly checkUnreachableCode?: boolean;
|
|
1015
|
+
/** Analyze cross-package usage (exports used in other workspace packages) */
|
|
1016
|
+
readonly crossPackageAnalysis?: boolean;
|
|
1017
|
+
/** Consider re-exports as usage */
|
|
1018
|
+
readonly countReexportsAsUsage?: boolean;
|
|
1019
|
+
/** Export patterns to ignore (e.g., 'index.ts' entry points) */
|
|
1020
|
+
readonly ignoreExportPatterns?: readonly string[];
|
|
1021
|
+
/** Severity for unused export warnings */
|
|
1022
|
+
readonly unusedExportSeverity?: Severity;
|
|
1023
|
+
/** Severity for unreachable code warnings */
|
|
1024
|
+
readonly unreachableCodeSeverity?: Severity;
|
|
1025
|
+
/** File patterns to exclude from analysis */
|
|
1026
|
+
readonly excludePatterns?: readonly string[];
|
|
1027
|
+
}
|
|
1028
|
+
declare const deadCodeAnalyzerMetadata: AnalyzerMetadata;
|
|
1029
|
+
/**
|
|
1030
|
+
* Information about an exported symbol.
|
|
1031
|
+
*/
|
|
1032
|
+
interface ExportedSymbol {
|
|
1033
|
+
/** Symbol name */
|
|
1034
|
+
readonly name: string;
|
|
1035
|
+
/** Export type */
|
|
1036
|
+
readonly type: 'function' | 'class' | 'variable' | 'type' | 'interface' | 'enum' | 'namespace';
|
|
1037
|
+
/** File where exported */
|
|
1038
|
+
readonly filePath: string;
|
|
1039
|
+
/** Location of the export */
|
|
1040
|
+
readonly location: IssueLocation;
|
|
1041
|
+
/** Whether this is a re-export */
|
|
1042
|
+
readonly isReexport: boolean;
|
|
1043
|
+
/** Whether this is a default export */
|
|
1044
|
+
readonly isDefault: boolean;
|
|
1045
|
+
/** Package containing this export */
|
|
1046
|
+
readonly packageName: string;
|
|
1047
|
+
}
|
|
1048
|
+
/**
|
|
1049
|
+
* Creates a DeadCodeAnalyzer instance.
|
|
1050
|
+
*/
|
|
1051
|
+
declare function createDeadCodeAnalyzer(options?: DeadCodeAnalyzerOptions): Analyzer;
|
|
1052
|
+
/**
|
|
1053
|
+
* Computes statistics about dead code in a package.
|
|
1054
|
+
*/
|
|
1055
|
+
interface DeadCodeStats {
|
|
1056
|
+
/** Total exports analyzed */
|
|
1057
|
+
readonly totalExports: number;
|
|
1058
|
+
/** Number of unused exports */
|
|
1059
|
+
readonly unusedExports: number;
|
|
1060
|
+
/** Number of used exports */
|
|
1061
|
+
readonly usedExports: number;
|
|
1062
|
+
/** Usage percentage */
|
|
1063
|
+
readonly usagePercentage: number;
|
|
1064
|
+
/** Breakdown by export type */
|
|
1065
|
+
readonly byType: Readonly<Record<string, {
|
|
1066
|
+
total: number;
|
|
1067
|
+
unused: number;
|
|
1068
|
+
}>>;
|
|
1069
|
+
}
|
|
1070
|
+
/**
|
|
1071
|
+
* Computes dead code statistics from analysis results.
|
|
1072
|
+
*/
|
|
1073
|
+
declare function computeDeadCodeStats(exports: readonly ExportedSymbol[], unusedExportNames: readonly string[]): DeadCodeStats;
|
|
1074
|
+
|
|
1075
|
+
/**
|
|
1076
|
+
* DuplicateCodeAnalyzer - Detects duplicate code patterns using AST fingerprinting.
|
|
1077
|
+
*
|
|
1078
|
+
* Identifies code duplication within and across packages in the workspace:
|
|
1079
|
+
* - Exact function duplicates with different names
|
|
1080
|
+
* - Similar code blocks that could be refactored
|
|
1081
|
+
* - Duplicated utility functions across packages
|
|
1082
|
+
*
|
|
1083
|
+
* Uses structural AST fingerprinting rather than text comparison to detect
|
|
1084
|
+
* semantically equivalent code regardless of variable naming or formatting.
|
|
1085
|
+
*/
|
|
1086
|
+
|
|
1087
|
+
/**
|
|
1088
|
+
* Configuration options for DuplicateCodeAnalyzer.
|
|
1089
|
+
*/
|
|
1090
|
+
interface DuplicateCodeAnalyzerOptions {
|
|
1091
|
+
/** Minimum number of statements for a block to be considered for duplication */
|
|
1092
|
+
readonly minStatements?: number;
|
|
1093
|
+
/** Minimum fingerprint similarity threshold (0-1) for reporting */
|
|
1094
|
+
readonly similarityThreshold?: number;
|
|
1095
|
+
/** Check for duplicates across packages (not just within) */
|
|
1096
|
+
readonly crossPackageAnalysis?: boolean;
|
|
1097
|
+
/** Report duplicate functions */
|
|
1098
|
+
readonly reportFunctions?: boolean;
|
|
1099
|
+
/** Report duplicate class methods */
|
|
1100
|
+
readonly reportMethods?: boolean;
|
|
1101
|
+
/** Report similar code blocks */
|
|
1102
|
+
readonly reportCodeBlocks?: boolean;
|
|
1103
|
+
/** Severity for exact duplicates */
|
|
1104
|
+
readonly exactDuplicateSeverity?: Severity;
|
|
1105
|
+
/** Severity for similar code */
|
|
1106
|
+
readonly similarCodeSeverity?: Severity;
|
|
1107
|
+
/** File patterns to exclude from analysis */
|
|
1108
|
+
readonly excludePatterns?: readonly string[];
|
|
1109
|
+
}
|
|
1110
|
+
declare const duplicateCodeAnalyzerMetadata: AnalyzerMetadata;
|
|
1111
|
+
/**
|
|
1112
|
+
* Creates a DuplicateCodeAnalyzer instance.
|
|
1113
|
+
*/
|
|
1114
|
+
declare function createDuplicateCodeAnalyzer(options?: DuplicateCodeAnalyzerOptions): Analyzer;
|
|
1115
|
+
/**
|
|
1116
|
+
* Fingerprint of a code fragment for comparison.
|
|
1117
|
+
*/
|
|
1118
|
+
interface CodeFingerprint {
|
|
1119
|
+
/** Unique hash of the structural fingerprint */
|
|
1120
|
+
readonly hash: string;
|
|
1121
|
+
/** Type of code fragment */
|
|
1122
|
+
readonly type: 'function' | 'method' | 'block';
|
|
1123
|
+
/** Name of the function/method (if applicable) */
|
|
1124
|
+
readonly name?: string;
|
|
1125
|
+
/** Package containing this code */
|
|
1126
|
+
readonly packageName: string;
|
|
1127
|
+
/** File path */
|
|
1128
|
+
readonly filePath: string;
|
|
1129
|
+
/** Location in the file */
|
|
1130
|
+
readonly location: IssueLocation;
|
|
1131
|
+
/** Number of statements in the fragment */
|
|
1132
|
+
readonly statementCount: number;
|
|
1133
|
+
/** Original code (for display) */
|
|
1134
|
+
readonly codePreview: string;
|
|
1135
|
+
/** Structural elements for similarity comparison */
|
|
1136
|
+
readonly structure: readonly string[];
|
|
1137
|
+
}
|
|
1138
|
+
/**
|
|
1139
|
+
* Detected duplicate code pattern.
|
|
1140
|
+
*/
|
|
1141
|
+
interface DuplicatePattern {
|
|
1142
|
+
/** Fingerprint hash */
|
|
1143
|
+
readonly hash: string;
|
|
1144
|
+
/** All occurrences of this duplicate */
|
|
1145
|
+
readonly occurrences: readonly CodeFingerprint[];
|
|
1146
|
+
/** Whether this is an exact match or similar */
|
|
1147
|
+
readonly isExactMatch: boolean;
|
|
1148
|
+
/** Similarity score (1.0 for exact matches) */
|
|
1149
|
+
readonly similarity: number;
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
/**
|
|
1153
|
+
* DuplicateDependencyAnalyzer - Detects duplicate and inconsistent dependencies across workspace packages.
|
|
1154
|
+
*
|
|
1155
|
+
* Identifies:
|
|
1156
|
+
* - Same dependency with different versions across packages
|
|
1157
|
+
* - Dependencies that could be hoisted to workspace root
|
|
1158
|
+
* - Redundant devDependencies that match production dependencies
|
|
1159
|
+
* - Version conflicts that may cause runtime issues
|
|
1160
|
+
*/
|
|
1161
|
+
|
|
1162
|
+
/**
|
|
1163
|
+
* Configuration options specific to DuplicateDependencyAnalyzer.
|
|
1164
|
+
*/
|
|
1165
|
+
interface DuplicateDependencyAnalyzerOptions {
|
|
1166
|
+
/** Ignore version differences for these packages */
|
|
1167
|
+
readonly ignorePackages?: readonly string[];
|
|
1168
|
+
/** Severity for version conflicts */
|
|
1169
|
+
readonly conflictSeverity?: Severity;
|
|
1170
|
+
/** Whether to suggest hoisting common dependencies */
|
|
1171
|
+
readonly suggestHoisting?: boolean;
|
|
1172
|
+
/** Minimum number of packages using a dependency to suggest hoisting */
|
|
1173
|
+
readonly hoistingThreshold?: number;
|
|
1174
|
+
/** Check for redundant dev dependencies */
|
|
1175
|
+
readonly checkRedundantDev?: boolean;
|
|
1176
|
+
}
|
|
1177
|
+
declare const duplicateDependencyAnalyzerMetadata: AnalyzerMetadata;
|
|
1178
|
+
/**
|
|
1179
|
+
* Information about a dependency occurrence.
|
|
1180
|
+
*/
|
|
1181
|
+
interface DependencyOccurrence {
|
|
1182
|
+
readonly packageName: string;
|
|
1183
|
+
readonly version: string;
|
|
1184
|
+
readonly type: 'dependencies' | 'devDependencies' | 'peerDependencies' | 'optionalDependencies';
|
|
1185
|
+
readonly packageJsonPath: string;
|
|
1186
|
+
}
|
|
1187
|
+
/**
|
|
1188
|
+
* Aggregated dependency information across all packages.
|
|
1189
|
+
*/
|
|
1190
|
+
interface DependencyInfo {
|
|
1191
|
+
readonly dependencyName: string;
|
|
1192
|
+
readonly occurrences: readonly DependencyOccurrence[];
|
|
1193
|
+
readonly versions: readonly string[];
|
|
1194
|
+
readonly hasConflict: boolean;
|
|
1195
|
+
}
|
|
1196
|
+
/**
|
|
1197
|
+
* Creates a DuplicateDependencyAnalyzer instance.
|
|
1198
|
+
*
|
|
1199
|
+
* @example
|
|
1200
|
+
* ```ts
|
|
1201
|
+
* const analyzer = createDuplicateDependencyAnalyzer({
|
|
1202
|
+
* conflictSeverity: 'error',
|
|
1203
|
+
* suggestHoisting: true,
|
|
1204
|
+
* })
|
|
1205
|
+
* const result = await analyzer.analyze(context)
|
|
1206
|
+
* ```
|
|
1207
|
+
*/
|
|
1208
|
+
declare function createDuplicateDependencyAnalyzer(options?: DuplicateDependencyAnalyzerOptions): Analyzer;
|
|
1209
|
+
/**
|
|
1210
|
+
* Aggregates duplicate dependency statistics.
|
|
1211
|
+
*/
|
|
1212
|
+
interface DuplicateDependencyStats {
|
|
1213
|
+
/** Total unique dependencies across workspace */
|
|
1214
|
+
readonly totalUniqueDependencies: number;
|
|
1215
|
+
/** Number of dependencies with version conflicts */
|
|
1216
|
+
readonly conflictingDependencies: number;
|
|
1217
|
+
/** Number of packages with redundant dev dependencies */
|
|
1218
|
+
readonly packagesWithRedundantDev: number;
|
|
1219
|
+
/** Dependencies appearing in most packages */
|
|
1220
|
+
readonly mostCommon: readonly {
|
|
1221
|
+
readonly name: string;
|
|
1222
|
+
readonly count: number;
|
|
1223
|
+
}[];
|
|
1224
|
+
/** Dependencies with the most version variants */
|
|
1225
|
+
readonly mostVariants: readonly {
|
|
1226
|
+
readonly name: string;
|
|
1227
|
+
readonly versionCount: number;
|
|
1228
|
+
}[];
|
|
1229
|
+
}
|
|
1230
|
+
/**
|
|
1231
|
+
* Computes statistics about dependency duplicates.
|
|
1232
|
+
*/
|
|
1233
|
+
declare function computeDuplicateStats(dependencyMap: ReadonlyMap<string, DependencyInfo>, topN?: number): DuplicateDependencyStats;
|
|
1234
|
+
|
|
1235
|
+
/**
|
|
1236
|
+
* EslintConfigAnalyzer - Validates ESLint configuration for consistency and best practices.
|
|
1237
|
+
*
|
|
1238
|
+
* Detects issues such as:
|
|
1239
|
+
* - Missing ESLint configuration files
|
|
1240
|
+
* - Inconsistent config patterns across packages
|
|
1241
|
+
* - Missing recommended plugins for TypeScript packages
|
|
1242
|
+
*/
|
|
1243
|
+
|
|
1244
|
+
/**
|
|
1245
|
+
* Configuration options specific to EslintConfigAnalyzer.
|
|
1246
|
+
*/
|
|
1247
|
+
interface EslintConfigAnalyzerOptions {
|
|
1248
|
+
/** Whether to require ESLint config for all packages */
|
|
1249
|
+
readonly requireConfig?: boolean;
|
|
1250
|
+
/** Expected config file pattern (e.g., 'eslint.config.ts') */
|
|
1251
|
+
readonly expectedConfigFile?: string;
|
|
1252
|
+
/** Whether to check for flat config usage */
|
|
1253
|
+
readonly requireFlatConfig?: boolean;
|
|
1254
|
+
/** Package names exempt from checks */
|
|
1255
|
+
readonly exemptPackages?: readonly string[];
|
|
1256
|
+
}
|
|
1257
|
+
declare const METADATA$4: AnalyzerMetadata;
|
|
1258
|
+
/**
|
|
1259
|
+
* Creates an EslintConfigAnalyzer instance.
|
|
1260
|
+
*/
|
|
1261
|
+
declare function createEslintConfigAnalyzer(options?: EslintConfigAnalyzerOptions): Analyzer;
|
|
1262
|
+
|
|
1263
|
+
/**
|
|
1264
|
+
* ExportsFieldAnalyzer - Validates package.json exports against actual source structure.
|
|
1265
|
+
*
|
|
1266
|
+
* Detects issues such as:
|
|
1267
|
+
* - Exports pointing to non-existent files
|
|
1268
|
+
* - Missing exports for existing source files
|
|
1269
|
+
* - Invalid export conditions
|
|
1270
|
+
* - Inconsistent export patterns
|
|
1271
|
+
*/
|
|
1272
|
+
|
|
1273
|
+
/**
|
|
1274
|
+
* Configuration options specific to ExportsFieldAnalyzer.
|
|
1275
|
+
*/
|
|
1276
|
+
interface ExportsFieldAnalyzerOptions {
|
|
1277
|
+
/** Whether to check if export paths resolve to existing files */
|
|
1278
|
+
readonly validatePaths?: boolean;
|
|
1279
|
+
/** Whether to check export condition order */
|
|
1280
|
+
readonly checkConditionOrder?: boolean;
|
|
1281
|
+
/** Whether to suggest missing exports for source files */
|
|
1282
|
+
readonly suggestMissingExports?: boolean;
|
|
1283
|
+
/** Common output directories to check for built files */
|
|
1284
|
+
readonly outputDirs?: readonly string[];
|
|
1285
|
+
/** Package names exempt from checks */
|
|
1286
|
+
readonly exemptPackages?: readonly string[];
|
|
1287
|
+
}
|
|
1288
|
+
declare const METADATA$3: AnalyzerMetadata;
|
|
1289
|
+
/**
|
|
1290
|
+
* Creates an ExportsFieldAnalyzer instance.
|
|
1291
|
+
*/
|
|
1292
|
+
declare function createExportsFieldAnalyzer(options?: ExportsFieldAnalyzerOptions): Analyzer;
|
|
1293
|
+
|
|
1294
|
+
/**
|
|
1295
|
+
* LargeDependencyAnalyzer - Identifies large dependencies that impact bundle size.
|
|
1296
|
+
*
|
|
1297
|
+
* Analyzes package dependencies to identify:
|
|
1298
|
+
* - Known large packages that significantly impact bundle size
|
|
1299
|
+
* - Dependencies with lighter alternatives
|
|
1300
|
+
* - Packages that may be overkill for the actual usage
|
|
1301
|
+
*
|
|
1302
|
+
* Uses a database of known package sizes and suggests optimizations.
|
|
1303
|
+
*/
|
|
1304
|
+
|
|
1305
|
+
/**
|
|
1306
|
+
* Configuration options for LargeDependencyAnalyzer.
|
|
1307
|
+
*/
|
|
1308
|
+
interface LargeDependencyAnalyzerOptions {
|
|
1309
|
+
/** Minimum size threshold in KB (gzipped) to report */
|
|
1310
|
+
readonly sizeThresholdKb?: number;
|
|
1311
|
+
/** Report lighter alternatives when available */
|
|
1312
|
+
readonly suggestAlternatives?: boolean;
|
|
1313
|
+
/** Check for packages with heavy transitive dependencies */
|
|
1314
|
+
readonly checkTransitiveDeps?: boolean;
|
|
1315
|
+
/** Severity for large dependency warnings */
|
|
1316
|
+
readonly largeDependencySeverity?: Severity;
|
|
1317
|
+
/** Severity for alternative suggestions */
|
|
1318
|
+
readonly alternativeSuggestionSeverity?: Severity;
|
|
1319
|
+
/** Packages to ignore */
|
|
1320
|
+
readonly ignorePackages?: readonly string[];
|
|
1321
|
+
}
|
|
1322
|
+
declare const largeDependencyAnalyzerMetadata: AnalyzerMetadata;
|
|
1323
|
+
/**
|
|
1324
|
+
* Known package sizes and metadata.
|
|
1325
|
+
* Sizes are approximate gzipped KB.
|
|
1326
|
+
*/
|
|
1327
|
+
interface PackageInfo {
|
|
1328
|
+
/** Approximate gzipped size in KB */
|
|
1329
|
+
readonly sizeKb: number;
|
|
1330
|
+
/** Category of the package */
|
|
1331
|
+
readonly category: string;
|
|
1332
|
+
/** Lighter alternatives (if any) */
|
|
1333
|
+
readonly alternatives?: readonly AlternativePackage[];
|
|
1334
|
+
/** Whether the package supports tree-shaking */
|
|
1335
|
+
readonly treeShakable: boolean;
|
|
1336
|
+
/** Notes about usage */
|
|
1337
|
+
readonly notes?: string;
|
|
1338
|
+
}
|
|
1339
|
+
interface AlternativePackage {
|
|
1340
|
+
/** Package name */
|
|
1341
|
+
readonly name: string;
|
|
1342
|
+
/** Approximate size in KB */
|
|
1343
|
+
readonly sizeKb: number;
|
|
1344
|
+
/** Notes about the alternative */
|
|
1345
|
+
readonly notes?: string;
|
|
1346
|
+
}
|
|
1347
|
+
/**
|
|
1348
|
+
* Creates a LargeDependencyAnalyzer instance.
|
|
1349
|
+
*/
|
|
1350
|
+
declare function createLargeDependencyAnalyzer(options?: LargeDependencyAnalyzerOptions): Analyzer;
|
|
1351
|
+
/**
|
|
1352
|
+
* Gets known package information for a dependency.
|
|
1353
|
+
*/
|
|
1354
|
+
declare function getPackageInfo(packageName: string): PackageInfo | undefined;
|
|
1355
|
+
/**
|
|
1356
|
+
* Gets all known large packages.
|
|
1357
|
+
*/
|
|
1358
|
+
declare function getKnownLargePackages(): readonly string[];
|
|
1359
|
+
|
|
1360
|
+
/**
|
|
1361
|
+
* PackageJsonAnalyzer - Validates package.json configuration for best practices.
|
|
1362
|
+
*
|
|
1363
|
+
* Detects issues such as:
|
|
1364
|
+
* - Missing required fields (types, exports, etc.)
|
|
1365
|
+
* - Inconsistent entry points
|
|
1366
|
+
* - Invalid dependency versions
|
|
1367
|
+
* - Missing peer dependency declarations
|
|
1368
|
+
*/
|
|
1369
|
+
|
|
1370
|
+
/**
|
|
1371
|
+
* Configuration options specific to PackageJsonAnalyzer.
|
|
1372
|
+
*/
|
|
1373
|
+
interface PackageJsonAnalyzerOptions {
|
|
1374
|
+
/** Whether to require types field for TypeScript packages */
|
|
1375
|
+
readonly requireTypes?: boolean;
|
|
1376
|
+
/** Whether to require exports field for ESM packages */
|
|
1377
|
+
readonly requireExports?: boolean;
|
|
1378
|
+
/** Whether to check for common scripts like build, test, lint */
|
|
1379
|
+
readonly checkScripts?: boolean;
|
|
1380
|
+
/** Package names exempt from certain checks */
|
|
1381
|
+
readonly exemptPackages?: readonly string[];
|
|
1382
|
+
}
|
|
1383
|
+
declare const METADATA$2: AnalyzerMetadata;
|
|
1384
|
+
/**
|
|
1385
|
+
* Creates a PackageJsonAnalyzer instance.
|
|
1386
|
+
*/
|
|
1387
|
+
declare function createPackageJsonAnalyzer(options?: PackageJsonAnalyzerOptions): Analyzer;
|
|
1388
|
+
|
|
1389
|
+
/**
|
|
1390
|
+
* PeerDependencyAnalyzer - Validates peer dependency declarations in workspace packages.
|
|
1391
|
+
*
|
|
1392
|
+
* Ensures workspace packages correctly declare peer dependencies for:
|
|
1393
|
+
* - Packages that should be provided by consumers
|
|
1394
|
+
* - Plugin architectures where host version matters
|
|
1395
|
+
* - Framework dependencies that consumers must provide
|
|
1396
|
+
*
|
|
1397
|
+
* Reports:
|
|
1398
|
+
* - Missing peer dependency declarations
|
|
1399
|
+
* - Peer dependency version mismatches
|
|
1400
|
+
* - Invalid peer dependency ranges
|
|
1401
|
+
* - Workspace packages not declared as peers when they should be
|
|
1402
|
+
*/
|
|
1403
|
+
|
|
1404
|
+
/**
|
|
1405
|
+
* Configuration options specific to PeerDependencyAnalyzer.
|
|
1406
|
+
*/
|
|
1407
|
+
interface PeerDependencyAnalyzerOptions {
|
|
1408
|
+
/** Packages that should always be declared as peer dependencies */
|
|
1409
|
+
readonly requiredPeers?: readonly string[];
|
|
1410
|
+
/** Packages that should never be peer dependencies */
|
|
1411
|
+
readonly disallowedPeers?: readonly string[];
|
|
1412
|
+
/** Whether to check for workspace packages that should be peers */
|
|
1413
|
+
readonly checkWorkspacePeers?: boolean;
|
|
1414
|
+
/** Workspace package prefixes */
|
|
1415
|
+
readonly workspacePrefixes?: readonly string[];
|
|
1416
|
+
/** Check for peer dependencies that are also in dependencies (dual declaration) */
|
|
1417
|
+
readonly checkDualDeclarations?: boolean;
|
|
1418
|
+
}
|
|
1419
|
+
declare const peerDependencyAnalyzerMetadata: AnalyzerMetadata;
|
|
1420
|
+
/**
|
|
1421
|
+
* Creates a PeerDependencyAnalyzer instance.
|
|
1422
|
+
*
|
|
1423
|
+
* @example
|
|
1424
|
+
* ```ts
|
|
1425
|
+
* const analyzer = createPeerDependencyAnalyzer({
|
|
1426
|
+
* requiredPeers: ['react', 'typescript'],
|
|
1427
|
+
* checkDualDeclarations: true,
|
|
1428
|
+
* })
|
|
1429
|
+
* const result = await analyzer.analyze(context)
|
|
1430
|
+
* ```
|
|
1431
|
+
*/
|
|
1432
|
+
declare function createPeerDependencyAnalyzer(options?: PeerDependencyAnalyzerOptions): Analyzer;
|
|
1433
|
+
|
|
1434
|
+
/**
|
|
1435
|
+
* TreeShakingBlockerAnalyzer - Detects patterns that prevent effective tree-shaking.
|
|
1436
|
+
*
|
|
1437
|
+
* Identifies code patterns that block bundler tree-shaking optimizations:
|
|
1438
|
+
* - CommonJS require() calls mixed with ES modules
|
|
1439
|
+
* - Namespace imports (import * as X)
|
|
1440
|
+
* - Side-effect imports without proper module configuration
|
|
1441
|
+
* - Module.exports patterns
|
|
1442
|
+
* - Dynamic requires with non-literal arguments
|
|
1443
|
+
*
|
|
1444
|
+
* Also detects type-only import enforcement opportunities (TASK-051) and
|
|
1445
|
+
* provides dynamic import optimization suggestions (TASK-052).
|
|
1446
|
+
*/
|
|
1447
|
+
|
|
1448
|
+
/**
|
|
1449
|
+
* Configuration options for TreeShakingBlockerAnalyzer.
|
|
1450
|
+
*/
|
|
1451
|
+
interface TreeShakingBlockerAnalyzerOptions {
|
|
1452
|
+
/** Report namespace imports (import * as X) */
|
|
1453
|
+
readonly reportNamespaceImports?: boolean;
|
|
1454
|
+
/** Report CommonJS require() calls */
|
|
1455
|
+
readonly reportRequireCalls?: boolean;
|
|
1456
|
+
/** Report module.exports patterns */
|
|
1457
|
+
readonly reportModuleExports?: boolean;
|
|
1458
|
+
/** Report dynamic require with non-literal arguments */
|
|
1459
|
+
readonly reportDynamicRequire?: boolean;
|
|
1460
|
+
/** Report type-only import opportunities */
|
|
1461
|
+
readonly reportTypeOnlyOpportunities?: boolean;
|
|
1462
|
+
/** Report dynamic import optimization opportunities */
|
|
1463
|
+
readonly reportDynamicImportOpportunities?: boolean;
|
|
1464
|
+
/** Severity for CommonJS interop issues */
|
|
1465
|
+
readonly commonJsInteropSeverity?: Severity;
|
|
1466
|
+
/** Severity for namespace import issues */
|
|
1467
|
+
readonly namespaceImportSeverity?: Severity;
|
|
1468
|
+
/** Severity for type-only import opportunities */
|
|
1469
|
+
readonly typeOnlyImportSeverity?: Severity;
|
|
1470
|
+
/** File patterns to exclude from analysis */
|
|
1471
|
+
readonly excludePatterns?: readonly string[];
|
|
1472
|
+
}
|
|
1473
|
+
declare const treeShakingBlockerAnalyzerMetadata: AnalyzerMetadata;
|
|
1474
|
+
/**
|
|
1475
|
+
* Creates a TreeShakingBlockerAnalyzer instance.
|
|
1476
|
+
*/
|
|
1477
|
+
declare function createTreeShakingBlockerAnalyzer(options?: TreeShakingBlockerAnalyzerOptions): Analyzer;
|
|
1478
|
+
/**
|
|
1479
|
+
* Detected tree-shaking blocker pattern.
|
|
1480
|
+
*/
|
|
1481
|
+
interface TreeShakingBlocker {
|
|
1482
|
+
/** Type of blocker */
|
|
1483
|
+
readonly type: TreeShakingBlockerType;
|
|
1484
|
+
/** Location in source */
|
|
1485
|
+
readonly location: IssueLocation;
|
|
1486
|
+
/** Detailed description */
|
|
1487
|
+
readonly description: string;
|
|
1488
|
+
/** Suggested fix */
|
|
1489
|
+
readonly suggestion: string;
|
|
1490
|
+
/** Additional metadata */
|
|
1491
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
1492
|
+
}
|
|
1493
|
+
type TreeShakingBlockerType = 'namespace-import' | 'require-call' | 'module-exports' | 'dynamic-require' | 'side-effect-import' | 'type-only-opportunity' | 'dynamic-import-opportunity';
|
|
1494
|
+
|
|
1495
|
+
/**
|
|
1496
|
+
* TsconfigAnalyzer - Validates tsconfig.json configuration for consistency and best practices.
|
|
1497
|
+
*
|
|
1498
|
+
* Detects issues such as:
|
|
1499
|
+
* - Missing recommended compiler options
|
|
1500
|
+
* - Inconsistent settings across packages
|
|
1501
|
+
* - Invalid path mappings
|
|
1502
|
+
* - Missing project references
|
|
1503
|
+
*/
|
|
1504
|
+
|
|
1505
|
+
/**
|
|
1506
|
+
* Configuration options specific to TsconfigAnalyzer.
|
|
1507
|
+
*/
|
|
1508
|
+
interface TsconfigAnalyzerOptions {
|
|
1509
|
+
/** Whether to check for strict mode */
|
|
1510
|
+
readonly requireStrict?: boolean;
|
|
1511
|
+
/** Whether to require explicit module settings */
|
|
1512
|
+
readonly requireModuleSettings?: boolean;
|
|
1513
|
+
/** Whether to check path mapping consistency */
|
|
1514
|
+
readonly checkPaths?: boolean;
|
|
1515
|
+
/** Whether to require project references in monorepo */
|
|
1516
|
+
readonly requireReferences?: boolean;
|
|
1517
|
+
/** Package names exempt from certain checks */
|
|
1518
|
+
readonly exemptPackages?: readonly string[];
|
|
1519
|
+
/** Expected base tsconfig to extend from */
|
|
1520
|
+
readonly expectedExtends?: string;
|
|
1521
|
+
}
|
|
1522
|
+
declare const METADATA$1: AnalyzerMetadata;
|
|
1523
|
+
/**
|
|
1524
|
+
* Creates a TsconfigAnalyzer instance.
|
|
1525
|
+
*/
|
|
1526
|
+
declare function createTsconfigAnalyzer(options?: TsconfigAnalyzerOptions): Analyzer;
|
|
1527
|
+
|
|
1528
|
+
/**
|
|
1529
|
+
* UnusedDependencyAnalyzer - Detects unused dependencies in workspace packages.
|
|
1530
|
+
*
|
|
1531
|
+
* Compares declared dependencies in package.json against actual imports
|
|
1532
|
+
* found in source files to identify unused packages that can be removed.
|
|
1533
|
+
*
|
|
1534
|
+
* Handles:
|
|
1535
|
+
* - Static imports (import { x } from 'pkg')
|
|
1536
|
+
* - Dynamic imports (await import('pkg'))
|
|
1537
|
+
* - require() calls (const x = require('pkg'))
|
|
1538
|
+
* - Type-only imports (import type { T } from 'pkg')
|
|
1539
|
+
* - Dev vs production dependency classification
|
|
1540
|
+
*/
|
|
1541
|
+
|
|
1542
|
+
/**
|
|
1543
|
+
* Configuration options specific to UnusedDependencyAnalyzer.
|
|
1544
|
+
*/
|
|
1545
|
+
interface UnusedDependencyAnalyzerOptions {
|
|
1546
|
+
/** Include devDependencies in analysis */
|
|
1547
|
+
readonly checkDevDependencies?: boolean;
|
|
1548
|
+
/** Include peerDependencies in analysis */
|
|
1549
|
+
readonly checkPeerDependencies?: boolean;
|
|
1550
|
+
/** Include optionalDependencies in analysis */
|
|
1551
|
+
readonly checkOptionalDependencies?: boolean;
|
|
1552
|
+
/** Package names to ignore (regex patterns) */
|
|
1553
|
+
readonly ignorePatterns?: readonly string[];
|
|
1554
|
+
/** Packages known to be used implicitly (e.g., type packages, build tools) */
|
|
1555
|
+
readonly implicitlyUsed?: readonly string[];
|
|
1556
|
+
/** Workspace package prefixes for identifying workspace dependencies */
|
|
1557
|
+
readonly workspacePrefixes?: readonly string[];
|
|
1558
|
+
}
|
|
1559
|
+
declare const unusedDependencyAnalyzerMetadata: AnalyzerMetadata;
|
|
1560
|
+
/**
|
|
1561
|
+
* Creates an UnusedDependencyAnalyzer instance.
|
|
1562
|
+
*
|
|
1563
|
+
* @example
|
|
1564
|
+
* ```ts
|
|
1565
|
+
* const analyzer = createUnusedDependencyAnalyzer({
|
|
1566
|
+
* checkDevDependencies: true,
|
|
1567
|
+
* ignorePatterns: ['@types/*'],
|
|
1568
|
+
* })
|
|
1569
|
+
* const result = await analyzer.analyze(context)
|
|
1570
|
+
* ```
|
|
1571
|
+
*/
|
|
1572
|
+
declare function createUnusedDependencyAnalyzer(options?: UnusedDependencyAnalyzerOptions): Analyzer;
|
|
1573
|
+
/**
|
|
1574
|
+
* Aggregates import information from multiple packages for workspace-wide analysis.
|
|
1575
|
+
*/
|
|
1576
|
+
declare function aggregatePackageImports(packages: readonly WorkspacePackage[], importResults: ReadonlyMap<string, readonly ImportExtractionResult[]>): {
|
|
1577
|
+
readonly externalByPackage: ReadonlyMap<string, Set<string>>;
|
|
1578
|
+
readonly workspaceByPackage: ReadonlyMap<string, Set<string>>;
|
|
1579
|
+
};
|
|
1580
|
+
|
|
1581
|
+
/**
|
|
1582
|
+
* VersionAlignmentAnalyzer - Checks for consistent dependency versions across workspace.
|
|
1583
|
+
*
|
|
1584
|
+
* Detects issues such as:
|
|
1585
|
+
* - Different versions of the same dependency across packages
|
|
1586
|
+
* - Workspace packages with mismatched versions
|
|
1587
|
+
* - Invalid workspace: protocol references
|
|
1588
|
+
*/
|
|
1589
|
+
|
|
1590
|
+
/**
|
|
1591
|
+
* Configuration options specific to VersionAlignmentAnalyzer.
|
|
1592
|
+
*/
|
|
1593
|
+
interface VersionAlignmentAnalyzerOptions {
|
|
1594
|
+
/** Whether to check for misaligned external dependency versions */
|
|
1595
|
+
readonly checkExternalVersions?: boolean;
|
|
1596
|
+
/** Whether to check workspace protocol references */
|
|
1597
|
+
readonly checkWorkspaceProtocol?: boolean;
|
|
1598
|
+
/** Dependencies to ignore in version alignment checks */
|
|
1599
|
+
readonly ignoreDependencies?: readonly string[];
|
|
1600
|
+
/** Package names exempt from checks */
|
|
1601
|
+
readonly exemptPackages?: readonly string[];
|
|
1602
|
+
}
|
|
1603
|
+
declare const METADATA: AnalyzerMetadata;
|
|
1604
|
+
/**
|
|
1605
|
+
* Creates a VersionAlignmentAnalyzer instance.
|
|
1606
|
+
*/
|
|
1607
|
+
declare function createVersionAlignmentAnalyzer(options?: VersionAlignmentAnalyzerOptions): Analyzer;
|
|
1608
|
+
|
|
1609
|
+
/**
|
|
1610
|
+
* Analyzer registry and exports for workspace analysis.
|
|
1611
|
+
*
|
|
1612
|
+
* Provides a plugin architecture for registering and managing analyzers,
|
|
1613
|
+
* with built-in analyzers for configuration validation and dependency analysis.
|
|
1614
|
+
*/
|
|
1615
|
+
|
|
1616
|
+
/**
|
|
1617
|
+
* Registry for managing analyzer registrations.
|
|
1618
|
+
*/
|
|
1619
|
+
interface AnalyzerRegistry {
|
|
1620
|
+
/** Register an analyzer */
|
|
1621
|
+
readonly register: (id: string, registration: AnalyzerRegistration) => void;
|
|
1622
|
+
/** Unregister an analyzer */
|
|
1623
|
+
readonly unregister: (id: string) => boolean;
|
|
1624
|
+
/** Get a registered analyzer */
|
|
1625
|
+
readonly get: (id: string) => AnalyzerRegistration | undefined;
|
|
1626
|
+
/** Get all registered analyzers */
|
|
1627
|
+
readonly getAll: () => Map<string, AnalyzerRegistration>;
|
|
1628
|
+
/** Get enabled analyzers sorted by priority */
|
|
1629
|
+
readonly getEnabled: () => Analyzer[];
|
|
1630
|
+
/** Check if an analyzer is registered */
|
|
1631
|
+
readonly has: (id: string) => boolean;
|
|
1632
|
+
}
|
|
1633
|
+
/**
|
|
1634
|
+
* Creates a new analyzer registry.
|
|
1635
|
+
*
|
|
1636
|
+
* @example
|
|
1637
|
+
* ```ts
|
|
1638
|
+
* const registry = createAnalyzerRegistry()
|
|
1639
|
+
*
|
|
1640
|
+
* // Register a custom analyzer
|
|
1641
|
+
* registry.register('my-analyzer', {
|
|
1642
|
+
* analyzer: createMyAnalyzer(),
|
|
1643
|
+
* enabled: true,
|
|
1644
|
+
* priority: 50,
|
|
1645
|
+
* })
|
|
1646
|
+
*
|
|
1647
|
+
* // Get all enabled analyzers
|
|
1648
|
+
* const analyzers = registry.getEnabled()
|
|
1649
|
+
* ```
|
|
1650
|
+
*/
|
|
1651
|
+
declare function createAnalyzerRegistry(): AnalyzerRegistry;
|
|
1652
|
+
/**
|
|
1653
|
+
* Built-in analyzer IDs.
|
|
1654
|
+
*/
|
|
1655
|
+
declare const BUILTIN_ANALYZER_IDS: {
|
|
1656
|
+
readonly PACKAGE_JSON: "package-json";
|
|
1657
|
+
readonly TSCONFIG: "tsconfig";
|
|
1658
|
+
readonly ESLINT_CONFIG: "eslint-config";
|
|
1659
|
+
readonly BUILD_CONFIG: "build-config";
|
|
1660
|
+
readonly CONFIG_CONSISTENCY: "config-consistency";
|
|
1661
|
+
readonly VERSION_ALIGNMENT: "version-alignment";
|
|
1662
|
+
readonly EXPORTS_FIELD: "exports-field";
|
|
1663
|
+
readonly UNUSED_DEPENDENCY: "unused-dependency";
|
|
1664
|
+
readonly CIRCULAR_IMPORT: "circular-import";
|
|
1665
|
+
readonly PEER_DEPENDENCY: "peer-dependency";
|
|
1666
|
+
readonly DUPLICATE_DEPENDENCY: "duplicate-dependency";
|
|
1667
|
+
readonly ARCHITECTURAL: "architectural";
|
|
1668
|
+
readonly DEAD_CODE: "dead-code";
|
|
1669
|
+
readonly DUPLICATE_CODE: "duplicate-code";
|
|
1670
|
+
readonly LARGE_DEPENDENCY: "large-dependency";
|
|
1671
|
+
readonly TREE_SHAKING_BLOCKER: "tree-shaking-blocker";
|
|
1672
|
+
};
|
|
1673
|
+
/**
|
|
1674
|
+
* Creates a registry with all built-in analyzers registered.
|
|
1675
|
+
*
|
|
1676
|
+
* @example
|
|
1677
|
+
* ```ts
|
|
1678
|
+
* const registry = createDefaultRegistry()
|
|
1679
|
+
*
|
|
1680
|
+
* // Disable a specific analyzer
|
|
1681
|
+
* const registration = registry.get('eslint-config')
|
|
1682
|
+
* if (registration) {
|
|
1683
|
+
* registry.register('eslint-config', {...registration, enabled: false})
|
|
1684
|
+
* }
|
|
1685
|
+
*
|
|
1686
|
+
* // Run enabled analyzers
|
|
1687
|
+
* const analyzers = registry.getEnabled()
|
|
1688
|
+
* ```
|
|
1689
|
+
*/
|
|
1690
|
+
declare function createDefaultRegistry(): AnalyzerRegistry;
|
|
1691
|
+
/**
|
|
1692
|
+
* All built-in analyzer factories for direct use.
|
|
1693
|
+
*/
|
|
1694
|
+
declare const builtinAnalyzers: {
|
|
1695
|
+
readonly packageJson: typeof createPackageJsonAnalyzer;
|
|
1696
|
+
readonly tsconfig: typeof createTsconfigAnalyzer;
|
|
1697
|
+
readonly eslintConfig: typeof createEslintConfigAnalyzer;
|
|
1698
|
+
readonly buildConfig: typeof createBuildConfigAnalyzer;
|
|
1699
|
+
readonly configConsistency: typeof createConfigConsistencyAnalyzer;
|
|
1700
|
+
readonly versionAlignment: typeof createVersionAlignmentAnalyzer;
|
|
1701
|
+
readonly exportsField: typeof createExportsFieldAnalyzer;
|
|
1702
|
+
readonly unusedDependency: typeof createUnusedDependencyAnalyzer;
|
|
1703
|
+
readonly circularImport: typeof createCircularImportAnalyzer;
|
|
1704
|
+
readonly peerDependency: typeof createPeerDependencyAnalyzer;
|
|
1705
|
+
readonly duplicateDependency: typeof createDuplicateDependencyAnalyzer;
|
|
1706
|
+
readonly architectural: typeof createArchitecturalAnalyzer;
|
|
1707
|
+
readonly deadCode: typeof createDeadCodeAnalyzer;
|
|
1708
|
+
readonly duplicateCode: typeof createDuplicateCodeAnalyzer;
|
|
1709
|
+
readonly largeDependency: typeof createLargeDependencyAnalyzer;
|
|
1710
|
+
readonly treeShakingBlocker: typeof createTreeShakingBlockerAnalyzer;
|
|
1711
|
+
};
|
|
1712
|
+
|
|
1713
|
+
/**
|
|
1714
|
+
* Main public API for workspace analysis.
|
|
1715
|
+
*
|
|
1716
|
+
* Provides the `analyzeWorkspace()` function as the primary entry point
|
|
1717
|
+
* for programmatic workspace analysis.
|
|
1718
|
+
*/
|
|
1719
|
+
|
|
1720
|
+
/**
|
|
1721
|
+
* Options for the analyzeWorkspace function.
|
|
1722
|
+
*/
|
|
1723
|
+
interface AnalyzeWorkspaceOptions {
|
|
1724
|
+
/** Glob patterns for files to include */
|
|
1725
|
+
readonly include?: readonly string[];
|
|
1726
|
+
/** Glob patterns for files to exclude */
|
|
1727
|
+
readonly exclude?: readonly string[];
|
|
1728
|
+
/** Minimum severity level to report */
|
|
1729
|
+
readonly minSeverity?: 'info' | 'warning' | 'error' | 'critical';
|
|
1730
|
+
/** Categories of issues to check (empty means all) */
|
|
1731
|
+
readonly categories?: readonly ('configuration' | 'dependency' | 'architecture' | 'performance' | 'circular-import' | 'unused-export' | 'type-safety')[];
|
|
1732
|
+
/** Enable incremental analysis caching */
|
|
1733
|
+
readonly cache?: boolean;
|
|
1734
|
+
/** Custom rules configuration */
|
|
1735
|
+
readonly rules?: Record<string, unknown>;
|
|
1736
|
+
/** Glob patterns for package locations */
|
|
1737
|
+
readonly packagePatterns?: readonly string[];
|
|
1738
|
+
/** Maximum parallel analysis operations */
|
|
1739
|
+
readonly concurrency?: number;
|
|
1740
|
+
/** Directory for analysis cache files */
|
|
1741
|
+
readonly cacheDir?: string;
|
|
1742
|
+
/** Maximum cache age in milliseconds */
|
|
1743
|
+
readonly maxCacheAge?: number;
|
|
1744
|
+
/** Hash algorithm for file content */
|
|
1745
|
+
readonly hashAlgorithm?: 'sha256' | 'md5';
|
|
1746
|
+
/** Path to workspace-analyzer.config.ts file */
|
|
1747
|
+
readonly configPath?: string;
|
|
1748
|
+
/** Callback for progress reporting */
|
|
1749
|
+
readonly onProgress?: (progress: AnalysisProgress) => void;
|
|
1750
|
+
/** Per-analyzer configuration */
|
|
1751
|
+
readonly analyzers?: Record<string, {
|
|
1752
|
+
enabled?: boolean;
|
|
1753
|
+
severity?: 'info' | 'warning' | 'error' | 'critical';
|
|
1754
|
+
options?: Record<string, unknown>;
|
|
1755
|
+
}>;
|
|
1756
|
+
/** Architectural analysis rules */
|
|
1757
|
+
readonly architecture?: {
|
|
1758
|
+
layers?: {
|
|
1759
|
+
name: string;
|
|
1760
|
+
patterns: string[];
|
|
1761
|
+
allowedImports: string[];
|
|
1762
|
+
}[];
|
|
1763
|
+
allowBarrelExports?: boolean | string[];
|
|
1764
|
+
enforcePublicApi?: boolean;
|
|
1765
|
+
};
|
|
1766
|
+
/** Enable verbose logging */
|
|
1767
|
+
readonly verbose?: boolean;
|
|
1768
|
+
}
|
|
1769
|
+
/**
|
|
1770
|
+
* Error codes for workspace analysis.
|
|
1771
|
+
*/
|
|
1772
|
+
type AnalyzeWorkspaceErrorCode = 'CONFIG_ERROR' | 'SCAN_ERROR' | 'ANALYSIS_ERROR' | 'INVALID_PATH';
|
|
1773
|
+
/**
|
|
1774
|
+
* Error that occurred during workspace analysis.
|
|
1775
|
+
*/
|
|
1776
|
+
interface AnalyzeWorkspaceError {
|
|
1777
|
+
readonly code: AnalyzeWorkspaceErrorCode;
|
|
1778
|
+
readonly message: string;
|
|
1779
|
+
readonly cause?: unknown;
|
|
1780
|
+
}
|
|
1781
|
+
/**
|
|
1782
|
+
* Analyzes a workspace for configuration, dependency, and architectural issues.
|
|
1783
|
+
*
|
|
1784
|
+
* This is the main entry point for programmatic workspace analysis.
|
|
1785
|
+
*
|
|
1786
|
+
* @param workspacePath - Path to the workspace root directory
|
|
1787
|
+
* @param options - Analysis options
|
|
1788
|
+
* @returns Result containing analysis results or an error
|
|
1789
|
+
*
|
|
1790
|
+
* @example
|
|
1791
|
+
* ```ts
|
|
1792
|
+
* import {analyzeWorkspace} from '@bfra.me/workspace-analyzer'
|
|
1793
|
+
*
|
|
1794
|
+
* const result = await analyzeWorkspace('./my-monorepo', {
|
|
1795
|
+
* minSeverity: 'warning',
|
|
1796
|
+
* categories: ['dependency', 'architecture'],
|
|
1797
|
+
* onProgress: (progress) => {
|
|
1798
|
+
* console.log(`${progress.phase}: ${progress.processed}/${progress.total}`)
|
|
1799
|
+
* },
|
|
1800
|
+
* })
|
|
1801
|
+
*
|
|
1802
|
+
* if (result.success) {
|
|
1803
|
+
* console.log(`Found ${result.data.summary.totalIssues} issues`)
|
|
1804
|
+
* for (const issue of result.data.issues) {
|
|
1805
|
+
* console.log(`[${issue.severity}] ${issue.title}`)
|
|
1806
|
+
* }
|
|
1807
|
+
* } else {
|
|
1808
|
+
* console.error(`Analysis failed: ${result.error.message}`)
|
|
1809
|
+
* }
|
|
1810
|
+
* ```
|
|
1811
|
+
*/
|
|
1812
|
+
declare function analyzeWorkspace(workspacePath: string, options?: AnalyzeWorkspaceOptions): Promise<Result<AnalysisResult, AnalyzeWorkspaceError>>;
|
|
1813
|
+
/**
|
|
1814
|
+
* Analyzes specific packages within a workspace.
|
|
1815
|
+
*
|
|
1816
|
+
* @param workspacePath - Path to the workspace root directory
|
|
1817
|
+
* @param packageNames - Names of packages to analyze
|
|
1818
|
+
* @param options - Analysis options
|
|
1819
|
+
* @returns Result containing analysis results or an error
|
|
1820
|
+
*
|
|
1821
|
+
* @example
|
|
1822
|
+
* ```ts
|
|
1823
|
+
* import {analyzePackages} from '@bfra.me/workspace-analyzer'
|
|
1824
|
+
*
|
|
1825
|
+
* const result = await analyzePackages('./my-monorepo', ['@myorg/core', '@myorg/utils'])
|
|
1826
|
+
*
|
|
1827
|
+
* if (result.success) {
|
|
1828
|
+
* console.log(`Analyzed ${result.data.summary.packagesAnalyzed} packages`)
|
|
1829
|
+
* }
|
|
1830
|
+
* ```
|
|
1831
|
+
*/
|
|
1832
|
+
declare function analyzePackages(workspacePath: string, packageNames: readonly string[], options?: AnalyzeWorkspaceOptions): Promise<Result<AnalysisResult, AnalyzeWorkspaceError>>;
|
|
1833
|
+
|
|
1834
|
+
/**
|
|
1835
|
+
* Cache schema types for workspace analyzer incremental analysis.
|
|
1836
|
+
*
|
|
1837
|
+
* These types define the structure for storing and retrieving analysis results
|
|
1838
|
+
* to enable efficient incremental analysis on large codebases.
|
|
1839
|
+
*/
|
|
1840
|
+
|
|
1841
|
+
/**
|
|
1842
|
+
* Schema version for cache format migration.
|
|
1843
|
+
* Increment when making breaking changes to cache structure.
|
|
1844
|
+
*/
|
|
1845
|
+
declare const CACHE_SCHEMA_VERSION = 1;
|
|
1846
|
+
/**
|
|
1847
|
+
* Metadata about a cached file's state at analysis time.
|
|
1848
|
+
*/
|
|
1849
|
+
interface CachedFileState {
|
|
1850
|
+
/** Absolute file path */
|
|
1851
|
+
readonly path: string;
|
|
1852
|
+
/** Content hash (SHA-256) at time of analysis */
|
|
1853
|
+
readonly contentHash: string;
|
|
1854
|
+
/** File modification timestamp (ISO 8601) */
|
|
1855
|
+
readonly modifiedAt: string;
|
|
1856
|
+
/** File size in bytes */
|
|
1857
|
+
readonly size: number;
|
|
1858
|
+
}
|
|
1859
|
+
/**
|
|
1860
|
+
* Metadata about a cached analysis run.
|
|
1861
|
+
*/
|
|
1862
|
+
interface CacheMetadata {
|
|
1863
|
+
/** Cache schema version for migration support */
|
|
1864
|
+
readonly version: number;
|
|
1865
|
+
/** Workspace root path that was analyzed */
|
|
1866
|
+
readonly workspacePath: string;
|
|
1867
|
+
/** Timestamp when the cache was created (ISO 8601) */
|
|
1868
|
+
readonly createdAt: string;
|
|
1869
|
+
/** Timestamp when the cache was last updated (ISO 8601) */
|
|
1870
|
+
readonly updatedAt: string;
|
|
1871
|
+
/** Hash of the analyzer configuration */
|
|
1872
|
+
readonly configHash: string;
|
|
1873
|
+
/** Workspace analyzer package version */
|
|
1874
|
+
readonly analyzerVersion: string;
|
|
1875
|
+
}
|
|
1876
|
+
/**
|
|
1877
|
+
* A cached analysis result for a single file.
|
|
1878
|
+
*/
|
|
1879
|
+
interface CachedFileAnalysis {
|
|
1880
|
+
/** File state at time of analysis */
|
|
1881
|
+
readonly fileState: CachedFileState;
|
|
1882
|
+
/** Issues found in this file */
|
|
1883
|
+
readonly issues: readonly Issue[];
|
|
1884
|
+
/** Analyzer IDs that processed this file */
|
|
1885
|
+
readonly analyzersRun: readonly string[];
|
|
1886
|
+
/** Analysis timestamp (ISO 8601) */
|
|
1887
|
+
readonly analyzedAt: string;
|
|
1888
|
+
}
|
|
1889
|
+
/**
|
|
1890
|
+
* A cached package-level analysis result.
|
|
1891
|
+
*/
|
|
1892
|
+
interface CachedPackageAnalysis {
|
|
1893
|
+
/** Package name */
|
|
1894
|
+
readonly packageName: string;
|
|
1895
|
+
/** Package path relative to workspace root */
|
|
1896
|
+
readonly packagePath: string;
|
|
1897
|
+
/** Hash of package.json content */
|
|
1898
|
+
readonly packageJsonHash: string;
|
|
1899
|
+
/** Issues found at the package level */
|
|
1900
|
+
readonly issues: readonly Issue[];
|
|
1901
|
+
/** Analyzer IDs that processed this package */
|
|
1902
|
+
readonly analyzersRun: readonly string[];
|
|
1903
|
+
/** Analysis timestamp (ISO 8601) */
|
|
1904
|
+
readonly analyzedAt: string;
|
|
1905
|
+
}
|
|
1906
|
+
/**
|
|
1907
|
+
* Complete analysis cache for a workspace.
|
|
1908
|
+
*/
|
|
1909
|
+
interface AnalysisCache {
|
|
1910
|
+
/** Cache metadata */
|
|
1911
|
+
readonly metadata: CacheMetadata;
|
|
1912
|
+
/** Per-file analysis results indexed by file path */
|
|
1913
|
+
readonly files: Readonly<Record<string, CachedFileAnalysis>>;
|
|
1914
|
+
/** Per-package analysis results indexed by package name */
|
|
1915
|
+
readonly packages: Readonly<Record<string, CachedPackageAnalysis>>;
|
|
1916
|
+
/** Workspace-level issues not tied to specific files */
|
|
1917
|
+
readonly workspaceIssues: readonly Issue[];
|
|
1918
|
+
/** Configuration files state for invalidation detection */
|
|
1919
|
+
readonly configFiles: readonly CachedFileState[];
|
|
1920
|
+
}
|
|
1921
|
+
/**
|
|
1922
|
+
* Result of cache validation check.
|
|
1923
|
+
*/
|
|
1924
|
+
interface CacheValidationResult {
|
|
1925
|
+
/** Whether the cache is valid and can be used */
|
|
1926
|
+
readonly isValid: boolean;
|
|
1927
|
+
/** Files that have changed since last analysis */
|
|
1928
|
+
readonly changedFiles: readonly string[];
|
|
1929
|
+
/** Files that are new since last analysis */
|
|
1930
|
+
readonly newFiles: readonly string[];
|
|
1931
|
+
/** Files that were deleted since last analysis */
|
|
1932
|
+
readonly deletedFiles: readonly string[];
|
|
1933
|
+
/** Packages that need re-analysis */
|
|
1934
|
+
readonly invalidatedPackages: readonly string[];
|
|
1935
|
+
/** Configuration files that changed (triggers full invalidation) */
|
|
1936
|
+
readonly changedConfigFiles: readonly string[];
|
|
1937
|
+
/** Reason for invalidation if not valid */
|
|
1938
|
+
readonly invalidationReason?: string;
|
|
1939
|
+
}
|
|
1940
|
+
/**
|
|
1941
|
+
* Options for cache operations.
|
|
1942
|
+
*/
|
|
1943
|
+
interface CacheOptions {
|
|
1944
|
+
/** Directory path for cache storage (default: .workspace-analyzer-cache) */
|
|
1945
|
+
readonly cacheDir?: string;
|
|
1946
|
+
/** Maximum cache age in milliseconds (default: 7 days) */
|
|
1947
|
+
readonly maxAge?: number;
|
|
1948
|
+
/** Whether to compress cache files (default: true) */
|
|
1949
|
+
readonly compress?: boolean;
|
|
1950
|
+
/** Hash algorithm for file content (default: sha256) */
|
|
1951
|
+
readonly hashAlgorithm?: 'sha256' | 'md5';
|
|
1952
|
+
}
|
|
1953
|
+
/**
|
|
1954
|
+
* Statistics about cache usage.
|
|
1955
|
+
*/
|
|
1956
|
+
interface CacheStatistics {
|
|
1957
|
+
/** Number of cached files */
|
|
1958
|
+
readonly cachedFiles: number;
|
|
1959
|
+
/** Number of cached packages */
|
|
1960
|
+
readonly cachedPackages: number;
|
|
1961
|
+
/** Total cache size in bytes */
|
|
1962
|
+
readonly totalSizeBytes: number;
|
|
1963
|
+
/** Cache age in milliseconds */
|
|
1964
|
+
readonly ageMs: number;
|
|
1965
|
+
/** Number of cache hits during last analysis */
|
|
1966
|
+
readonly hitCount: number;
|
|
1967
|
+
/** Number of cache misses during last analysis */
|
|
1968
|
+
readonly missCount: number;
|
|
1969
|
+
/** Cache hit rate (0-1) */
|
|
1970
|
+
readonly hitRate: number;
|
|
1971
|
+
}
|
|
1972
|
+
/**
|
|
1973
|
+
* Configuration file patterns for cache invalidation.
|
|
1974
|
+
* Changes to these files trigger re-analysis of affected areas.
|
|
1975
|
+
*/
|
|
1976
|
+
declare const CONFIG_FILE_PATTERNS: readonly string[];
|
|
1977
|
+
/**
|
|
1978
|
+
* Default cache options.
|
|
1979
|
+
*/
|
|
1980
|
+
declare const DEFAULT_CACHE_OPTIONS: Required<CacheOptions>;
|
|
1981
|
+
/**
|
|
1982
|
+
* Creates an empty analysis cache with default metadata.
|
|
1983
|
+
*/
|
|
1984
|
+
declare function createEmptyCache(workspacePath: string, configHash: string, analyzerVersion: string): AnalysisCache;
|
|
1985
|
+
/**
|
|
1986
|
+
* Creates a cache entry for a file analysis result.
|
|
1987
|
+
*/
|
|
1988
|
+
declare function createFileAnalysisEntry(path: string, contentHash: string, modifiedAt: Date, size: number, issues: readonly Issue[], analyzersRun: readonly string[]): CachedFileAnalysis;
|
|
1989
|
+
/**
|
|
1990
|
+
* Creates a cache entry for a package analysis result.
|
|
1991
|
+
*/
|
|
1992
|
+
declare function createPackageAnalysisEntry(packageName: string, packagePath: string, packageJsonHash: string, issues: readonly Issue[], analyzersRun: readonly string[]): CachedPackageAnalysis;
|
|
1993
|
+
|
|
1994
|
+
/**
|
|
1995
|
+
* Cache manager for workspace analysis results.
|
|
1996
|
+
*
|
|
1997
|
+
* Provides file-based storage for analysis caches with incremental updates,
|
|
1998
|
+
* compression support, and automatic invalidation.
|
|
1999
|
+
*/
|
|
2000
|
+
|
|
2001
|
+
/**
|
|
2002
|
+
* Error codes for cache operations.
|
|
2003
|
+
*/
|
|
2004
|
+
type CacheErrorCode = 'CACHE_NOT_FOUND' | 'CACHE_CORRUPTED' | 'CACHE_EXPIRED' | 'CACHE_VERSION_MISMATCH' | 'CACHE_WRITE_FAILED' | 'CACHE_READ_FAILED' | 'CACHE_INVALID';
|
|
2005
|
+
/**
|
|
2006
|
+
* Error for cache operations.
|
|
2007
|
+
*/
|
|
2008
|
+
interface CacheError {
|
|
2009
|
+
readonly code: CacheErrorCode;
|
|
2010
|
+
readonly message: string;
|
|
2011
|
+
readonly cause?: Error;
|
|
2012
|
+
}
|
|
2013
|
+
/**
|
|
2014
|
+
* Cache manager for workspace analysis.
|
|
2015
|
+
*/
|
|
2016
|
+
interface CacheManager {
|
|
2017
|
+
/** Load cache from disk */
|
|
2018
|
+
readonly load: () => Promise<Result<AnalysisCache, CacheError>>;
|
|
2019
|
+
/** Save cache to disk */
|
|
2020
|
+
readonly save: (cache: AnalysisCache) => Promise<Result<void, CacheError>>;
|
|
2021
|
+
/** Validate cache against current workspace state */
|
|
2022
|
+
readonly validate: (cache: AnalysisCache, currentFiles: readonly string[]) => Promise<CacheValidationResult>;
|
|
2023
|
+
/** Update cache with new file analysis */
|
|
2024
|
+
readonly updateFile: (cache: AnalysisCache, path: string, issues: readonly Issue[], analyzersRun: readonly string[]) => Promise<Result<AnalysisCache, CacheError>>;
|
|
2025
|
+
/** Update cache with new package analysis */
|
|
2026
|
+
readonly updatePackage: (cache: AnalysisCache, packageName: string, packagePath: string, issues: readonly Issue[], analyzersRun: readonly string[]) => Promise<Result<AnalysisCache, CacheError>>;
|
|
2027
|
+
/** Clear all cache files */
|
|
2028
|
+
readonly clear: () => Promise<Result<void, CacheError>>;
|
|
2029
|
+
/** Get cache statistics */
|
|
2030
|
+
readonly getStatistics: (cache: AnalysisCache) => CacheStatistics;
|
|
2031
|
+
/** Check if cache is valid without full validation */
|
|
2032
|
+
readonly quickValidate: (cache: AnalysisCache, configHash: string) => boolean;
|
|
2033
|
+
}
|
|
2034
|
+
/**
|
|
2035
|
+
* Options for creating a cache manager.
|
|
2036
|
+
*/
|
|
2037
|
+
interface CacheManagerOptions extends CacheOptions {
|
|
2038
|
+
/** Workspace root path */
|
|
2039
|
+
readonly workspacePath: string;
|
|
2040
|
+
/** Current analyzer version */
|
|
2041
|
+
readonly analyzerVersion: string;
|
|
2042
|
+
}
|
|
2043
|
+
/**
|
|
2044
|
+
* Creates a cache manager for workspace analysis.
|
|
2045
|
+
*
|
|
2046
|
+
* @param options - Cache manager configuration
|
|
2047
|
+
* @returns A CacheManager instance
|
|
2048
|
+
*
|
|
2049
|
+
* @example
|
|
2050
|
+
* ```ts
|
|
2051
|
+
* const manager = createCacheManager({
|
|
2052
|
+
* workspacePath: '/path/to/workspace',
|
|
2053
|
+
* analyzerVersion: '1.0.0',
|
|
2054
|
+
* })
|
|
2055
|
+
*
|
|
2056
|
+
* const result = await manager.load()
|
|
2057
|
+
* if (isOk(result)) {
|
|
2058
|
+
* const validation = await manager.validate(result.data, currentFiles)
|
|
2059
|
+
* if (!validation.isValid) {
|
|
2060
|
+
* // Re-analyze changed files
|
|
2061
|
+
* }
|
|
2062
|
+
* }
|
|
2063
|
+
* ```
|
|
2064
|
+
*/
|
|
2065
|
+
declare function createCacheManager(options: CacheManagerOptions): CacheManager;
|
|
2066
|
+
/**
|
|
2067
|
+
* Creates an empty cache for a workspace.
|
|
2068
|
+
*
|
|
2069
|
+
* @param workspacePath - Workspace root path
|
|
2070
|
+
* @param configHash - Hash of the current configuration
|
|
2071
|
+
* @param analyzerVersion - Current analyzer version
|
|
2072
|
+
* @returns A new empty AnalysisCache
|
|
2073
|
+
*/
|
|
2074
|
+
declare function initializeCache(workspacePath: string, configHash: string, analyzerVersion: string): AnalysisCache;
|
|
2075
|
+
/**
|
|
2076
|
+
* Collects configuration file states for cache invalidation tracking.
|
|
2077
|
+
*
|
|
2078
|
+
* @param workspacePath - Workspace root path
|
|
2079
|
+
* @param packagePaths - Package directory paths (relative to workspace)
|
|
2080
|
+
* @returns Array of configuration file states
|
|
2081
|
+
*/
|
|
2082
|
+
declare function collectConfigFileStates(workspacePath: string, packagePaths: readonly string[]): Promise<CachedFileState[]>;
|
|
2083
|
+
|
|
2084
|
+
/**
|
|
2085
|
+
* Change detector for incremental analysis.
|
|
2086
|
+
*
|
|
2087
|
+
* Re-exports from @bfra.me/es/watcher with workspace-analyzer-specific utilities.
|
|
2088
|
+
*/
|
|
2089
|
+
|
|
2090
|
+
/**
|
|
2091
|
+
* Options for creating an analysis change detector.
|
|
2092
|
+
*/
|
|
2093
|
+
interface AnalysisChangeDetectorOptions extends ChangeDetectorOptions {
|
|
2094
|
+
/** Configuration file patterns to monitor for invalidation */
|
|
2095
|
+
readonly configFilePatterns?: readonly string[];
|
|
2096
|
+
}
|
|
2097
|
+
/**
|
|
2098
|
+
* Extended change detector for workspace analysis.
|
|
2099
|
+
*/
|
|
2100
|
+
interface AnalysisChangeDetector extends ChangeDetector {
|
|
2101
|
+
/** Validate cache against current file states */
|
|
2102
|
+
readonly validateCache: (cachedFiles: readonly CachedFileState[], currentFiles: readonly string[]) => Promise<CacheValidationResult>;
|
|
2103
|
+
/** Get all recorded file paths */
|
|
2104
|
+
readonly getRecordedPaths: () => readonly string[];
|
|
2105
|
+
/** Check if configuration files have changed */
|
|
2106
|
+
readonly hasConfigChanged: (configFiles: readonly CachedFileState[]) => Promise<boolean>;
|
|
2107
|
+
}
|
|
2108
|
+
/**
|
|
2109
|
+
* Creates an extended change detector for workspace analysis.
|
|
2110
|
+
*
|
|
2111
|
+
* @param options - Change detector configuration options
|
|
2112
|
+
* @returns An AnalysisChangeDetector instance
|
|
2113
|
+
*
|
|
2114
|
+
* @example
|
|
2115
|
+
* ```ts
|
|
2116
|
+
* const detector = createAnalysisChangeDetector()
|
|
2117
|
+
*
|
|
2118
|
+
* // Record initial file state
|
|
2119
|
+
* await detector.record('src/index.ts')
|
|
2120
|
+
*
|
|
2121
|
+
* // Later, validate cache
|
|
2122
|
+
* const validation = await detector.validateCache(
|
|
2123
|
+
* cachedFileStates,
|
|
2124
|
+
* currentFilePaths
|
|
2125
|
+
* )
|
|
2126
|
+
*
|
|
2127
|
+
* if (!validation.isValid) {
|
|
2128
|
+
* console.log('Cache invalid:', validation.invalidationReason)
|
|
2129
|
+
* }
|
|
2130
|
+
* ```
|
|
2131
|
+
*/
|
|
2132
|
+
declare function createAnalysisChangeDetector(options?: AnalysisChangeDetectorOptions): AnalysisChangeDetector;
|
|
2133
|
+
|
|
2134
|
+
/**
|
|
2135
|
+
* File hasher for cache invalidation and change detection.
|
|
2136
|
+
*
|
|
2137
|
+
* Re-exports from @bfra.me/es/watcher with workspace-analyzer-specific utilities.
|
|
2138
|
+
*/
|
|
2139
|
+
|
|
2140
|
+
/**
|
|
2141
|
+
* Options for creating a workspace file hasher.
|
|
2142
|
+
*/
|
|
2143
|
+
interface WorkspaceHasherOptions {
|
|
2144
|
+
/** Hash algorithm to use (default: sha256) */
|
|
2145
|
+
readonly algorithm?: 'sha256' | 'md5';
|
|
2146
|
+
/** Whether to normalize line endings before hashing (default: true) */
|
|
2147
|
+
readonly normalizeLineEndings?: boolean;
|
|
2148
|
+
}
|
|
2149
|
+
/**
|
|
2150
|
+
* Extended file hasher with workspace-specific utilities.
|
|
2151
|
+
*/
|
|
2152
|
+
interface WorkspaceFileHasher extends FileHasher {
|
|
2153
|
+
/** Hash a JSON object consistently (keys sorted) */
|
|
2154
|
+
readonly hashJson: (obj: unknown) => string;
|
|
2155
|
+
/** Hash multiple files and return combined hash */
|
|
2156
|
+
readonly hashFiles: (paths: readonly string[]) => Promise<string>;
|
|
2157
|
+
}
|
|
2158
|
+
/**
|
|
2159
|
+
* Creates an extended file hasher with workspace-specific utilities.
|
|
2160
|
+
*
|
|
2161
|
+
* @param options - Hasher configuration options
|
|
2162
|
+
* @returns A WorkspaceFileHasher instance
|
|
2163
|
+
*
|
|
2164
|
+
* @example
|
|
2165
|
+
* ```ts
|
|
2166
|
+
* const hasher = createWorkspaceHasher()
|
|
2167
|
+
* const configHash = hasher.hashJson(analyzerConfig)
|
|
2168
|
+
* const filesHash = await hasher.hashFiles(['package.json', 'tsconfig.json'])
|
|
2169
|
+
* ```
|
|
2170
|
+
*/
|
|
2171
|
+
declare function createWorkspaceHasher(options?: WorkspaceHasherOptions): WorkspaceFileHasher;
|
|
2172
|
+
|
|
2173
|
+
/**
|
|
2174
|
+
* Default configuration values for workspace analyzer.
|
|
2175
|
+
*
|
|
2176
|
+
* Provides sensible defaults that work well for typical TypeScript monorepo projects,
|
|
2177
|
+
* with all options explicitly documented and type-safe.
|
|
2178
|
+
*/
|
|
2179
|
+
|
|
2180
|
+
/**
|
|
2181
|
+
* Default glob patterns for including source files in analysis.
|
|
2182
|
+
*/
|
|
2183
|
+
declare const DEFAULT_INCLUDE_PATTERNS: readonly string[];
|
|
2184
|
+
/**
|
|
2185
|
+
* Default glob patterns for excluding files from analysis.
|
|
2186
|
+
*/
|
|
2187
|
+
declare const DEFAULT_EXCLUDE_PATTERNS: readonly string[];
|
|
2188
|
+
/**
|
|
2189
|
+
* Default package location patterns for monorepo scanning.
|
|
2190
|
+
*/
|
|
2191
|
+
declare const DEFAULT_PACKAGE_PATTERNS: readonly string[];
|
|
2192
|
+
/**
|
|
2193
|
+
* Default concurrency limit for parallel analysis.
|
|
2194
|
+
*/
|
|
2195
|
+
declare const DEFAULT_CONCURRENCY = 4;
|
|
2196
|
+
/**
|
|
2197
|
+
* Complete default analyzer configuration.
|
|
2198
|
+
*/
|
|
2199
|
+
interface DefaultAnalyzerConfig {
|
|
2200
|
+
/** Glob patterns for files to include */
|
|
2201
|
+
readonly include: readonly string[];
|
|
2202
|
+
/** Glob patterns for files to exclude */
|
|
2203
|
+
readonly exclude: readonly string[];
|
|
2204
|
+
/** Minimum severity level to report */
|
|
2205
|
+
readonly minSeverity: Severity;
|
|
2206
|
+
/** Categories of issues to check (empty means all) */
|
|
2207
|
+
readonly categories: readonly IssueCategory[];
|
|
2208
|
+
/** Whether to enable caching */
|
|
2209
|
+
readonly cache: boolean;
|
|
2210
|
+
/** Custom rules configuration */
|
|
2211
|
+
readonly rules: Readonly<Record<string, unknown>>;
|
|
2212
|
+
}
|
|
2213
|
+
/**
|
|
2214
|
+
* Default analyzer configuration values.
|
|
2215
|
+
*/
|
|
2216
|
+
declare const DEFAULT_ANALYZER_CONFIG: DefaultAnalyzerConfig;
|
|
2217
|
+
/**
|
|
2218
|
+
* Default workspace analyzer options.
|
|
2219
|
+
*/
|
|
2220
|
+
interface DefaultWorkspaceOptions {
|
|
2221
|
+
/** Glob patterns for package locations */
|
|
2222
|
+
readonly packagePatterns: readonly string[];
|
|
2223
|
+
/** Maximum parallel analysis operations */
|
|
2224
|
+
readonly concurrency: number;
|
|
2225
|
+
/** Cache directory path */
|
|
2226
|
+
readonly cacheDir: string;
|
|
2227
|
+
/** Maximum cache age in milliseconds */
|
|
2228
|
+
readonly maxCacheAge: number;
|
|
2229
|
+
/** Hash algorithm for file content */
|
|
2230
|
+
readonly hashAlgorithm: 'sha256' | 'md5';
|
|
2231
|
+
}
|
|
2232
|
+
/**
|
|
2233
|
+
* Default workspace analyzer options values.
|
|
2234
|
+
*/
|
|
2235
|
+
declare const DEFAULT_WORKSPACE_OPTIONS: DefaultWorkspaceOptions;
|
|
2236
|
+
/**
|
|
2237
|
+
* Complete default configuration combining analyzer and workspace options.
|
|
2238
|
+
*/
|
|
2239
|
+
interface DefaultConfig extends DefaultAnalyzerConfig, DefaultWorkspaceOptions {
|
|
2240
|
+
/** Configuration file path (optional) */
|
|
2241
|
+
readonly configPath?: string;
|
|
2242
|
+
}
|
|
2243
|
+
/**
|
|
2244
|
+
* Get the complete default configuration.
|
|
2245
|
+
*/
|
|
2246
|
+
declare function getDefaultConfig(): DefaultConfig;
|
|
2247
|
+
|
|
2248
|
+
/**
|
|
2249
|
+
* Zod schemas for configuration validation.
|
|
2250
|
+
*
|
|
2251
|
+
* Provides runtime validation for workspace analyzer configuration,
|
|
2252
|
+
* ensuring type safety and helpful error messages for invalid configs.
|
|
2253
|
+
*/
|
|
2254
|
+
|
|
2255
|
+
/**
|
|
2256
|
+
* Complete workspace analyzer configuration schema.
|
|
2257
|
+
*/
|
|
2258
|
+
declare const workspaceAnalyzerConfigSchema: z.ZodObject<{
|
|
2259
|
+
analyzers: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
2260
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
2261
|
+
severity: z.ZodOptional<z.ZodEnum<{
|
|
2262
|
+
info: "info";
|
|
2263
|
+
warning: "warning";
|
|
2264
|
+
error: "error";
|
|
2265
|
+
critical: "critical";
|
|
2266
|
+
}>>;
|
|
2267
|
+
options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
2268
|
+
}, z.core.$strict>>>>;
|
|
2269
|
+
architecture: z.ZodOptional<z.ZodObject<{
|
|
2270
|
+
layers: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
2271
|
+
name: z.ZodString;
|
|
2272
|
+
patterns: z.ZodArray<z.ZodString>;
|
|
2273
|
+
allowedImports: z.ZodArray<z.ZodString>;
|
|
2274
|
+
}, z.core.$strip>>>;
|
|
2275
|
+
allowBarrelExports: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodArray<z.ZodString>]>>;
|
|
2276
|
+
enforcePublicApi: z.ZodOptional<z.ZodBoolean>;
|
|
2277
|
+
}, z.core.$strict>>;
|
|
2278
|
+
packagePatterns: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
|
|
2279
|
+
concurrency: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
2280
|
+
cacheDir: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
2281
|
+
maxCacheAge: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
2282
|
+
hashAlgorithm: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
2283
|
+
sha256: "sha256";
|
|
2284
|
+
md5: "md5";
|
|
2285
|
+
}>>>;
|
|
2286
|
+
include: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
|
|
2287
|
+
exclude: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
|
|
2288
|
+
minSeverity: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
2289
|
+
info: "info";
|
|
2290
|
+
warning: "warning";
|
|
2291
|
+
error: "error";
|
|
2292
|
+
critical: "critical";
|
|
2293
|
+
}>>>;
|
|
2294
|
+
categories: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
2295
|
+
configuration: "configuration";
|
|
2296
|
+
dependency: "dependency";
|
|
2297
|
+
architecture: "architecture";
|
|
2298
|
+
performance: "performance";
|
|
2299
|
+
"circular-import": "circular-import";
|
|
2300
|
+
"unused-export": "unused-export";
|
|
2301
|
+
"type-safety": "type-safety";
|
|
2302
|
+
}>>>>;
|
|
2303
|
+
cache: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
2304
|
+
rules: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
2305
|
+
}, z.core.$strict>;
|
|
2306
|
+
/**
|
|
2307
|
+
* Schema for the analyzeWorkspace() options parameter.
|
|
2308
|
+
*/
|
|
2309
|
+
declare const analyzeWorkspaceOptionsSchema: z.ZodObject<{
|
|
2310
|
+
configPath: z.ZodOptional<z.ZodString>;
|
|
2311
|
+
analyzers: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
2312
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
2313
|
+
severity: z.ZodOptional<z.ZodEnum<{
|
|
2314
|
+
info: "info";
|
|
2315
|
+
warning: "warning";
|
|
2316
|
+
error: "error";
|
|
2317
|
+
critical: "critical";
|
|
2318
|
+
}>>;
|
|
2319
|
+
options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
2320
|
+
}, z.core.$strict>>>>;
|
|
2321
|
+
architecture: z.ZodOptional<z.ZodObject<{
|
|
2322
|
+
layers: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
2323
|
+
name: z.ZodString;
|
|
2324
|
+
patterns: z.ZodArray<z.ZodString>;
|
|
2325
|
+
allowedImports: z.ZodArray<z.ZodString>;
|
|
2326
|
+
}, z.core.$strip>>>;
|
|
2327
|
+
allowBarrelExports: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodArray<z.ZodString>]>>;
|
|
2328
|
+
enforcePublicApi: z.ZodOptional<z.ZodBoolean>;
|
|
2329
|
+
}, z.core.$strict>>;
|
|
2330
|
+
packagePatterns: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
|
|
2331
|
+
concurrency: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
2332
|
+
cacheDir: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
2333
|
+
maxCacheAge: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
2334
|
+
hashAlgorithm: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
2335
|
+
sha256: "sha256";
|
|
2336
|
+
md5: "md5";
|
|
2337
|
+
}>>>;
|
|
2338
|
+
include: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
|
|
2339
|
+
exclude: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
|
|
2340
|
+
minSeverity: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
2341
|
+
info: "info";
|
|
2342
|
+
warning: "warning";
|
|
2343
|
+
error: "error";
|
|
2344
|
+
critical: "critical";
|
|
2345
|
+
}>>>;
|
|
2346
|
+
categories: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
2347
|
+
configuration: "configuration";
|
|
2348
|
+
dependency: "dependency";
|
|
2349
|
+
architecture: "architecture";
|
|
2350
|
+
performance: "performance";
|
|
2351
|
+
"circular-import": "circular-import";
|
|
2352
|
+
"unused-export": "unused-export";
|
|
2353
|
+
"type-safety": "type-safety";
|
|
2354
|
+
}>>>>;
|
|
2355
|
+
cache: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
2356
|
+
rules: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
2357
|
+
}, z.core.$strict>;
|
|
2358
|
+
type WorkspaceAnalyzerConfigOutput = z.output<typeof workspaceAnalyzerConfigSchema>;
|
|
2359
|
+
type AnalyzeWorkspaceOptionsOutput = z.output<typeof analyzeWorkspaceOptionsSchema>;
|
|
2360
|
+
/**
|
|
2361
|
+
* Validates and parses workspace analyzer configuration.
|
|
2362
|
+
*
|
|
2363
|
+
* @param config - Raw configuration input
|
|
2364
|
+
* @returns Validated and defaulted configuration
|
|
2365
|
+
* @throws {z.ZodError} If validation fails
|
|
2366
|
+
*/
|
|
2367
|
+
declare function parseWorkspaceAnalyzerConfig(config: unknown): WorkspaceAnalyzerConfigOutput;
|
|
2368
|
+
/**
|
|
2369
|
+
* Safe parse result type for configuration validation.
|
|
2370
|
+
*/
|
|
2371
|
+
type SafeParseResult<T> = {
|
|
2372
|
+
success: true;
|
|
2373
|
+
data: T;
|
|
2374
|
+
} | {
|
|
2375
|
+
success: false;
|
|
2376
|
+
error: z.ZodError;
|
|
2377
|
+
};
|
|
2378
|
+
/**
|
|
2379
|
+
* Validates analyzeWorkspace() options.
|
|
2380
|
+
*
|
|
2381
|
+
* @param options - Raw options input
|
|
2382
|
+
* @returns Validation result with success status and data/error
|
|
2383
|
+
*/
|
|
2384
|
+
declare function safeParseAnalyzeOptions(options: unknown): SafeParseResult<AnalyzeWorkspaceOptionsOutput>;
|
|
2385
|
+
|
|
2386
|
+
/**
|
|
2387
|
+
* Configuration file loader for workspace-analyzer.config.ts files.
|
|
2388
|
+
*
|
|
2389
|
+
* Provides functionality to discover, load, and parse TypeScript configuration files
|
|
2390
|
+
* using the defineConfig() pattern similar to other tools in the ecosystem.
|
|
2391
|
+
*/
|
|
2392
|
+
|
|
2393
|
+
/**
|
|
2394
|
+
* Error codes for configuration loading operations.
|
|
2395
|
+
*/
|
|
2396
|
+
type ConfigLoadErrorCode = 'FILE_NOT_FOUND' | 'IMPORT_ERROR' | 'VALIDATION_ERROR' | 'INVALID_EXPORT';
|
|
2397
|
+
/**
|
|
2398
|
+
* Error that occurred during configuration loading.
|
|
2399
|
+
*/
|
|
2400
|
+
interface ConfigLoadError {
|
|
2401
|
+
readonly code: ConfigLoadErrorCode;
|
|
2402
|
+
readonly message: string;
|
|
2403
|
+
readonly filePath?: string;
|
|
2404
|
+
readonly cause?: unknown;
|
|
2405
|
+
}
|
|
2406
|
+
/**
|
|
2407
|
+
* Result of loading a configuration file.
|
|
2408
|
+
*/
|
|
2409
|
+
interface ConfigLoadResult {
|
|
2410
|
+
/** Loaded and validated configuration */
|
|
2411
|
+
readonly config: WorkspaceAnalyzerConfigOutput;
|
|
2412
|
+
/** Path to the loaded configuration file */
|
|
2413
|
+
readonly filePath: string;
|
|
2414
|
+
}
|
|
2415
|
+
/**
|
|
2416
|
+
* User-facing configuration interface for defineConfig().
|
|
2417
|
+
* Allows partial configuration that will be merged with defaults.
|
|
2418
|
+
*/
|
|
2419
|
+
interface WorkspaceAnalyzerConfig {
|
|
2420
|
+
/** Glob patterns for files to include */
|
|
2421
|
+
include?: readonly string[];
|
|
2422
|
+
/** Glob patterns for files to exclude */
|
|
2423
|
+
exclude?: readonly string[];
|
|
2424
|
+
/** Minimum severity level to report */
|
|
2425
|
+
minSeverity?: 'info' | 'warning' | 'error' | 'critical';
|
|
2426
|
+
/** Categories of issues to check (empty means all) */
|
|
2427
|
+
categories?: readonly ('configuration' | 'dependency' | 'architecture' | 'performance' | 'circular-import' | 'unused-export' | 'type-safety')[];
|
|
2428
|
+
/** Enable incremental analysis caching */
|
|
2429
|
+
cache?: boolean;
|
|
2430
|
+
/** Custom rules configuration */
|
|
2431
|
+
rules?: Record<string, unknown>;
|
|
2432
|
+
/** Glob patterns for package locations */
|
|
2433
|
+
packagePatterns?: readonly string[];
|
|
2434
|
+
/** Maximum parallel analysis operations */
|
|
2435
|
+
concurrency?: number;
|
|
2436
|
+
/** Directory for analysis cache files */
|
|
2437
|
+
cacheDir?: string;
|
|
2438
|
+
/** Maximum cache age in milliseconds */
|
|
2439
|
+
maxCacheAge?: number;
|
|
2440
|
+
/** Hash algorithm for file content */
|
|
2441
|
+
hashAlgorithm?: 'sha256' | 'md5';
|
|
2442
|
+
/** Per-analyzer configuration */
|
|
2443
|
+
analyzers?: Record<string, {
|
|
2444
|
+
enabled?: boolean;
|
|
2445
|
+
severity?: 'info' | 'warning' | 'error' | 'critical';
|
|
2446
|
+
options?: Record<string, unknown>;
|
|
2447
|
+
}>;
|
|
2448
|
+
/** Architectural analysis rules */
|
|
2449
|
+
architecture?: {
|
|
2450
|
+
layers?: {
|
|
2451
|
+
name: string;
|
|
2452
|
+
patterns: string[];
|
|
2453
|
+
allowedImports: string[];
|
|
2454
|
+
}[];
|
|
2455
|
+
allowBarrelExports?: boolean | string[];
|
|
2456
|
+
enforcePublicApi?: boolean;
|
|
2457
|
+
};
|
|
2458
|
+
}
|
|
2459
|
+
/**
|
|
2460
|
+
* Helper function for defining configuration with type safety.
|
|
2461
|
+
*
|
|
2462
|
+
* @example
|
|
2463
|
+
* ```ts
|
|
2464
|
+
* // workspace-analyzer.config.ts
|
|
2465
|
+
* import {defineConfig} from '@bfra.me/workspace-analyzer'
|
|
2466
|
+
*
|
|
2467
|
+
* export default defineConfig({
|
|
2468
|
+
* minSeverity: 'warning',
|
|
2469
|
+
* categories: ['dependency', 'architecture'],
|
|
2470
|
+
* analyzers: {
|
|
2471
|
+
* 'circular-import': {enabled: true},
|
|
2472
|
+
* 'unused-dependency': {enabled: true},
|
|
2473
|
+
* },
|
|
2474
|
+
* })
|
|
2475
|
+
* ```
|
|
2476
|
+
*/
|
|
2477
|
+
declare function defineConfig(config: WorkspaceAnalyzerConfig): WorkspaceAnalyzerConfig;
|
|
2478
|
+
/**
|
|
2479
|
+
* Finds a configuration file in the given directory or its parents.
|
|
2480
|
+
*
|
|
2481
|
+
* @param startDir - Directory to start searching from
|
|
2482
|
+
* @param stopAt - Directory to stop searching at (defaults to filesystem root)
|
|
2483
|
+
* @returns Path to the found configuration file, or undefined if not found
|
|
2484
|
+
*/
|
|
2485
|
+
declare function findConfigFile(startDir: string, stopAt?: string): Promise<string | undefined>;
|
|
2486
|
+
/**
|
|
2487
|
+
* Loads and validates a configuration file.
|
|
2488
|
+
*
|
|
2489
|
+
* @param filePath - Path to the configuration file
|
|
2490
|
+
* @returns Result containing the loaded config or an error
|
|
2491
|
+
*/
|
|
2492
|
+
declare function loadConfigFile(filePath: string): Promise<Result<ConfigLoadResult, ConfigLoadError>>;
|
|
2493
|
+
/**
|
|
2494
|
+
* Discovers and loads configuration from the workspace.
|
|
2495
|
+
*
|
|
2496
|
+
* @param workspacePath - Root path of the workspace
|
|
2497
|
+
* @param explicitPath - Optional explicit path to config file
|
|
2498
|
+
* @returns Result containing the loaded config or an error
|
|
2499
|
+
*/
|
|
2500
|
+
declare function loadConfig(workspacePath: string, explicitPath?: string): Promise<Result<ConfigLoadResult | undefined, ConfigLoadError>>;
|
|
2501
|
+
|
|
2502
|
+
/**
|
|
2503
|
+
* Configuration merging utilities for workspace analyzer.
|
|
2504
|
+
*
|
|
2505
|
+
* Provides deep merging of configuration sources with proper precedence:
|
|
2506
|
+
* programmatic options > config file > defaults
|
|
2507
|
+
*/
|
|
2508
|
+
|
|
2509
|
+
/**
|
|
2510
|
+
* Complete configuration after merging all sources.
|
|
2511
|
+
*/
|
|
2512
|
+
interface MergedConfig {
|
|
2513
|
+
/** Glob patterns for files to include */
|
|
2514
|
+
readonly include: readonly string[];
|
|
2515
|
+
/** Glob patterns for files to exclude */
|
|
2516
|
+
readonly exclude: readonly string[];
|
|
2517
|
+
/** Minimum severity level to report */
|
|
2518
|
+
readonly minSeverity: 'info' | 'warning' | 'error' | 'critical';
|
|
2519
|
+
/** Categories of issues to check (empty means all) */
|
|
2520
|
+
readonly categories: readonly ('configuration' | 'dependency' | 'architecture' | 'performance' | 'circular-import' | 'unused-export' | 'type-safety')[];
|
|
2521
|
+
/** Enable incremental analysis caching */
|
|
2522
|
+
readonly cache: boolean;
|
|
2523
|
+
/** Custom rules configuration */
|
|
2524
|
+
readonly rules: Readonly<Record<string, unknown>>;
|
|
2525
|
+
/** Glob patterns for package locations */
|
|
2526
|
+
readonly packagePatterns: readonly string[];
|
|
2527
|
+
/** Maximum parallel analysis operations */
|
|
2528
|
+
readonly concurrency: number;
|
|
2529
|
+
/** Directory for analysis cache files */
|
|
2530
|
+
readonly cacheDir: string;
|
|
2531
|
+
/** Maximum cache age in milliseconds */
|
|
2532
|
+
readonly maxCacheAge: number;
|
|
2533
|
+
/** Hash algorithm for file content */
|
|
2534
|
+
readonly hashAlgorithm: 'sha256' | 'md5';
|
|
2535
|
+
/** Per-analyzer configuration */
|
|
2536
|
+
readonly analyzers: Readonly<Record<string, {
|
|
2537
|
+
readonly enabled?: boolean;
|
|
2538
|
+
readonly severity?: 'info' | 'warning' | 'error' | 'critical';
|
|
2539
|
+
readonly options?: Readonly<Record<string, unknown>>;
|
|
2540
|
+
}>>;
|
|
2541
|
+
/** Architectural analysis rules */
|
|
2542
|
+
readonly architecture?: {
|
|
2543
|
+
readonly layers?: readonly {
|
|
2544
|
+
readonly name: string;
|
|
2545
|
+
readonly patterns: readonly string[];
|
|
2546
|
+
readonly allowedImports: readonly string[];
|
|
2547
|
+
}[];
|
|
2548
|
+
readonly allowBarrelExports?: boolean | readonly string[];
|
|
2549
|
+
readonly enforcePublicApi?: boolean;
|
|
2550
|
+
};
|
|
2551
|
+
}
|
|
2552
|
+
/**
|
|
2553
|
+
* Merges analyzer-specific configurations.
|
|
2554
|
+
*
|
|
2555
|
+
* @param baseAnalyzers - Base analyzer config from file
|
|
2556
|
+
* @param overrideAnalyzers - Override config from programmatic options
|
|
2557
|
+
* @returns Merged analyzer configurations
|
|
2558
|
+
*/
|
|
2559
|
+
declare function mergeAnalyzerConfigs(baseAnalyzers: MergedConfig['analyzers'], overrideAnalyzers?: WorkspaceAnalyzerConfig['analyzers']): MergedConfig['analyzers'];
|
|
2560
|
+
/**
|
|
2561
|
+
* Merges configuration from multiple sources.
|
|
2562
|
+
*
|
|
2563
|
+
* Precedence (highest to lowest):
|
|
2564
|
+
* 1. Programmatic options passed to analyzeWorkspace()
|
|
2565
|
+
* 2. Configuration file (workspace-analyzer.config.ts)
|
|
2566
|
+
* 3. Default values
|
|
2567
|
+
*
|
|
2568
|
+
* @param fileConfig - Configuration loaded from file (optional)
|
|
2569
|
+
* @param programmaticOptions - Options passed programmatically (optional)
|
|
2570
|
+
* @returns Fully merged configuration with all defaults applied
|
|
2571
|
+
*/
|
|
2572
|
+
declare function mergeConfig(fileConfig?: WorkspaceAnalyzerConfigOutput, programmaticOptions?: WorkspaceAnalyzerConfig): MergedConfig;
|
|
2573
|
+
/**
|
|
2574
|
+
* Creates analyzer options from merged configuration for a specific analyzer.
|
|
2575
|
+
*
|
|
2576
|
+
* @param mergedConfig - The fully merged configuration
|
|
2577
|
+
* @param analyzerId - The ID of the analyzer to get options for
|
|
2578
|
+
* @returns Options for the specified analyzer
|
|
2579
|
+
*/
|
|
2580
|
+
declare function getAnalyzerOptions(mergedConfig: MergedConfig, analyzerId: string): {
|
|
2581
|
+
enabled: boolean;
|
|
2582
|
+
minSeverity: MergedConfig['minSeverity'];
|
|
2583
|
+
categories: MergedConfig['categories'];
|
|
2584
|
+
options: Record<string, unknown>;
|
|
2585
|
+
};
|
|
2586
|
+
|
|
2587
|
+
/**
|
|
2588
|
+
* Incremental analyzer orchestrator for workspace analysis.
|
|
2589
|
+
*
|
|
2590
|
+
* Provides efficient incremental analysis by leveraging file change detection,
|
|
2591
|
+
* cache management, and parallel execution for large codebase performance.
|
|
2592
|
+
*/
|
|
2593
|
+
|
|
2594
|
+
/**
|
|
2595
|
+
* Options for incremental analysis.
|
|
2596
|
+
*/
|
|
2597
|
+
interface IncrementalAnalysisOptions {
|
|
2598
|
+
/** Workspace root path */
|
|
2599
|
+
readonly workspacePath: string;
|
|
2600
|
+
/** Current analyzer version (for cache invalidation) */
|
|
2601
|
+
readonly analyzerVersion: string;
|
|
2602
|
+
/** Whether to use caching (default: true) */
|
|
2603
|
+
readonly useCache?: boolean;
|
|
2604
|
+
/** Maximum number of concurrent file analyses (default: 4) */
|
|
2605
|
+
readonly concurrency?: number;
|
|
2606
|
+
/** Maximum cache age in milliseconds (default: 7 days) */
|
|
2607
|
+
readonly maxCacheAge?: number;
|
|
2608
|
+
/** Minimum severity to report (default: 'info') */
|
|
2609
|
+
readonly minSeverity?: Severity;
|
|
2610
|
+
/** Progress callback for reporting */
|
|
2611
|
+
readonly onProgress?: (progress: AnalysisProgress) => void;
|
|
2612
|
+
/** Cache directory (default: .workspace-analyzer-cache) */
|
|
2613
|
+
readonly cacheDir?: string;
|
|
2614
|
+
/** Hash algorithm for file content (default: sha256) */
|
|
2615
|
+
readonly hashAlgorithm?: 'sha256' | 'md5';
|
|
2616
|
+
}
|
|
2617
|
+
/**
|
|
2618
|
+
* Error codes for incremental analysis.
|
|
2619
|
+
*/
|
|
2620
|
+
type IncrementalAnalysisErrorCode = 'SCAN_FAILED' | 'ANALYSIS_FAILED' | 'CACHE_ERROR' | 'ANALYZER_ERROR' | 'TIMEOUT';
|
|
2621
|
+
/**
|
|
2622
|
+
* Error for incremental analysis operations.
|
|
2623
|
+
*/
|
|
2624
|
+
interface IncrementalAnalysisError {
|
|
2625
|
+
readonly code: IncrementalAnalysisErrorCode;
|
|
2626
|
+
readonly message: string;
|
|
2627
|
+
readonly cause?: Error;
|
|
2628
|
+
}
|
|
2629
|
+
/**
|
|
2630
|
+
* Result of incremental analysis.
|
|
2631
|
+
*/
|
|
2632
|
+
interface IncrementalAnalysisResult {
|
|
2633
|
+
/** All issues found */
|
|
2634
|
+
readonly issues: readonly Issue[];
|
|
2635
|
+
/** Number of files analyzed (not from cache) */
|
|
2636
|
+
readonly filesAnalyzed: number;
|
|
2637
|
+
/** Number of files loaded from cache */
|
|
2638
|
+
readonly filesFromCache: number;
|
|
2639
|
+
/** Number of packages analyzed */
|
|
2640
|
+
readonly packagesAnalyzed: number;
|
|
2641
|
+
/** Analysis duration in milliseconds */
|
|
2642
|
+
readonly durationMs: number;
|
|
2643
|
+
/** Whether cache was used */
|
|
2644
|
+
readonly cacheUsed: boolean;
|
|
2645
|
+
/** Cache statistics after analysis */
|
|
2646
|
+
readonly cacheStats?: {
|
|
2647
|
+
readonly hitRate: number;
|
|
2648
|
+
readonly hitCount: number;
|
|
2649
|
+
readonly missCount: number;
|
|
2650
|
+
};
|
|
2651
|
+
}
|
|
2652
|
+
/**
|
|
2653
|
+
* Extended analysis context with incremental analysis metadata.
|
|
2654
|
+
*/
|
|
2655
|
+
interface IncrementalAnalysisContext {
|
|
2656
|
+
/** Workspace root path */
|
|
2657
|
+
readonly workspacePath: string;
|
|
2658
|
+
/** All source files in the workspace */
|
|
2659
|
+
readonly files: readonly string[];
|
|
2660
|
+
/** Package paths (relative to workspace root) */
|
|
2661
|
+
readonly packagePaths: readonly string[];
|
|
2662
|
+
/** Configuration hash for cache invalidation */
|
|
2663
|
+
readonly configHash: string;
|
|
2664
|
+
/** Current cache state (if available) */
|
|
2665
|
+
readonly cache?: AnalysisCache;
|
|
2666
|
+
/** Files that need fresh analysis */
|
|
2667
|
+
readonly filesToAnalyze: readonly string[];
|
|
2668
|
+
/** Files that can use cached results */
|
|
2669
|
+
readonly cachedFiles: readonly string[];
|
|
2670
|
+
/** Progress reporter */
|
|
2671
|
+
readonly reportProgress: (current: string, processed: number, total?: number) => void;
|
|
2672
|
+
}
|
|
2673
|
+
/**
|
|
2674
|
+
* Incremental analyzer orchestrator.
|
|
2675
|
+
*/
|
|
2676
|
+
interface IncrementalAnalyzer {
|
|
2677
|
+
/** Run incremental analysis on the workspace */
|
|
2678
|
+
readonly analyze: (files: readonly string[], packages: readonly WorkspacePackage[], analyzers: readonly Analyzer[]) => Promise<Result<IncrementalAnalysisResult, IncrementalAnalysisError>>;
|
|
2679
|
+
/** Invalidate cache for specific files */
|
|
2680
|
+
readonly invalidateFiles: (paths: readonly string[]) => Promise<void>;
|
|
2681
|
+
/** Clear the entire cache */
|
|
2682
|
+
readonly clearCache: () => Promise<Result<void, IncrementalAnalysisError>>;
|
|
2683
|
+
/** Get current cache statistics */
|
|
2684
|
+
readonly getCacheStats: () => Promise<Result<{
|
|
2685
|
+
cachedFiles: number;
|
|
2686
|
+
cachedPackages: number;
|
|
2687
|
+
ageMs: number;
|
|
2688
|
+
}, IncrementalAnalysisError>>;
|
|
2689
|
+
}
|
|
2690
|
+
/**
|
|
2691
|
+
* Default options for incremental analysis.
|
|
2692
|
+
*/
|
|
2693
|
+
declare const DEFAULT_INCREMENTAL_OPTIONS: {
|
|
2694
|
+
readonly useCache: true;
|
|
2695
|
+
readonly concurrency: 4;
|
|
2696
|
+
readonly maxCacheAge: number;
|
|
2697
|
+
readonly minSeverity: Severity;
|
|
2698
|
+
readonly cacheDir: ".workspace-analyzer-cache";
|
|
2699
|
+
readonly hashAlgorithm: "sha256";
|
|
2700
|
+
};
|
|
2701
|
+
/**
|
|
2702
|
+
* Creates an incremental analyzer orchestrator.
|
|
2703
|
+
*
|
|
2704
|
+
* @param options - Incremental analysis configuration
|
|
2705
|
+
* @returns An IncrementalAnalyzer instance
|
|
2706
|
+
*
|
|
2707
|
+
* @example
|
|
2708
|
+
* ```ts
|
|
2709
|
+
* const analyzer = createIncrementalAnalyzer({
|
|
2710
|
+
* workspacePath: '/path/to/workspace',
|
|
2711
|
+
* analyzerVersion: '1.0.0',
|
|
2712
|
+
* onProgress: (progress) => {
|
|
2713
|
+
* console.error(`${progress.phase}: ${progress.processed}/${progress.total}`)
|
|
2714
|
+
* },
|
|
2715
|
+
* })
|
|
2716
|
+
*
|
|
2717
|
+
* const result = await analyzer.analyze(files, packages, analyzers)
|
|
2718
|
+
* if (result.success) {
|
|
2719
|
+
* console.error(`Found ${result.data.issues.length} issues`)
|
|
2720
|
+
* }
|
|
2721
|
+
* ```
|
|
2722
|
+
*/
|
|
2723
|
+
declare function createIncrementalAnalyzer(options: IncrementalAnalysisOptions): IncrementalAnalyzer;
|
|
2724
|
+
/**
|
|
2725
|
+
* Creates a progress callback that logs to stderr.
|
|
2726
|
+
*/
|
|
2727
|
+
declare function createConsoleProgressCallback(): (progress: AnalysisProgress) => void;
|
|
2728
|
+
/**
|
|
2729
|
+
* Creates a no-op progress callback.
|
|
2730
|
+
*/
|
|
2731
|
+
declare function createSilentProgressCallback(): (progress: AnalysisProgress) => void;
|
|
2732
|
+
|
|
2733
|
+
/**
|
|
2734
|
+
* Analysis orchestrator for workspace analysis.
|
|
2735
|
+
*
|
|
2736
|
+
* Adapts the doc-sync sync-orchestrator pattern for workspace analysis,
|
|
2737
|
+
* coordinating scanner, analyzers, and reporters into a unified pipeline.
|
|
2738
|
+
*/
|
|
2739
|
+
|
|
2740
|
+
/**
|
|
2741
|
+
* Extended analysis context shared between analyzers.
|
|
2742
|
+
* Contains all information needed to perform analysis operations.
|
|
2743
|
+
*/
|
|
2744
|
+
interface AnalysisContext {
|
|
2745
|
+
/** Root path of the workspace being analyzed */
|
|
2746
|
+
readonly workspacePath: string;
|
|
2747
|
+
/** All packages discovered in the workspace */
|
|
2748
|
+
readonly packages: readonly WorkspacePackage[];
|
|
2749
|
+
/** All source files in the workspace */
|
|
2750
|
+
readonly sourceFiles: readonly string[];
|
|
2751
|
+
/** Merged configuration */
|
|
2752
|
+
readonly config: MergedConfig;
|
|
2753
|
+
/** Configuration hash for caching */
|
|
2754
|
+
readonly configHash: string;
|
|
2755
|
+
/** Report progress during analysis */
|
|
2756
|
+
readonly reportProgress: (message: string) => void;
|
|
2757
|
+
}
|
|
2758
|
+
/**
|
|
2759
|
+
* Error codes for orchestration operations.
|
|
2760
|
+
*/
|
|
2761
|
+
type OrchestratorErrorCode = 'SCAN_FAILED' | 'ANALYSIS_FAILED' | 'INVALID_CONFIG' | 'NO_PACKAGES';
|
|
2762
|
+
/**
|
|
2763
|
+
* Error that occurred during orchestration.
|
|
2764
|
+
*/
|
|
2765
|
+
interface OrchestratorError {
|
|
2766
|
+
readonly code: OrchestratorErrorCode;
|
|
2767
|
+
readonly message: string;
|
|
2768
|
+
readonly cause?: unknown;
|
|
2769
|
+
}
|
|
2770
|
+
/**
|
|
2771
|
+
* Options for the analysis orchestrator.
|
|
2772
|
+
*/
|
|
2773
|
+
interface OrchestratorOptions {
|
|
2774
|
+
/** Root path of the workspace to analyze */
|
|
2775
|
+
readonly workspacePath: string;
|
|
2776
|
+
/** Merged configuration */
|
|
2777
|
+
readonly config: MergedConfig;
|
|
2778
|
+
/** Progress callback */
|
|
2779
|
+
readonly onProgress?: (progress: AnalysisProgress) => void;
|
|
2780
|
+
/** Verbose logging */
|
|
2781
|
+
readonly verbose?: boolean;
|
|
2782
|
+
}
|
|
2783
|
+
/**
|
|
2784
|
+
* Analysis orchestrator interface.
|
|
2785
|
+
*/
|
|
2786
|
+
interface AnalysisOrchestrator {
|
|
2787
|
+
/** Run full analysis on the workspace */
|
|
2788
|
+
readonly analyzeAll: () => Promise<Result<AnalysisResult, OrchestratorError>>;
|
|
2789
|
+
/** Run analysis on specific packages */
|
|
2790
|
+
readonly analyzePackages: (packageNames: readonly string[]) => Promise<Result<AnalysisResult, OrchestratorError>>;
|
|
2791
|
+
/** Get the current analysis context */
|
|
2792
|
+
readonly getContext: () => Promise<Result<AnalysisContext, OrchestratorError>>;
|
|
2793
|
+
}
|
|
2794
|
+
/**
|
|
2795
|
+
* Creates an analysis orchestrator for coordinating workspace analysis.
|
|
2796
|
+
*
|
|
2797
|
+
* @example
|
|
2798
|
+
* ```ts
|
|
2799
|
+
* const orchestrator = createOrchestrator({
|
|
2800
|
+
* config: mergedConfig,
|
|
2801
|
+
* onProgress: (progress) => console.log(progress.phase),
|
|
2802
|
+
* })
|
|
2803
|
+
*
|
|
2804
|
+
* const result = await orchestrator.analyzeAll()
|
|
2805
|
+
* if (result.success) {
|
|
2806
|
+
* console.log(`Found ${result.data.summary.totalIssues} issues`)
|
|
2807
|
+
* }
|
|
2808
|
+
* ```
|
|
2809
|
+
*/
|
|
2810
|
+
declare function createOrchestrator(options: OrchestratorOptions): AnalysisOrchestrator;
|
|
2811
|
+
|
|
2812
|
+
/**
|
|
2813
|
+
* Configuration file parser for package.json, tsconfig.json, and other config files.
|
|
2814
|
+
*
|
|
2815
|
+
* Provides utilities for parsing and extracting information from various
|
|
2816
|
+
* configuration files used in TypeScript/JavaScript projects.
|
|
2817
|
+
*/
|
|
2818
|
+
|
|
2819
|
+
/**
|
|
2820
|
+
* Error codes for configuration parsing.
|
|
2821
|
+
*/
|
|
2822
|
+
type ConfigErrorCode = 'FILE_NOT_FOUND' | 'INVALID_JSON' | 'INVALID_CONFIG' | 'READ_ERROR';
|
|
2823
|
+
/**
|
|
2824
|
+
* Error that occurred during configuration parsing.
|
|
2825
|
+
*/
|
|
2826
|
+
interface ConfigError {
|
|
2827
|
+
/** Error code for programmatic handling */
|
|
2828
|
+
readonly code: ConfigErrorCode;
|
|
2829
|
+
/** Human-readable error message */
|
|
2830
|
+
readonly message: string;
|
|
2831
|
+
/** Path to the config file */
|
|
2832
|
+
readonly filePath: string;
|
|
2833
|
+
/** Underlying cause */
|
|
2834
|
+
readonly cause?: unknown;
|
|
2835
|
+
}
|
|
2836
|
+
/**
|
|
2837
|
+
* Parsed package.json structure with relevant fields for analysis.
|
|
2838
|
+
*/
|
|
2839
|
+
interface ParsedPackageJson {
|
|
2840
|
+
/** Package name */
|
|
2841
|
+
readonly name: string;
|
|
2842
|
+
/** Package version */
|
|
2843
|
+
readonly version: string;
|
|
2844
|
+
/** Package description */
|
|
2845
|
+
readonly description?: string;
|
|
2846
|
+
/** Main entry point */
|
|
2847
|
+
readonly main?: string;
|
|
2848
|
+
/** Module entry point (ESM) */
|
|
2849
|
+
readonly module?: string;
|
|
2850
|
+
/** Types entry point */
|
|
2851
|
+
readonly types?: string;
|
|
2852
|
+
/** Exports map */
|
|
2853
|
+
readonly exports?: Record<string, unknown>;
|
|
2854
|
+
/** Dependencies */
|
|
2855
|
+
readonly dependencies?: Readonly<Record<string, string>>;
|
|
2856
|
+
/** Development dependencies */
|
|
2857
|
+
readonly devDependencies?: Readonly<Record<string, string>>;
|
|
2858
|
+
/** Peer dependencies */
|
|
2859
|
+
readonly peerDependencies?: Readonly<Record<string, string>>;
|
|
2860
|
+
/** Optional dependencies */
|
|
2861
|
+
readonly optionalDependencies?: Readonly<Record<string, string>>;
|
|
2862
|
+
/** Package type (module or commonjs) */
|
|
2863
|
+
readonly type?: 'module' | 'commonjs';
|
|
2864
|
+
/** Scripts */
|
|
2865
|
+
readonly scripts?: Readonly<Record<string, string>>;
|
|
2866
|
+
/** Files to include in package */
|
|
2867
|
+
readonly files?: readonly string[];
|
|
2868
|
+
/** Raw package.json data */
|
|
2869
|
+
readonly raw: Readonly<Record<string, unknown>>;
|
|
2870
|
+
}
|
|
2871
|
+
/**
|
|
2872
|
+
* Parsed tsconfig.json structure with relevant fields for analysis.
|
|
2873
|
+
*/
|
|
2874
|
+
interface ParsedTsConfig {
|
|
2875
|
+
/** Extends from another config */
|
|
2876
|
+
readonly extends?: string | readonly string[];
|
|
2877
|
+
/** Compiler options */
|
|
2878
|
+
readonly compilerOptions?: TsCompilerOptions;
|
|
2879
|
+
/** Include patterns */
|
|
2880
|
+
readonly include?: readonly string[];
|
|
2881
|
+
/** Exclude patterns */
|
|
2882
|
+
readonly exclude?: readonly string[];
|
|
2883
|
+
/** Project references */
|
|
2884
|
+
readonly references?: readonly TsProjectReference[];
|
|
2885
|
+
/** File path of the config */
|
|
2886
|
+
readonly filePath: string;
|
|
2887
|
+
/** Raw tsconfig data */
|
|
2888
|
+
readonly raw: Readonly<Record<string, unknown>>;
|
|
2889
|
+
}
|
|
2890
|
+
/**
|
|
2891
|
+
* TypeScript compiler options subset relevant for analysis.
|
|
2892
|
+
*/
|
|
2893
|
+
interface TsCompilerOptions {
|
|
2894
|
+
/** Target ECMAScript version */
|
|
2895
|
+
readonly target?: string;
|
|
2896
|
+
/** Module system */
|
|
2897
|
+
readonly module?: string;
|
|
2898
|
+
/** Module resolution strategy */
|
|
2899
|
+
readonly moduleResolution?: string;
|
|
2900
|
+
/** Path mappings */
|
|
2901
|
+
readonly paths?: Readonly<Record<string, readonly string[]>>;
|
|
2902
|
+
/** Base URL for path resolution */
|
|
2903
|
+
readonly baseUrl?: string;
|
|
2904
|
+
/** Root directory */
|
|
2905
|
+
readonly rootDir?: string;
|
|
2906
|
+
/** Output directory */
|
|
2907
|
+
readonly outDir?: string;
|
|
2908
|
+
/** Strict mode */
|
|
2909
|
+
readonly strict?: boolean;
|
|
2910
|
+
/** Declaration files */
|
|
2911
|
+
readonly declaration?: boolean;
|
|
2912
|
+
/** Source maps */
|
|
2913
|
+
readonly sourceMap?: boolean;
|
|
2914
|
+
/** ESM interop */
|
|
2915
|
+
readonly esModuleInterop?: boolean;
|
|
2916
|
+
/** Allow synthetic default imports */
|
|
2917
|
+
readonly allowSyntheticDefaultImports?: boolean;
|
|
2918
|
+
/** Skip library check */
|
|
2919
|
+
readonly skipLibCheck?: boolean;
|
|
2920
|
+
/** Resolve JSON modules */
|
|
2921
|
+
readonly resolveJsonModule?: boolean;
|
|
2922
|
+
/** Isolated modules */
|
|
2923
|
+
readonly isolatedModules?: boolean;
|
|
2924
|
+
}
|
|
2925
|
+
/**
|
|
2926
|
+
* TypeScript project reference.
|
|
2927
|
+
*/
|
|
2928
|
+
interface TsProjectReference {
|
|
2929
|
+
/** Path to referenced project */
|
|
2930
|
+
readonly path: string;
|
|
2931
|
+
}
|
|
2932
|
+
/**
|
|
2933
|
+
* Parses a package.json file.
|
|
2934
|
+
*
|
|
2935
|
+
* @example
|
|
2936
|
+
* ```ts
|
|
2937
|
+
* const result = await parsePackageJson('/path/to/package.json')
|
|
2938
|
+
* if (result.success) {
|
|
2939
|
+
* console.log(`Package: ${result.data.name}@${result.data.version}`)
|
|
2940
|
+
* }
|
|
2941
|
+
* ```
|
|
2942
|
+
*/
|
|
2943
|
+
declare function parsePackageJson(packageJsonPath: string): Promise<Result<ParsedPackageJson, ConfigError>>;
|
|
2944
|
+
/**
|
|
2945
|
+
* Parses package.json content from a string.
|
|
2946
|
+
*/
|
|
2947
|
+
declare function parsePackageJsonContent(content: string, filePath: string): Result<ParsedPackageJson, ConfigError>;
|
|
2948
|
+
/**
|
|
2949
|
+
* Parses a tsconfig.json file.
|
|
2950
|
+
*
|
|
2951
|
+
* @example
|
|
2952
|
+
* ```ts
|
|
2953
|
+
* const result = await parseTsConfig('/path/to/tsconfig.json')
|
|
2954
|
+
* if (result.success) {
|
|
2955
|
+
* console.log(`Target: ${result.data.compilerOptions?.target}`)
|
|
2956
|
+
* }
|
|
2957
|
+
* ```
|
|
2958
|
+
*/
|
|
2959
|
+
declare function parseTsConfig(tsconfigPath: string): Promise<Result<ParsedTsConfig, ConfigError>>;
|
|
2960
|
+
/**
|
|
2961
|
+
* Parses tsconfig.json content from a string.
|
|
2962
|
+
*
|
|
2963
|
+
* Note: This does basic JSON parsing. tsconfig.json supports comments
|
|
2964
|
+
* and trailing commas which this parser strips before parsing.
|
|
2965
|
+
*/
|
|
2966
|
+
declare function parseTsConfigContent(content: string, filePath: string): Result<ParsedTsConfig, ConfigError>;
|
|
2967
|
+
/**
|
|
2968
|
+
* Gets all dependencies from a package.json (combined).
|
|
2969
|
+
*/
|
|
2970
|
+
declare function getAllDependencies(pkg: ParsedPackageJson): Readonly<Record<string, {
|
|
2971
|
+
version: string;
|
|
2972
|
+
type: 'prod' | 'dev' | 'peer' | 'optional';
|
|
2973
|
+
}>>;
|
|
2974
|
+
/**
|
|
2975
|
+
* Resolves tsconfig extends chain.
|
|
2976
|
+
*/
|
|
2977
|
+
declare function resolveTsConfigExtends(tsconfigPath: string, maxDepth?: number): Promise<Result<ParsedTsConfig[], ConfigError>>;
|
|
2978
|
+
|
|
2979
|
+
/**
|
|
2980
|
+
* TypeScript AST parser utilities for workspace analysis.
|
|
2981
|
+
*
|
|
2982
|
+
* Re-exports core parsing utilities from @bfra.me/doc-sync/parsers and provides
|
|
2983
|
+
* additional workspace-analyzer-specific helpers for multi-file analysis.
|
|
2984
|
+
*/
|
|
2985
|
+
|
|
2986
|
+
/**
|
|
2987
|
+
* Gets the source file at a path, creating the project if needed.
|
|
2988
|
+
*
|
|
2989
|
+
* Convenience function for one-off file parsing without manually managing a project.
|
|
2990
|
+
*/
|
|
2991
|
+
declare function getSourceFile(filePath: string, options?: {
|
|
2992
|
+
tsConfigPath?: string;
|
|
2993
|
+
compilerOptions?: Record<string, unknown>;
|
|
2994
|
+
}): Result<SourceFile, ParseError>;
|
|
2995
|
+
/**
|
|
2996
|
+
* Parses multiple source files into a single project.
|
|
2997
|
+
*
|
|
2998
|
+
* More efficient than parsing files individually when analyzing many files,
|
|
2999
|
+
* as the project can share type resolution and compiler settings.
|
|
3000
|
+
*/
|
|
3001
|
+
declare function parseSourceFiles(filePaths: readonly string[], options?: {
|
|
3002
|
+
tsConfigPath?: string;
|
|
3003
|
+
compilerOptions?: Record<string, unknown>;
|
|
3004
|
+
}): Result<Project, ParseError>;
|
|
3005
|
+
/**
|
|
3006
|
+
* Gets all source files from a project.
|
|
3007
|
+
*/
|
|
3008
|
+
declare function getAllSourceFiles(project: Project): readonly SourceFile[];
|
|
3009
|
+
/**
|
|
3010
|
+
* Checks if a file path represents a TypeScript file.
|
|
3011
|
+
*/
|
|
3012
|
+
declare function isTypeScriptFile(filePath: string): boolean;
|
|
3013
|
+
/**
|
|
3014
|
+
* Checks if a file path represents a JavaScript file.
|
|
3015
|
+
*/
|
|
3016
|
+
declare function isJavaScriptFile(filePath: string): boolean;
|
|
3017
|
+
/**
|
|
3018
|
+
* Checks if a file path is a parseable source file (TypeScript or JavaScript).
|
|
3019
|
+
*/
|
|
3020
|
+
declare function isSourceFile(filePath: string): boolean;
|
|
3021
|
+
|
|
3022
|
+
/**
|
|
3023
|
+
* Bundle size estimator for identifying large module contributors.
|
|
3024
|
+
*
|
|
3025
|
+
* Analyzes source files and dependencies to estimate bundle size impact,
|
|
3026
|
+
* helping identify optimization opportunities for tree-shaking and code splitting.
|
|
3027
|
+
*
|
|
3028
|
+
* This is a heuristic estimator - actual bundle sizes depend on bundler configuration,
|
|
3029
|
+
* tree-shaking effectiveness, and minification.
|
|
3030
|
+
*/
|
|
3031
|
+
|
|
3032
|
+
/**
|
|
3033
|
+
* Estimated size information for a module or package.
|
|
3034
|
+
*/
|
|
3035
|
+
interface BundleSizeEstimate {
|
|
3036
|
+
/** Source file path or package name */
|
|
3037
|
+
readonly identifier: string;
|
|
3038
|
+
/** Raw source size in bytes (unminified) */
|
|
3039
|
+
readonly sourceSize: number;
|
|
3040
|
+
/** Estimated minified size in bytes (heuristic: ~60% of source) */
|
|
3041
|
+
readonly estimatedMinifiedSize: number;
|
|
3042
|
+
/** Estimated gzipped size in bytes (heuristic: ~30% of minified) */
|
|
3043
|
+
readonly estimatedGzippedSize: number;
|
|
3044
|
+
/** Number of imports this module brings in */
|
|
3045
|
+
readonly importCount: number;
|
|
3046
|
+
/** Number of exports this module provides */
|
|
3047
|
+
readonly exportCount: number;
|
|
3048
|
+
/** Whether this is a direct or transitive dependency */
|
|
3049
|
+
readonly isTransitive: boolean;
|
|
3050
|
+
}
|
|
3051
|
+
/**
|
|
3052
|
+
* Aggregated bundle size statistics for a package.
|
|
3053
|
+
*/
|
|
3054
|
+
interface PackageBundleStats {
|
|
3055
|
+
/** Package name */
|
|
3056
|
+
readonly packageName: string;
|
|
3057
|
+
/** Total source size of all modules */
|
|
3058
|
+
readonly totalSourceSize: number;
|
|
3059
|
+
/** Estimated total minified size */
|
|
3060
|
+
readonly totalMinifiedSize: number;
|
|
3061
|
+
/** Estimated total gzipped size */
|
|
3062
|
+
readonly totalGzippedSize: number;
|
|
3063
|
+
/** Number of source files */
|
|
3064
|
+
readonly fileCount: number;
|
|
3065
|
+
/** Individual file estimates */
|
|
3066
|
+
readonly files: readonly BundleSizeEstimate[];
|
|
3067
|
+
/** External dependency size estimates */
|
|
3068
|
+
readonly dependencies: readonly DependencySizeEstimate[];
|
|
3069
|
+
/** Top contributors by size */
|
|
3070
|
+
readonly topContributors: readonly BundleSizeEstimate[];
|
|
3071
|
+
}
|
|
3072
|
+
/**
|
|
3073
|
+
* Size estimate for an external dependency.
|
|
3074
|
+
*/
|
|
3075
|
+
interface DependencySizeEstimate {
|
|
3076
|
+
/** Package name */
|
|
3077
|
+
readonly packageName: string;
|
|
3078
|
+
/** Estimated size (if known from registry data) */
|
|
3079
|
+
readonly estimatedSize?: number;
|
|
3080
|
+
/** Whether size data is available */
|
|
3081
|
+
readonly sizeKnown: boolean;
|
|
3082
|
+
/** Number of times imported */
|
|
3083
|
+
readonly importCount: number;
|
|
3084
|
+
/** Import locations */
|
|
3085
|
+
readonly locations: readonly string[];
|
|
3086
|
+
}
|
|
3087
|
+
/**
|
|
3088
|
+
* Options for bundle size estimation.
|
|
3089
|
+
*/
|
|
3090
|
+
interface BundleEstimatorOptions {
|
|
3091
|
+
/** Include node_modules size estimates */
|
|
3092
|
+
readonly includeNodeModules?: boolean;
|
|
3093
|
+
/** Maximum files to analyze (for performance) */
|
|
3094
|
+
readonly maxFiles?: number;
|
|
3095
|
+
/** Minification ratio estimate (0-1) */
|
|
3096
|
+
readonly minificationRatio?: number;
|
|
3097
|
+
/** Gzip ratio estimate (0-1) */
|
|
3098
|
+
readonly gzipRatio?: number;
|
|
3099
|
+
/** Size threshold for "large file" warnings (bytes) */
|
|
3100
|
+
readonly largeFileThreshold?: number;
|
|
3101
|
+
/** Size threshold for "large dependency" warnings (bytes) */
|
|
3102
|
+
readonly largeDependencyThreshold?: number;
|
|
3103
|
+
}
|
|
3104
|
+
/**
|
|
3105
|
+
* Estimates bundle size for source files in a package.
|
|
3106
|
+
*/
|
|
3107
|
+
declare function estimatePackageBundleSize(pkg: WorkspacePackage, importResults: readonly ImportExtractionResult[], options?: BundleEstimatorOptions): Promise<PackageBundleStats>;
|
|
3108
|
+
/**
|
|
3109
|
+
* Estimates the size of a single source file.
|
|
3110
|
+
*/
|
|
3111
|
+
declare function estimateFileSize(filePath: string, options?: BundleEstimatorOptions): Promise<BundleSizeEstimate | null>;
|
|
3112
|
+
/**
|
|
3113
|
+
* Estimates the size contribution of an external dependency.
|
|
3114
|
+
*/
|
|
3115
|
+
declare function estimateDependencySize(packageName: string): DependencySizeEstimate;
|
|
3116
|
+
/**
|
|
3117
|
+
* Identifies files that exceed the large file threshold.
|
|
3118
|
+
*/
|
|
3119
|
+
declare function findLargeFiles(stats: PackageBundleStats, threshold?: number): readonly BundleSizeEstimate[];
|
|
3120
|
+
/**
|
|
3121
|
+
* Identifies dependencies that exceed the large dependency threshold.
|
|
3122
|
+
*/
|
|
3123
|
+
declare function findLargeDependencies(stats: PackageBundleStats, threshold?: number): readonly DependencySizeEstimate[];
|
|
3124
|
+
/**
|
|
3125
|
+
* Calculates the estimated tree-shaking savings for a file.
|
|
3126
|
+
*
|
|
3127
|
+
* Files that only use a subset of exports from large modules
|
|
3128
|
+
* can benefit significantly from tree-shaking.
|
|
3129
|
+
*/
|
|
3130
|
+
declare function estimateTreeShakingSavings(imports: readonly ExtractedImport[]): TreeShakingSavingsEstimate;
|
|
3131
|
+
/**
|
|
3132
|
+
* Estimate of potential tree-shaking savings.
|
|
3133
|
+
*/
|
|
3134
|
+
interface TreeShakingSavingsEstimate {
|
|
3135
|
+
/** Total potential bytes saved */
|
|
3136
|
+
readonly potentialSavings: number;
|
|
3137
|
+
/** Imports that could be optimized */
|
|
3138
|
+
readonly optimizableImports: readonly OptimizableImport[];
|
|
3139
|
+
/** Whether any optimizations are available */
|
|
3140
|
+
readonly hasPotentialOptimizations: boolean;
|
|
3141
|
+
}
|
|
3142
|
+
/**
|
|
3143
|
+
* An import that could be optimized for better tree-shaking.
|
|
3144
|
+
*/
|
|
3145
|
+
interface OptimizableImport {
|
|
3146
|
+
/** The module specifier */
|
|
3147
|
+
readonly moduleSpecifier: string;
|
|
3148
|
+
/** Current import style */
|
|
3149
|
+
readonly currentImportStyle: 'namespace' | 'default' | 'side-effect';
|
|
3150
|
+
/** Suggested import style */
|
|
3151
|
+
readonly suggestedImportStyle: 'named' | 'dynamic';
|
|
3152
|
+
/** Estimated bytes saved */
|
|
3153
|
+
readonly estimatedSavings: number;
|
|
3154
|
+
/** Line number */
|
|
3155
|
+
readonly line: number;
|
|
3156
|
+
/** Column number */
|
|
3157
|
+
readonly column: number;
|
|
3158
|
+
}
|
|
3159
|
+
/**
|
|
3160
|
+
* Formats a byte size as a human-readable string.
|
|
3161
|
+
*/
|
|
3162
|
+
declare function formatBytes(bytes: number): string;
|
|
3163
|
+
|
|
3164
|
+
/**
|
|
3165
|
+
* Report generator interface and base types for workspace analysis output.
|
|
3166
|
+
*
|
|
3167
|
+
* Defines the contract for reporters that format analysis results into
|
|
3168
|
+
* various output formats (JSON, Markdown, console, etc.).
|
|
3169
|
+
*/
|
|
3170
|
+
|
|
3171
|
+
/**
|
|
3172
|
+
* Supported output formats for analysis reports.
|
|
3173
|
+
*/
|
|
3174
|
+
type ReportFormat = 'json' | 'markdown' | 'console';
|
|
3175
|
+
/**
|
|
3176
|
+
* Options for configuring report generation.
|
|
3177
|
+
*/
|
|
3178
|
+
interface ReportOptions {
|
|
3179
|
+
/** Minimum severity level to include in the report */
|
|
3180
|
+
readonly minSeverity?: Severity;
|
|
3181
|
+
/** Categories of issues to include (empty means all) */
|
|
3182
|
+
readonly categories?: readonly IssueCategory[];
|
|
3183
|
+
/** Whether to include file location details (line/column numbers) */
|
|
3184
|
+
readonly includeLocation?: boolean;
|
|
3185
|
+
/** Whether to include fix suggestions */
|
|
3186
|
+
readonly includeSuggestions?: boolean;
|
|
3187
|
+
/** Whether to group issues by file, category, or severity */
|
|
3188
|
+
readonly groupBy?: 'file' | 'category' | 'severity' | 'none';
|
|
3189
|
+
/** Whether to include summary statistics */
|
|
3190
|
+
readonly includeSummary?: boolean;
|
|
3191
|
+
/** Output file path (if writing to file) */
|
|
3192
|
+
readonly outputPath?: string;
|
|
3193
|
+
/** Whether to use colors in output (for console reporter) */
|
|
3194
|
+
readonly colors?: boolean;
|
|
3195
|
+
/** Maximum number of issues to display per group */
|
|
3196
|
+
readonly maxIssuesPerGroup?: number;
|
|
3197
|
+
/** Whether to include metadata in output */
|
|
3198
|
+
readonly includeMetadata?: boolean;
|
|
3199
|
+
}
|
|
3200
|
+
/**
|
|
3201
|
+
* Grouped issues organized by a specific key.
|
|
3202
|
+
*/
|
|
3203
|
+
interface GroupedIssues {
|
|
3204
|
+
/** The grouping key (file path, category name, or severity level) */
|
|
3205
|
+
readonly key: string;
|
|
3206
|
+
/** Human-readable label for the group */
|
|
3207
|
+
readonly label: string;
|
|
3208
|
+
/** Issues in this group */
|
|
3209
|
+
readonly issues: readonly Issue[];
|
|
3210
|
+
/** Number of issues in this group */
|
|
3211
|
+
readonly count: number;
|
|
3212
|
+
}
|
|
3213
|
+
/**
|
|
3214
|
+
* Summary statistics for report output.
|
|
3215
|
+
*/
|
|
3216
|
+
interface ReportSummary {
|
|
3217
|
+
/** Total number of issues */
|
|
3218
|
+
readonly totalIssues: number;
|
|
3219
|
+
/** Issues by severity */
|
|
3220
|
+
readonly bySeverity: Readonly<Record<Severity, number>>;
|
|
3221
|
+
/** Issues by category */
|
|
3222
|
+
readonly byCategory: Readonly<Record<IssueCategory, number>>;
|
|
3223
|
+
/** Number of packages analyzed */
|
|
3224
|
+
readonly packagesAnalyzed: number;
|
|
3225
|
+
/** Number of files analyzed */
|
|
3226
|
+
readonly filesAnalyzed: number;
|
|
3227
|
+
/** Duration in milliseconds */
|
|
3228
|
+
readonly durationMs: number;
|
|
3229
|
+
/** Number of files with issues */
|
|
3230
|
+
readonly filesWithIssues: number;
|
|
3231
|
+
/** Highest severity level found */
|
|
3232
|
+
readonly highestSeverity: Severity | null;
|
|
3233
|
+
}
|
|
3234
|
+
/**
|
|
3235
|
+
* Reporter interface that all report generators must implement.
|
|
3236
|
+
*
|
|
3237
|
+
* @example
|
|
3238
|
+
* ```ts
|
|
3239
|
+
* const jsonReporter = createJsonReporter()
|
|
3240
|
+
* const report = jsonReporter.generate(analysisResult)
|
|
3241
|
+
* await fs.writeFile('report.json', report)
|
|
3242
|
+
* ```
|
|
3243
|
+
*/
|
|
3244
|
+
interface Reporter {
|
|
3245
|
+
/** Unique identifier for this reporter */
|
|
3246
|
+
readonly id: ReportFormat;
|
|
3247
|
+
/** Human-readable name for this reporter */
|
|
3248
|
+
readonly name: string;
|
|
3249
|
+
/** Generate a report string from analysis results */
|
|
3250
|
+
readonly generate: (result: AnalysisResult, options?: ReportOptions) => string;
|
|
3251
|
+
/** Stream report output to a writable stream (for large reports) */
|
|
3252
|
+
readonly stream?: (result: AnalysisResult, write: (chunk: string) => void, options?: ReportOptions) => void;
|
|
3253
|
+
}
|
|
3254
|
+
/**
|
|
3255
|
+
* Factory function type for creating reporter instances.
|
|
3256
|
+
*/
|
|
3257
|
+
type ReporterFactory = (options?: ReportOptions) => Reporter;
|
|
3258
|
+
/**
|
|
3259
|
+
* Default report options.
|
|
3260
|
+
*/
|
|
3261
|
+
declare const DEFAULT_REPORT_OPTIONS: Required<Omit<ReportOptions, 'outputPath' | 'categories' | 'minSeverity'>>;
|
|
3262
|
+
/**
|
|
3263
|
+
* Severity display configuration for consistent formatting.
|
|
3264
|
+
*/
|
|
3265
|
+
declare const SEVERITY_CONFIG: Readonly<Record<Severity, {
|
|
3266
|
+
label: string;
|
|
3267
|
+
emoji: string;
|
|
3268
|
+
color: string;
|
|
3269
|
+
priority: number;
|
|
3270
|
+
}>>;
|
|
3271
|
+
/**
|
|
3272
|
+
* Category display configuration for consistent formatting.
|
|
3273
|
+
*/
|
|
3274
|
+
declare const CATEGORY_CONFIG: Readonly<Record<IssueCategory, {
|
|
3275
|
+
label: string;
|
|
3276
|
+
emoji: string;
|
|
3277
|
+
description: string;
|
|
3278
|
+
}>>;
|
|
3279
|
+
/**
|
|
3280
|
+
* Filter issues based on report options.
|
|
3281
|
+
*/
|
|
3282
|
+
declare function filterIssuesForReport(issues: readonly Issue[], options: ReportOptions): readonly Issue[];
|
|
3283
|
+
/**
|
|
3284
|
+
* Group issues by the specified key.
|
|
3285
|
+
*/
|
|
3286
|
+
declare function groupIssues(issues: readonly Issue[], groupBy: ReportOptions['groupBy']): readonly GroupedIssues[];
|
|
3287
|
+
/**
|
|
3288
|
+
* Calculate summary statistics from analysis results.
|
|
3289
|
+
*/
|
|
3290
|
+
declare function calculateSummary(result: AnalysisResult): ReportSummary;
|
|
3291
|
+
/**
|
|
3292
|
+
* Format a file location for display.
|
|
3293
|
+
*/
|
|
3294
|
+
declare function formatLocation(location: Issue['location'], options?: {
|
|
3295
|
+
includeColumn?: boolean;
|
|
3296
|
+
}): string;
|
|
3297
|
+
/**
|
|
3298
|
+
* Format duration for human-readable display.
|
|
3299
|
+
*/
|
|
3300
|
+
declare function formatDuration(ms: number): string;
|
|
3301
|
+
/**
|
|
3302
|
+
* Truncate text to a maximum length with ellipsis.
|
|
3303
|
+
*/
|
|
3304
|
+
declare function truncateText(text: string, maxLength: number): string;
|
|
3305
|
+
/**
|
|
3306
|
+
* Get relative path from workspace root.
|
|
3307
|
+
*/
|
|
3308
|
+
declare function getRelativePath(filePath: string, workspacePath: string): string;
|
|
3309
|
+
|
|
3310
|
+
/**
|
|
3311
|
+
* Console reporter for terminal output with colors and formatting.
|
|
3312
|
+
*
|
|
3313
|
+
* Generates colorful terminal output using consola and @clack/prompts
|
|
3314
|
+
* for interactive analysis feedback and CI/CD integration.
|
|
3315
|
+
*/
|
|
3316
|
+
|
|
3317
|
+
/**
|
|
3318
|
+
* Options specific to console reporter.
|
|
3319
|
+
*/
|
|
3320
|
+
interface ConsoleReporterOptions extends ReportOptions {
|
|
3321
|
+
/** Whether to use colors (auto-detected by default) */
|
|
3322
|
+
readonly colors?: boolean;
|
|
3323
|
+
/** Whether to show verbose output with full descriptions */
|
|
3324
|
+
readonly verbose?: boolean;
|
|
3325
|
+
/** Whether to show compact output (one line per issue) */
|
|
3326
|
+
readonly compact?: boolean;
|
|
3327
|
+
/** Maximum width for text wrapping */
|
|
3328
|
+
readonly maxWidth?: number;
|
|
3329
|
+
/** Whether to use @clack/prompts styling */
|
|
3330
|
+
readonly useClack?: boolean;
|
|
3331
|
+
}
|
|
3332
|
+
/**
|
|
3333
|
+
* Create a console reporter instance.
|
|
3334
|
+
*
|
|
3335
|
+
* @example
|
|
3336
|
+
* ```ts
|
|
3337
|
+
* const reporter = createConsoleReporter({verbose: true})
|
|
3338
|
+
* reporter.generate(analysisResult) // Outputs to console
|
|
3339
|
+
* ```
|
|
3340
|
+
*/
|
|
3341
|
+
declare function createConsoleReporter(defaultOptions?: ConsoleReporterOptions): Reporter;
|
|
3342
|
+
|
|
3343
|
+
/**
|
|
3344
|
+
* JSON reporter for machine-readable analysis output.
|
|
3345
|
+
*
|
|
3346
|
+
* Generates structured JSON reports suitable for CI/CD integration,
|
|
3347
|
+
* programmatic processing, and data analysis tools.
|
|
3348
|
+
*/
|
|
3349
|
+
|
|
3350
|
+
/**
|
|
3351
|
+
* JSON report structure for serialization.
|
|
3352
|
+
*/
|
|
3353
|
+
interface JsonReport {
|
|
3354
|
+
/** Schema version for compatibility checking */
|
|
3355
|
+
readonly $schema?: string;
|
|
3356
|
+
/** Report metadata */
|
|
3357
|
+
readonly metadata: JsonReportMetadata;
|
|
3358
|
+
/** Summary statistics */
|
|
3359
|
+
readonly summary: ReportSummary;
|
|
3360
|
+
/** All issues (filtered based on options) */
|
|
3361
|
+
readonly issues: readonly JsonReportIssue[];
|
|
3362
|
+
/** Issues grouped by the specified key */
|
|
3363
|
+
readonly groupedIssues?: readonly JsonReportGroup[];
|
|
3364
|
+
}
|
|
3365
|
+
/**
|
|
3366
|
+
* Report metadata for provenance tracking.
|
|
3367
|
+
*/
|
|
3368
|
+
interface JsonReportMetadata {
|
|
3369
|
+
/** Report generation timestamp (ISO 8601) */
|
|
3370
|
+
readonly generatedAt: string;
|
|
3371
|
+
/** Analysis start timestamp (ISO 8601) */
|
|
3372
|
+
readonly analysisStartedAt: string;
|
|
3373
|
+
/** Analysis completion timestamp (ISO 8601) */
|
|
3374
|
+
readonly analysisCompletedAt: string;
|
|
3375
|
+
/** Workspace path that was analyzed */
|
|
3376
|
+
readonly workspacePath: string;
|
|
3377
|
+
/** Report options used for generation */
|
|
3378
|
+
readonly reportOptions: Partial<ReportOptions>;
|
|
3379
|
+
/** Analyzer version (if available) */
|
|
3380
|
+
readonly version?: string;
|
|
3381
|
+
}
|
|
3382
|
+
/**
|
|
3383
|
+
* Issue representation in JSON report.
|
|
3384
|
+
*/
|
|
3385
|
+
interface JsonReportIssue {
|
|
3386
|
+
/** Issue identifier */
|
|
3387
|
+
readonly id: string;
|
|
3388
|
+
/** Issue title */
|
|
3389
|
+
readonly title: string;
|
|
3390
|
+
/** Issue description */
|
|
3391
|
+
readonly description: string;
|
|
3392
|
+
/** Severity level */
|
|
3393
|
+
readonly severity: Issue['severity'];
|
|
3394
|
+
/** Issue category */
|
|
3395
|
+
readonly category: Issue['category'];
|
|
3396
|
+
/** File location */
|
|
3397
|
+
readonly location: JsonReportLocation;
|
|
3398
|
+
/** Related locations (for multi-file issues like circular imports) */
|
|
3399
|
+
readonly relatedLocations?: readonly JsonReportLocation[];
|
|
3400
|
+
/** Suggested fix */
|
|
3401
|
+
readonly suggestion?: string;
|
|
3402
|
+
/** Additional metadata */
|
|
3403
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
3404
|
+
}
|
|
3405
|
+
/**
|
|
3406
|
+
* Location representation in JSON report.
|
|
3407
|
+
*/
|
|
3408
|
+
interface JsonReportLocation {
|
|
3409
|
+
/** File path (relative to workspace root) */
|
|
3410
|
+
readonly file: string;
|
|
3411
|
+
/** Absolute file path */
|
|
3412
|
+
readonly absolutePath: string;
|
|
3413
|
+
/** Line number (1-indexed) */
|
|
3414
|
+
readonly line?: number;
|
|
3415
|
+
/** Column number (1-indexed) */
|
|
3416
|
+
readonly column?: number;
|
|
3417
|
+
/** End line number (1-indexed) */
|
|
3418
|
+
readonly endLine?: number;
|
|
3419
|
+
/** End column number (1-indexed) */
|
|
3420
|
+
readonly endColumn?: number;
|
|
3421
|
+
}
|
|
3422
|
+
/**
|
|
3423
|
+
* Grouped issues in JSON report.
|
|
3424
|
+
*/
|
|
3425
|
+
interface JsonReportGroup {
|
|
3426
|
+
/** Group key */
|
|
3427
|
+
readonly key: string;
|
|
3428
|
+
/** Group label */
|
|
3429
|
+
readonly label: string;
|
|
3430
|
+
/** Number of issues in group */
|
|
3431
|
+
readonly count: number;
|
|
3432
|
+
/** Issues in this group */
|
|
3433
|
+
readonly issues: readonly JsonReportIssue[];
|
|
3434
|
+
}
|
|
3435
|
+
/**
|
|
3436
|
+
* Options specific to JSON reporter.
|
|
3437
|
+
*/
|
|
3438
|
+
interface JsonReporterOptions extends ReportOptions {
|
|
3439
|
+
/** Whether to pretty-print JSON output */
|
|
3440
|
+
readonly prettyPrint?: boolean;
|
|
3441
|
+
/** Indentation size for pretty-printing (default: 2) */
|
|
3442
|
+
readonly indentation?: number;
|
|
3443
|
+
/** Whether to include grouped issues section */
|
|
3444
|
+
readonly includeGroupedIssues?: boolean;
|
|
3445
|
+
/** JSON schema URL for validation */
|
|
3446
|
+
readonly schemaUrl?: string;
|
|
3447
|
+
}
|
|
3448
|
+
/**
|
|
3449
|
+
* Create a JSON reporter instance.
|
|
3450
|
+
*
|
|
3451
|
+
* @example
|
|
3452
|
+
* ```ts
|
|
3453
|
+
* const reporter = createJsonReporter({prettyPrint: true})
|
|
3454
|
+
* const json = reporter.generate(analysisResult)
|
|
3455
|
+
* await fs.writeFile('report.json', json)
|
|
3456
|
+
* ```
|
|
3457
|
+
*/
|
|
3458
|
+
declare function createJsonReporter(defaultOptions?: JsonReporterOptions): Reporter;
|
|
3459
|
+
|
|
3460
|
+
/**
|
|
3461
|
+
* Markdown reporter for human-readable analysis output.
|
|
3462
|
+
*
|
|
3463
|
+
* Generates well-formatted Markdown reports suitable for GitHub issues,
|
|
3464
|
+
* pull request comments, documentation, and team review.
|
|
3465
|
+
*/
|
|
3466
|
+
|
|
3467
|
+
/**
|
|
3468
|
+
* Options specific to Markdown reporter.
|
|
3469
|
+
*/
|
|
3470
|
+
interface MarkdownReporterOptions extends ReportOptions {
|
|
3471
|
+
/** Whether to use GitHub-flavored Markdown features (checkboxes, alerts) */
|
|
3472
|
+
readonly githubFlavored?: boolean;
|
|
3473
|
+
/** Title for the report document */
|
|
3474
|
+
readonly title?: string;
|
|
3475
|
+
/** Whether to include table of contents */
|
|
3476
|
+
readonly includeTableOfContents?: boolean;
|
|
3477
|
+
/** Whether to use emoji in headers and status */
|
|
3478
|
+
readonly useEmoji?: boolean;
|
|
3479
|
+
/** Whether to use collapsible sections for issue details */
|
|
3480
|
+
readonly collapsibleDetails?: boolean;
|
|
3481
|
+
/** Maximum issues to show per group before truncating */
|
|
3482
|
+
readonly maxIssuesPerGroup?: number;
|
|
3483
|
+
}
|
|
3484
|
+
/**
|
|
3485
|
+
* Create a Markdown reporter instance.
|
|
3486
|
+
*
|
|
3487
|
+
* @example
|
|
3488
|
+
* ```ts
|
|
3489
|
+
* const reporter = createMarkdownReporter({githubFlavored: true})
|
|
3490
|
+
* const markdown = reporter.generate(analysisResult)
|
|
3491
|
+
* await fs.writeFile('report.md', markdown)
|
|
3492
|
+
* ```
|
|
3493
|
+
*/
|
|
3494
|
+
declare function createMarkdownReporter(defaultOptions?: MarkdownReporterOptions): Reporter;
|
|
3495
|
+
|
|
3496
|
+
/**
|
|
3497
|
+
* Built-in architectural rules for workspace analysis.
|
|
3498
|
+
*
|
|
3499
|
+
* Provides rules for detecting common architectural anti-patterns:
|
|
3500
|
+
* - Layer violations (cross-layer imports)
|
|
3501
|
+
* - Barrel export misuse (export * in application code)
|
|
3502
|
+
* - Public API validation (explicit exports)
|
|
3503
|
+
* - Side effects in module initialization
|
|
3504
|
+
* - Import path alias violations
|
|
3505
|
+
* - Package boundary enforcement
|
|
3506
|
+
*/
|
|
3507
|
+
|
|
3508
|
+
/**
|
|
3509
|
+
* Options for LayerViolationRule.
|
|
3510
|
+
*/
|
|
3511
|
+
interface LayerViolationRuleOptions extends RuleOptions {
|
|
3512
|
+
readonly options?: {
|
|
3513
|
+
/** Custom layer configuration */
|
|
3514
|
+
readonly layerConfig?: LayerConfiguration;
|
|
3515
|
+
/** Whether to report violations for unrecognized layers */
|
|
3516
|
+
readonly reportUnknownLayers?: boolean;
|
|
3517
|
+
};
|
|
3518
|
+
}
|
|
3519
|
+
declare const layerViolationRuleMetadata: RuleMetadata;
|
|
3520
|
+
/**
|
|
3521
|
+
* Creates a rule that detects layer boundary violations.
|
|
3522
|
+
*
|
|
3523
|
+
* @example
|
|
3524
|
+
* ```ts
|
|
3525
|
+
* const rule = createLayerViolationRule({
|
|
3526
|
+
* options: {
|
|
3527
|
+
* layerConfig: {
|
|
3528
|
+
* layers: [
|
|
3529
|
+
* {name: 'domain', allowedDependencies: []},
|
|
3530
|
+
* {name: 'application', allowedDependencies: ['domain']},
|
|
3531
|
+
* ],
|
|
3532
|
+
* patterns: [
|
|
3533
|
+
* {pattern: '**\/domain\/**', layer: 'domain'},
|
|
3534
|
+
* ],
|
|
3535
|
+
* },
|
|
3536
|
+
* },
|
|
3537
|
+
* })
|
|
3538
|
+
* ```
|
|
3539
|
+
*/
|
|
3540
|
+
declare function createLayerViolationRule(options?: LayerViolationRuleOptions): Rule;
|
|
3541
|
+
/**
|
|
3542
|
+
* Options for BarrelExportRule.
|
|
3543
|
+
*/
|
|
3544
|
+
interface BarrelExportRuleOptions extends RuleOptions {
|
|
3545
|
+
readonly options?: {
|
|
3546
|
+
/** Allow export * in these file patterns (e.g., index.ts in libs) */
|
|
3547
|
+
readonly allowedPatterns?: readonly string[];
|
|
3548
|
+
/** Whether to allow export * from workspace packages */
|
|
3549
|
+
readonly allowWorkspaceReexports?: boolean;
|
|
3550
|
+
};
|
|
3551
|
+
}
|
|
3552
|
+
declare const barrelExportRuleMetadata: RuleMetadata;
|
|
3553
|
+
/**
|
|
3554
|
+
* Creates a rule that detects export * (barrel export) misuse.
|
|
3555
|
+
*
|
|
3556
|
+
* @example
|
|
3557
|
+
* ```ts
|
|
3558
|
+
* const rule = createBarrelExportRule({
|
|
3559
|
+
* options: {
|
|
3560
|
+
* allowedPatterns: ['**\/index.ts'],
|
|
3561
|
+
* allowWorkspaceReexports: false,
|
|
3562
|
+
* },
|
|
3563
|
+
* })
|
|
3564
|
+
* ```
|
|
3565
|
+
*/
|
|
3566
|
+
declare function createBarrelExportRule(options?: BarrelExportRuleOptions): Rule;
|
|
3567
|
+
/**
|
|
3568
|
+
* Options for PublicApiRule.
|
|
3569
|
+
*/
|
|
3570
|
+
interface PublicApiRuleOptions extends RuleOptions {
|
|
3571
|
+
readonly options?: {
|
|
3572
|
+
/** Entry point files that define the public API */
|
|
3573
|
+
readonly entryPoints?: readonly string[];
|
|
3574
|
+
/** Require all exports to be re-exported from entry points */
|
|
3575
|
+
readonly requireReexport?: boolean;
|
|
3576
|
+
};
|
|
3577
|
+
}
|
|
3578
|
+
declare const publicApiRuleMetadata: RuleMetadata;
|
|
3579
|
+
/**
|
|
3580
|
+
* Creates a rule that validates public API surface definition.
|
|
3581
|
+
*
|
|
3582
|
+
* @example
|
|
3583
|
+
* ```ts
|
|
3584
|
+
* const rule = createPublicApiRule({
|
|
3585
|
+
* options: {
|
|
3586
|
+
* entryPoints: ['src/index.ts'],
|
|
3587
|
+
* requireReexport: true,
|
|
3588
|
+
* },
|
|
3589
|
+
* })
|
|
3590
|
+
* ```
|
|
3591
|
+
*/
|
|
3592
|
+
declare function createPublicApiRule(options?: PublicApiRuleOptions): Rule;
|
|
3593
|
+
/**
|
|
3594
|
+
* Options for SideEffectRule.
|
|
3595
|
+
*/
|
|
3596
|
+
interface SideEffectRuleOptions extends RuleOptions {
|
|
3597
|
+
readonly options?: {
|
|
3598
|
+
/** Allow side effects in these file patterns */
|
|
3599
|
+
readonly allowedPatterns?: readonly string[];
|
|
3600
|
+
/** Check for console.log/warn/error at module level */
|
|
3601
|
+
readonly checkConsoleCalls?: boolean;
|
|
3602
|
+
/** Check for assignments to global objects */
|
|
3603
|
+
readonly checkGlobalAssignments?: boolean;
|
|
3604
|
+
};
|
|
3605
|
+
}
|
|
3606
|
+
declare const sideEffectRuleMetadata: RuleMetadata;
|
|
3607
|
+
/**
|
|
3608
|
+
* Creates a rule that detects side effects at module initialization.
|
|
3609
|
+
*
|
|
3610
|
+
* @example
|
|
3611
|
+
* ```ts
|
|
3612
|
+
* const rule = createSideEffectRule({
|
|
3613
|
+
* options: {
|
|
3614
|
+
* allowedPatterns: ['**\/polyfills.ts'],
|
|
3615
|
+
* checkConsoleCalls: true,
|
|
3616
|
+
* },
|
|
3617
|
+
* })
|
|
3618
|
+
* ```
|
|
3619
|
+
*/
|
|
3620
|
+
declare function createSideEffectRule(options?: SideEffectRuleOptions): Rule;
|
|
3621
|
+
/**
|
|
3622
|
+
* Options for PathAliasRule.
|
|
3623
|
+
*/
|
|
3624
|
+
interface PathAliasRuleOptions extends RuleOptions {
|
|
3625
|
+
readonly options?: {
|
|
3626
|
+
/** Require path aliases for deep imports */
|
|
3627
|
+
readonly requireAliasForDeepImports?: boolean;
|
|
3628
|
+
/** Depth threshold for requiring aliases */
|
|
3629
|
+
readonly deepImportThreshold?: number;
|
|
3630
|
+
};
|
|
3631
|
+
}
|
|
3632
|
+
declare const pathAliasRuleMetadata: RuleMetadata;
|
|
3633
|
+
/**
|
|
3634
|
+
* Creates a rule that validates import path aliases against tsconfig.
|
|
3635
|
+
*
|
|
3636
|
+
* @example
|
|
3637
|
+
* ```ts
|
|
3638
|
+
* const rule = createPathAliasRule({
|
|
3639
|
+
* options: {
|
|
3640
|
+
* requireAliasForDeepImports: true,
|
|
3641
|
+
* deepImportThreshold: 3,
|
|
3642
|
+
* },
|
|
3643
|
+
* })
|
|
3644
|
+
* ```
|
|
3645
|
+
*/
|
|
3646
|
+
declare function createPathAliasRule(options?: PathAliasRuleOptions): Rule;
|
|
3647
|
+
/**
|
|
3648
|
+
* Options for PackageBoundaryRule.
|
|
3649
|
+
*/
|
|
3650
|
+
interface PackageBoundaryRuleOptions extends RuleOptions {
|
|
3651
|
+
readonly options?: {
|
|
3652
|
+
/** Allowed cross-package import patterns */
|
|
3653
|
+
readonly allowedCrossPackagePatterns?: readonly string[];
|
|
3654
|
+
/** Packages that can be imported from anywhere */
|
|
3655
|
+
readonly sharedPackages?: readonly string[];
|
|
3656
|
+
/** Enforce importing only from package entry points */
|
|
3657
|
+
readonly enforceEntryPointImports?: boolean;
|
|
3658
|
+
};
|
|
3659
|
+
}
|
|
3660
|
+
declare const packageBoundaryRuleMetadata: RuleMetadata;
|
|
3661
|
+
/**
|
|
3662
|
+
* Creates a rule that enforces monorepo package boundaries.
|
|
3663
|
+
*
|
|
3664
|
+
* @example
|
|
3665
|
+
* ```ts
|
|
3666
|
+
* const rule = createPackageBoundaryRule({
|
|
3667
|
+
* options: {
|
|
3668
|
+
* sharedPackages: ['@bfra.me/es', '@bfra.me/tsconfig'],
|
|
3669
|
+
* enforceEntryPointImports: true,
|
|
3670
|
+
* },
|
|
3671
|
+
* })
|
|
3672
|
+
* ```
|
|
3673
|
+
*/
|
|
3674
|
+
declare function createPackageBoundaryRule(options?: PackageBoundaryRuleOptions): Rule;
|
|
3675
|
+
|
|
3676
|
+
/**
|
|
3677
|
+
* Pattern matching utilities for glob-style file path matching.
|
|
3678
|
+
*
|
|
3679
|
+
* Provides simple glob pattern matching supporting ** (any path segments)
|
|
3680
|
+
* and * (single segment) without external dependencies.
|
|
3681
|
+
*/
|
|
3682
|
+
/**
|
|
3683
|
+
* Matches a file path against a glob pattern.
|
|
3684
|
+
*
|
|
3685
|
+
* Supported patterns:
|
|
3686
|
+
* - `**` matches any number of path segments
|
|
3687
|
+
* - `*` matches any characters except path separator
|
|
3688
|
+
*/
|
|
3689
|
+
declare function matchPattern(filePath: string, pattern: string): boolean;
|
|
3690
|
+
/**
|
|
3691
|
+
* Checks if a file path matches any of the given patterns.
|
|
3692
|
+
*/
|
|
3693
|
+
declare function matchAnyPattern(filePath: string, patterns: readonly string[]): boolean;
|
|
3694
|
+
/**
|
|
3695
|
+
* Normalizes a file path for consistent pattern matching.
|
|
3696
|
+
*
|
|
3697
|
+
* Converts backslashes to forward slashes for cross-platform compatibility.
|
|
3698
|
+
*/
|
|
3699
|
+
declare function normalizePath(filePath: string): string;
|
|
3700
|
+
|
|
3701
|
+
export { type AnalysisCache, type AnalysisChangeDetector, type AnalysisChangeDetectorOptions, type AnalysisContext$1 as AnalysisContext, type AnalysisOrchestrator, AnalysisProgress, AnalysisResult, type Analyzer, type AnalyzerError, type AnalyzerFactory, type AnalyzerMetadata, type AnalyzerOptions, type AnalyzerRegistration, type AnalyzerRegistry, type ArchitecturalAnalyzerOptions, BUILTIN_ANALYZER_IDS, BUILTIN_RULE_IDS, type BarrelExportRuleOptions, type BuildConfigAnalyzerOptions, type BundleEstimatorOptions, type BundleSizeEstimate, CACHE_SCHEMA_VERSION, CATEGORY_CONFIG, CONFIG_FILE_PATTERNS, type CacheError, type CacheErrorCode, type CacheManager, type CacheManagerOptions, type CacheMetadata, type CacheOptions, type CacheStatistics, type CacheValidationResult, type CachedFileAnalysis, type CachedFileState, type CachedPackageAnalysis, type CircularImportAnalyzerOptions, type CircularImportStats, type CodeFingerprint, type ConfigConsistencyAnalyzerOptions, type ConfigError, type ConfigErrorCode, type ConfigLoadError, type ConfigLoadErrorCode, type ConfigLoadResult, type ConsoleReporterOptions, type CycleEdge, type CycleNode, type CycleVisualization, DEFAULT_ANALYZER_CONFIG, DEFAULT_CACHE_OPTIONS, DEFAULT_CONCURRENCY, DEFAULT_EXCLUDE_PATTERNS, DEFAULT_INCLUDE_PATTERNS, DEFAULT_INCREMENTAL_OPTIONS, DEFAULT_LAYER_CONFIG, DEFAULT_PACKAGE_PATTERNS, DEFAULT_REPORT_OPTIONS, DEFAULT_WORKSPACE_OPTIONS, type DeadCodeAnalyzerOptions, type DeadCodeStats, type DependencyCycle, type DependencyEdge, type DependencyGraph, type DependencyGraphOptions, type DependencyNode, type DependencySizeEstimate, type DuplicateCodeAnalyzerOptions, type DuplicateDependencyAnalyzerOptions, type DuplicateDependencyStats, type DuplicatePattern, type EslintConfigAnalyzerOptions, type ExportedSymbol, type ExportsFieldAnalyzerOptions, type ExtractedImport, type GraphStatistics, type GroupedIssues, type ImportExtractionResult, type ImportExtractorOptions, type ImportType, type IncrementalAnalysisContext, type IncrementalAnalysisError, type IncrementalAnalysisErrorCode, type IncrementalAnalysisOptions, type IncrementalAnalysisResult, type IncrementalAnalyzer, Issue, IssueCategory, IssueLocation, type JsonReport, type JsonReportGroup, type JsonReportIssue, type JsonReportLocation, type JsonReportMetadata, type JsonReporterOptions, type LargeDependencyAnalyzerOptions, type LayerConfiguration, type LayerDefinition, type LayerPattern, type LayerViolationRuleOptions, type MarkdownReporterOptions, type MergedConfig, type OptimizableImport, type OrchestratorOptions, type PackageBoundaryRuleOptions, type PackageBundleStats, type PackageJsonAnalyzerOptions, type ParsedPackageJson, type ParsedTsConfig, type PathAliasRuleOptions, type PeerDependencyAnalyzerOptions, type PublicApiRuleOptions, type ReportFormat, type ReportOptions, type ReportSummary, type Reporter, type ReporterFactory, type Rule, type RuleContext, type RuleEngine, type RuleEngineError, type RuleFactory, type RuleMetadata, type RuleOptions, type RuleRegistration, type RuleResult, type RuleViolation, SEVERITY_CONFIG, type SafeParseResult, type ScanError, Severity, type SideEffectRuleOptions, type TreeShakingBlocker, type TreeShakingBlockerAnalyzerOptions, type TreeShakingBlockerType, type TreeShakingSavingsEstimate, type TsCompilerOptions, type TsProjectReference, type TsconfigAnalyzerOptions, type UnusedDependencyAnalyzerOptions, type VersionAlignmentAnalyzerOptions, type WorkspaceAnalyzerConfig, type WorkspaceFileHasher, type WorkspaceHasherOptions, type WorkspacePackage, type WorkspacePackageJson, type WorkspaceScanResult, type WorkspaceScannerOptions, aggregatePackageImports, analyzePackages, analyzeWorkspace, architecturalAnalyzerMetadata, barrelExportRuleMetadata, METADATA$6 as buildConfigAnalyzerMetadata, buildDependencyGraph, builtinAnalyzers, calculateSummary, circularImportAnalyzerMetadata, collectConfigFileStates, computeCycleStats, computeDeadCodeStats, computeDuplicateStats, computeGraphStatistics, METADATA$5 as configConsistencyAnalyzerMetadata, createAnalysisChangeDetector, createAnalyzerRegistry, createArchitecturalAnalyzer, createBarrelExportRule, createBuildConfigAnalyzer, createCacheManager, createCircularImportAnalyzer, createConfigConsistencyAnalyzer, createConsoleProgressCallback, createConsoleReporter, createDeadCodeAnalyzer, createDefaultRegistry, createDuplicateCodeAnalyzer, createDuplicateDependencyAnalyzer, createEmptyCache, createEslintConfigAnalyzer, createExportsFieldAnalyzer, createFileAnalysisEntry, createIncrementalAnalyzer, createIssue, createJsonReporter, createLargeDependencyAnalyzer, createLayerViolationRule, createMarkdownReporter, createOrchestrator, createPackageAnalysisEntry, createPackageBoundaryRule, createPackageJsonAnalyzer, createPathAliasRule, createPeerDependencyAnalyzer, createPublicApiRule, createRuleEngine, createSideEffectRule, createSilentProgressCallback, createTreeShakingBlockerAnalyzer, createTsconfigAnalyzer, createUnusedDependencyAnalyzer, createVersionAlignmentAnalyzer, createWorkspaceHasher, createWorkspaceScanner, deadCodeAnalyzerMetadata, defineConfig, duplicateCodeAnalyzerMetadata, duplicateDependencyAnalyzerMetadata, METADATA$4 as eslintConfigAnalyzerMetadata, estimateDependencySize, estimateFileSize, estimatePackageBundleSize, estimateTreeShakingSavings, METADATA$3 as exportsFieldAnalyzerMetadata, extractImports, filterIssues, filterIssuesForReport, filterPackagesByPattern, findConfigFile, findCycles, findLargeDependencies, findLargeFiles, formatBytes, formatDuration, formatLocation, generateCycleVisualization, getAllDependencies, getAllSourceFiles, getAnalyzerOptions, getDefaultConfig, getFileLayer, getKnownLargePackages, getPackageInfo, getPackageNameFromSpecifier, getPackageScope, getRelativePath, getSourceFile, getTransitiveDependencies, getTransitiveDependents, getUniqueDependencies, getUnscopedName, groupIssues, groupPackagesByScope, initializeCache, isJavaScriptFile, isLayerImportAllowed, isRelativeImport, isSourceFile, isTypeScriptFile, isWorkspacePackageImport, largeDependencyAnalyzerMetadata, layerViolationRuleMetadata, loadConfig, loadConfigFile, matchAnyPattern, matchPattern, meetsMinSeverity, mergeAnalyzerConfigs, mergeConfig, normalizePath, packageBoundaryRuleMetadata, METADATA$2 as packageJsonAnalyzerMetadata, parsePackageJson, parsePackageJsonContent, parseSourceFiles, parseTsConfig, parseTsConfigContent, parseWorkspaceAnalyzerConfig, pathAliasRuleMetadata, peerDependencyAnalyzerMetadata, publicApiRuleMetadata, resolveRelativeImport, resolveTsConfigExtends, safeParseAnalyzeOptions, shouldAnalyzeCategory, sideEffectRuleMetadata, treeShakingBlockerAnalyzerMetadata, truncateText, METADATA$1 as tsconfigAnalyzerMetadata, unusedDependencyAnalyzerMetadata, METADATA as versionAlignmentAnalyzerMetadata };
|