@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.
Files changed (73) hide show
  1. package/README.md +402 -0
  2. package/lib/chunk-4LSFAAZW.js +1 -0
  3. package/lib/chunk-JDF7DQ4V.js +27 -0
  4. package/lib/chunk-WOJ4C7N7.js +7122 -0
  5. package/lib/cli.d.ts +1 -0
  6. package/lib/cli.js +318 -0
  7. package/lib/index.d.ts +3701 -0
  8. package/lib/index.js +1262 -0
  9. package/lib/types/index.d.ts +146 -0
  10. package/lib/types/index.js +28 -0
  11. package/package.json +89 -0
  12. package/src/analyzers/analyzer.ts +201 -0
  13. package/src/analyzers/architectural-analyzer.ts +304 -0
  14. package/src/analyzers/build-config-analyzer.ts +334 -0
  15. package/src/analyzers/circular-import-analyzer.ts +463 -0
  16. package/src/analyzers/config-consistency-analyzer.ts +335 -0
  17. package/src/analyzers/dead-code-analyzer.ts +565 -0
  18. package/src/analyzers/duplicate-code-analyzer.ts +626 -0
  19. package/src/analyzers/duplicate-dependency-analyzer.ts +381 -0
  20. package/src/analyzers/eslint-config-analyzer.ts +281 -0
  21. package/src/analyzers/exports-field-analyzer.ts +324 -0
  22. package/src/analyzers/index.ts +388 -0
  23. package/src/analyzers/large-dependency-analyzer.ts +535 -0
  24. package/src/analyzers/package-json-analyzer.ts +349 -0
  25. package/src/analyzers/peer-dependency-analyzer.ts +275 -0
  26. package/src/analyzers/tree-shaking-analyzer.ts +623 -0
  27. package/src/analyzers/tsconfig-analyzer.ts +382 -0
  28. package/src/analyzers/unused-dependency-analyzer.ts +356 -0
  29. package/src/analyzers/version-alignment-analyzer.ts +308 -0
  30. package/src/api/analyze-workspace.ts +245 -0
  31. package/src/api/index.ts +11 -0
  32. package/src/cache/cache-manager.ts +495 -0
  33. package/src/cache/cache-schema.ts +247 -0
  34. package/src/cache/change-detector.ts +169 -0
  35. package/src/cache/file-hasher.ts +65 -0
  36. package/src/cache/index.ts +47 -0
  37. package/src/cli/commands/analyze.ts +240 -0
  38. package/src/cli/commands/index.ts +5 -0
  39. package/src/cli/index.ts +61 -0
  40. package/src/cli/types.ts +65 -0
  41. package/src/cli/ui.ts +213 -0
  42. package/src/cli.ts +9 -0
  43. package/src/config/defaults.ts +183 -0
  44. package/src/config/index.ts +81 -0
  45. package/src/config/loader.ts +270 -0
  46. package/src/config/merger.ts +229 -0
  47. package/src/config/schema.ts +263 -0
  48. package/src/core/incremental-analyzer.ts +462 -0
  49. package/src/core/index.ts +34 -0
  50. package/src/core/orchestrator.ts +416 -0
  51. package/src/graph/dependency-graph.ts +408 -0
  52. package/src/graph/index.ts +19 -0
  53. package/src/index.ts +417 -0
  54. package/src/parser/config-parser.ts +491 -0
  55. package/src/parser/import-extractor.ts +340 -0
  56. package/src/parser/index.ts +54 -0
  57. package/src/parser/typescript-parser.ts +95 -0
  58. package/src/performance/bundle-estimator.ts +444 -0
  59. package/src/performance/index.ts +27 -0
  60. package/src/reporters/console-reporter.ts +355 -0
  61. package/src/reporters/index.ts +49 -0
  62. package/src/reporters/json-reporter.ts +273 -0
  63. package/src/reporters/markdown-reporter.ts +349 -0
  64. package/src/reporters/reporter.ts +399 -0
  65. package/src/rules/builtin-rules.ts +709 -0
  66. package/src/rules/index.ts +52 -0
  67. package/src/rules/rule-engine.ts +409 -0
  68. package/src/scanner/index.ts +18 -0
  69. package/src/scanner/workspace-scanner.ts +403 -0
  70. package/src/types/index.ts +176 -0
  71. package/src/types/result.ts +19 -0
  72. package/src/utils/index.ts +7 -0
  73. package/src/utils/pattern-matcher.ts +48 -0
@@ -0,0 +1,245 @@
1
+ /**
2
+ * Main public API for workspace analysis.
3
+ *
4
+ * Provides the `analyzeWorkspace()` function as the primary entry point
5
+ * for programmatic workspace analysis.
6
+ */
7
+
8
+ import type {MergedConfig} from '../config/merger'
9
+ import type {AnalysisProgress, AnalysisResult} from '../types/index'
10
+ import type {Result} from '../types/result'
11
+
12
+ import path from 'node:path'
13
+
14
+ import {loadConfig} from '../config/loader'
15
+ import {mergeConfig} from '../config/merger'
16
+ import {createOrchestrator, type OrchestratorError} from '../core/orchestrator'
17
+ import {err, ok} from '../types/result'
18
+
19
+ /**
20
+ * Options for the analyzeWorkspace function.
21
+ */
22
+ export interface AnalyzeWorkspaceOptions {
23
+ /** Glob patterns for files to include */
24
+ readonly include?: readonly string[]
25
+ /** Glob patterns for files to exclude */
26
+ readonly exclude?: readonly string[]
27
+ /** Minimum severity level to report */
28
+ readonly minSeverity?: 'info' | 'warning' | 'error' | 'critical'
29
+ /** Categories of issues to check (empty means all) */
30
+ readonly categories?: readonly (
31
+ | 'configuration'
32
+ | 'dependency'
33
+ | 'architecture'
34
+ | 'performance'
35
+ | 'circular-import'
36
+ | 'unused-export'
37
+ | 'type-safety'
38
+ )[]
39
+ /** Enable incremental analysis caching */
40
+ readonly cache?: boolean
41
+ /** Custom rules configuration */
42
+ readonly rules?: Record<string, unknown>
43
+ /** Glob patterns for package locations */
44
+ readonly packagePatterns?: readonly string[]
45
+ /** Maximum parallel analysis operations */
46
+ readonly concurrency?: number
47
+ /** Directory for analysis cache files */
48
+ readonly cacheDir?: string
49
+ /** Maximum cache age in milliseconds */
50
+ readonly maxCacheAge?: number
51
+ /** Hash algorithm for file content */
52
+ readonly hashAlgorithm?: 'sha256' | 'md5'
53
+ /** Path to workspace-analyzer.config.ts file */
54
+ readonly configPath?: string
55
+ /** Callback for progress reporting */
56
+ readonly onProgress?: (progress: AnalysisProgress) => void
57
+ /** Per-analyzer configuration */
58
+ readonly analyzers?: Record<
59
+ string,
60
+ {
61
+ enabled?: boolean
62
+ severity?: 'info' | 'warning' | 'error' | 'critical'
63
+ options?: Record<string, unknown>
64
+ }
65
+ >
66
+ /** Architectural analysis rules */
67
+ readonly architecture?: {
68
+ layers?: {
69
+ name: string
70
+ patterns: string[]
71
+ allowedImports: string[]
72
+ }[]
73
+ allowBarrelExports?: boolean | string[]
74
+ enforcePublicApi?: boolean
75
+ }
76
+ /** Enable verbose logging */
77
+ readonly verbose?: boolean
78
+ }
79
+
80
+ /**
81
+ * Error codes for workspace analysis.
82
+ */
83
+ export type AnalyzeWorkspaceErrorCode =
84
+ | 'CONFIG_ERROR'
85
+ | 'SCAN_ERROR'
86
+ | 'ANALYSIS_ERROR'
87
+ | 'INVALID_PATH'
88
+
89
+ /**
90
+ * Error that occurred during workspace analysis.
91
+ */
92
+ export interface AnalyzeWorkspaceError {
93
+ readonly code: AnalyzeWorkspaceErrorCode
94
+ readonly message: string
95
+ readonly cause?: unknown
96
+ }
97
+
98
+ /**
99
+ * Converts orchestrator error to analyze workspace error.
100
+ */
101
+ function toAnalyzeError(error: OrchestratorError): AnalyzeWorkspaceError {
102
+ const codeMap: Record<string, AnalyzeWorkspaceErrorCode> = {
103
+ SCAN_FAILED: 'SCAN_ERROR',
104
+ NO_PACKAGES: 'SCAN_ERROR',
105
+ ANALYSIS_FAILED: 'ANALYSIS_ERROR',
106
+ INVALID_CONFIG: 'CONFIG_ERROR',
107
+ }
108
+
109
+ return {
110
+ code: codeMap[error.code] ?? 'ANALYSIS_ERROR',
111
+ message: error.message,
112
+ cause: error.cause,
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Analyzes a workspace for configuration, dependency, and architectural issues.
118
+ *
119
+ * This is the main entry point for programmatic workspace analysis.
120
+ *
121
+ * @param workspacePath - Path to the workspace root directory
122
+ * @param options - Analysis options
123
+ * @returns Result containing analysis results or an error
124
+ *
125
+ * @example
126
+ * ```ts
127
+ * import {analyzeWorkspace} from '@bfra.me/workspace-analyzer'
128
+ *
129
+ * const result = await analyzeWorkspace('./my-monorepo', {
130
+ * minSeverity: 'warning',
131
+ * categories: ['dependency', 'architecture'],
132
+ * onProgress: (progress) => {
133
+ * console.log(`${progress.phase}: ${progress.processed}/${progress.total}`)
134
+ * },
135
+ * })
136
+ *
137
+ * if (result.success) {
138
+ * console.log(`Found ${result.data.summary.totalIssues} issues`)
139
+ * for (const issue of result.data.issues) {
140
+ * console.log(`[${issue.severity}] ${issue.title}`)
141
+ * }
142
+ * } else {
143
+ * console.error(`Analysis failed: ${result.error.message}`)
144
+ * }
145
+ * ```
146
+ */
147
+ export async function analyzeWorkspace(
148
+ workspacePath: string,
149
+ options: AnalyzeWorkspaceOptions = {},
150
+ ): Promise<Result<AnalysisResult, AnalyzeWorkspaceError>> {
151
+ const resolvedPath = path.resolve(workspacePath)
152
+
153
+ // Load configuration from file if not explicitly provided
154
+ const configResult = await loadConfig(resolvedPath, options.configPath)
155
+
156
+ if (!configResult.success) {
157
+ return err({
158
+ code: 'CONFIG_ERROR',
159
+ message: configResult.error.message,
160
+ cause: configResult.error.cause,
161
+ })
162
+ }
163
+
164
+ // Merge configuration from all sources
165
+ const mergedConfig: MergedConfig = mergeConfig(
166
+ configResult.data?.config,
167
+ options as Parameters<typeof mergeConfig>[1],
168
+ )
169
+
170
+ // Create orchestrator and run analysis
171
+ const orchestrator = createOrchestrator({
172
+ workspacePath: resolvedPath,
173
+ config: mergedConfig,
174
+ onProgress: options.onProgress,
175
+ verbose: options.verbose,
176
+ })
177
+
178
+ const result = await orchestrator.analyzeAll()
179
+
180
+ if (!result.success) {
181
+ return err(toAnalyzeError(result.error))
182
+ }
183
+
184
+ return ok(result.data)
185
+ }
186
+
187
+ /**
188
+ * Analyzes specific packages within a workspace.
189
+ *
190
+ * @param workspacePath - Path to the workspace root directory
191
+ * @param packageNames - Names of packages to analyze
192
+ * @param options - Analysis options
193
+ * @returns Result containing analysis results or an error
194
+ *
195
+ * @example
196
+ * ```ts
197
+ * import {analyzePackages} from '@bfra.me/workspace-analyzer'
198
+ *
199
+ * const result = await analyzePackages('./my-monorepo', ['@myorg/core', '@myorg/utils'])
200
+ *
201
+ * if (result.success) {
202
+ * console.log(`Analyzed ${result.data.summary.packagesAnalyzed} packages`)
203
+ * }
204
+ * ```
205
+ */
206
+ export async function analyzePackages(
207
+ workspacePath: string,
208
+ packageNames: readonly string[],
209
+ options: AnalyzeWorkspaceOptions = {},
210
+ ): Promise<Result<AnalysisResult, AnalyzeWorkspaceError>> {
211
+ const resolvedPath = path.resolve(workspacePath)
212
+
213
+ // Load configuration from file if not explicitly provided
214
+ const configResult = await loadConfig(resolvedPath, options.configPath)
215
+
216
+ if (!configResult.success) {
217
+ return err({
218
+ code: 'CONFIG_ERROR',
219
+ message: configResult.error.message,
220
+ cause: configResult.error.cause,
221
+ })
222
+ }
223
+
224
+ // Merge configuration from all sources
225
+ const mergedConfig: MergedConfig = mergeConfig(
226
+ configResult.data?.config,
227
+ options as Parameters<typeof mergeConfig>[1],
228
+ )
229
+
230
+ // Create orchestrator and run analysis
231
+ const orchestrator = createOrchestrator({
232
+ workspacePath: resolvedPath,
233
+ config: mergedConfig,
234
+ onProgress: options.onProgress,
235
+ verbose: options.verbose,
236
+ })
237
+
238
+ const result = await orchestrator.analyzePackages(packageNames)
239
+
240
+ if (!result.success) {
241
+ return err(toAnalyzeError(result.error))
242
+ }
243
+
244
+ return ok(result.data)
245
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Public API exports for workspace analyzer.
3
+ */
4
+
5
+ export {analyzePackages, analyzeWorkspace} from './analyze-workspace'
6
+
7
+ export type {
8
+ AnalyzeWorkspaceError,
9
+ AnalyzeWorkspaceErrorCode,
10
+ AnalyzeWorkspaceOptions,
11
+ } from './analyze-workspace'