@angular-modernizer/api 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 (108) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +507 -0
  3. package/dist/analysis/complexity-metrics-calculator.d.ts +99 -0
  4. package/dist/analysis/complexity-metrics-calculator.d.ts.map +1 -0
  5. package/dist/analysis/complexity-metrics-calculator.js +195 -0
  6. package/dist/analysis/complexity-metrics-calculator.js.map +1 -0
  7. package/dist/analysis/dependency-analyzer.d.ts +227 -0
  8. package/dist/analysis/dependency-analyzer.d.ts.map +1 -0
  9. package/dist/analysis/dependency-analyzer.js +451 -0
  10. package/dist/analysis/dependency-analyzer.js.map +1 -0
  11. package/dist/analysis/external-template-loader.d.ts +44 -0
  12. package/dist/analysis/external-template-loader.d.ts.map +1 -0
  13. package/dist/analysis/external-template-loader.js +69 -0
  14. package/dist/analysis/external-template-loader.js.map +1 -0
  15. package/dist/analysis/selector-mapper.d.ts +77 -0
  16. package/dist/analysis/selector-mapper.d.ts.map +1 -0
  17. package/dist/analysis/selector-mapper.js +146 -0
  18. package/dist/analysis/selector-mapper.js.map +1 -0
  19. package/dist/analysis/service-detector.d.ts +164 -0
  20. package/dist/analysis/service-detector.d.ts.map +1 -0
  21. package/dist/analysis/service-detector.js +231 -0
  22. package/dist/analysis/service-detector.js.map +1 -0
  23. package/dist/analysis/service-pattern-recognizer.d.ts +247 -0
  24. package/dist/analysis/service-pattern-recognizer.d.ts.map +1 -0
  25. package/dist/analysis/service-pattern-recognizer.js +444 -0
  26. package/dist/analysis/service-pattern-recognizer.js.map +1 -0
  27. package/dist/analysis/symbol-locator.d.ts +81 -0
  28. package/dist/analysis/symbol-locator.d.ts.map +1 -0
  29. package/dist/analysis/symbol-locator.js +128 -0
  30. package/dist/analysis/symbol-locator.js.map +1 -0
  31. package/dist/analysis/template-analyzer-usage.d.ts +144 -0
  32. package/dist/analysis/template-analyzer-usage.d.ts.map +1 -0
  33. package/dist/analysis/template-analyzer-usage.js +474 -0
  34. package/dist/analysis/template-analyzer-usage.js.map +1 -0
  35. package/dist/analysis/template-analyzer.d.ts +80 -0
  36. package/dist/analysis/template-analyzer.d.ts.map +1 -0
  37. package/dist/analysis/template-analyzer.js +146 -0
  38. package/dist/analysis/template-analyzer.js.map +1 -0
  39. package/dist/index.d.ts +23 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +22 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/investigation/angular-symbol-finder.d.ts +76 -0
  44. package/dist/investigation/angular-symbol-finder.d.ts.map +1 -0
  45. package/dist/investigation/angular-symbol-finder.js +199 -0
  46. package/dist/investigation/angular-symbol-finder.js.map +1 -0
  47. package/dist/investigation/call-graph-builder.d.ts +85 -0
  48. package/dist/investigation/call-graph-builder.d.ts.map +1 -0
  49. package/dist/investigation/call-graph-builder.js +196 -0
  50. package/dist/investigation/call-graph-builder.js.map +1 -0
  51. package/dist/investigation/codebase-searcher.d.ts +99 -0
  52. package/dist/investigation/codebase-searcher.d.ts.map +1 -0
  53. package/dist/investigation/codebase-searcher.js +201 -0
  54. package/dist/investigation/codebase-searcher.js.map +1 -0
  55. package/dist/investigation/stack-trace-parser.d.ts +70 -0
  56. package/dist/investigation/stack-trace-parser.d.ts.map +1 -0
  57. package/dist/investigation/stack-trace-parser.js +117 -0
  58. package/dist/investigation/stack-trace-parser.js.map +1 -0
  59. package/dist/investigation/type-resolver.d.ts +59 -0
  60. package/dist/investigation/type-resolver.d.ts.map +1 -0
  61. package/dist/investigation/type-resolver.js +111 -0
  62. package/dist/investigation/type-resolver.js.map +1 -0
  63. package/dist/investigation/usage-finder.d.ts +69 -0
  64. package/dist/investigation/usage-finder.d.ts.map +1 -0
  65. package/dist/investigation/usage-finder.js +132 -0
  66. package/dist/investigation/usage-finder.js.map +1 -0
  67. package/dist/metrics/complexity-metrics.d.ts +196 -0
  68. package/dist/metrics/complexity-metrics.d.ts.map +1 -0
  69. package/dist/metrics/complexity-metrics.js +445 -0
  70. package/dist/metrics/complexity-metrics.js.map +1 -0
  71. package/dist/public-api.d.ts +77 -0
  72. package/dist/public-api.d.ts.map +1 -0
  73. package/dist/public-api.js +50 -0
  74. package/dist/public-api.js.map +1 -0
  75. package/dist/transformation/import-manager.d.ts +276 -0
  76. package/dist/transformation/import-manager.d.ts.map +1 -0
  77. package/dist/transformation/import-manager.js +488 -0
  78. package/dist/transformation/import-manager.js.map +1 -0
  79. package/dist/transformation/ng-morph-adapter.d.ts +111 -0
  80. package/dist/transformation/ng-morph-adapter.d.ts.map +1 -0
  81. package/dist/transformation/ng-morph-adapter.js +179 -0
  82. package/dist/transformation/ng-morph-adapter.js.map +1 -0
  83. package/dist/transformation/ngmodule-manager.d.ts +145 -0
  84. package/dist/transformation/ngmodule-manager.d.ts.map +1 -0
  85. package/dist/transformation/ngmodule-manager.js +356 -0
  86. package/dist/transformation/ngmodule-manager.js.map +1 -0
  87. package/package.json +62 -0
  88. package/src/analysis/complexity-metrics-calculator.ts +253 -0
  89. package/src/analysis/dependency-analyzer.ts +720 -0
  90. package/src/analysis/external-template-loader.ts +79 -0
  91. package/src/analysis/selector-mapper.ts +186 -0
  92. package/src/analysis/service-detector.ts +280 -0
  93. package/src/analysis/service-pattern-recognizer.ts +545 -0
  94. package/src/analysis/symbol-locator.ts +170 -0
  95. package/src/analysis/template-analyzer-usage.ts +614 -0
  96. package/src/analysis/template-analyzer.ts +208 -0
  97. package/src/index.ts +51 -0
  98. package/src/investigation/angular-symbol-finder.ts +263 -0
  99. package/src/investigation/call-graph-builder.ts +298 -0
  100. package/src/investigation/codebase-searcher.ts +286 -0
  101. package/src/investigation/stack-trace-parser.ts +166 -0
  102. package/src/investigation/type-resolver.ts +144 -0
  103. package/src/investigation/usage-finder.ts +198 -0
  104. package/src/metrics/complexity-metrics.ts +617 -0
  105. package/src/public-api.ts +119 -0
  106. package/src/transformation/import-manager.ts +626 -0
  107. package/src/transformation/ng-morph-adapter.ts +252 -0
  108. package/src/transformation/ngmodule-manager.ts +450 -0
@@ -0,0 +1,451 @@
1
+ /**
2
+ * @angular-modernizer/api - Dependency Analyzer
3
+ *
4
+ * The "All-Knowing Cartographer" - builds comprehensive symbol maps for Angular modules.
5
+ * Recursively walks NgModule imports to create a complete map of available symbols.
6
+ *
7
+ * Philosophy: "Trust the Map"
8
+ * - Builds the definitive map of what's available in a module's scope
9
+ * - Handles the critical edge case: `` on setters with aliases
10
+ * - Plugins use this map to make intelligent decisions
11
+ */
12
+ /**
13
+ * Dependency Analyzer - extracts dependency relationships and builds symbol maps.
14
+ *
15
+ * This is the "All-Knowing Cartographer" that creates comprehensive maps of
16
+ * what's available in an NgModule's scope.
17
+ */
18
+ export class DependencyAnalyzer {
19
+ /**
20
+ * Analyze all dependencies from a source file.
21
+ * Extracts all named imports and creates dependency objects for each.
22
+ *
23
+ * @param sourceFile - The source file to analyze
24
+ * @returns Array of dependencies
25
+ */
26
+ analyzeDependencies(sourceFile) {
27
+ const filePath = sourceFile.getFilePath();
28
+ return sourceFile.getImportDeclarations().flatMap((importDecl) => {
29
+ const moduleSpecifier = importDecl.getModuleSpecifierValue();
30
+ return importDecl.getNamedImports().map((namedImport) => ({
31
+ from: filePath,
32
+ to: moduleSpecifier,
33
+ type: 'import',
34
+ symbol: namedImport.getName(),
35
+ }));
36
+ });
37
+ }
38
+ /**
39
+ * Check if a file depends on another file.
40
+ *
41
+ * @param sourceFile - The source file
42
+ * @param targetPath - The target file path
43
+ * @returns True if dependency exists
44
+ */
45
+ dependsOn(sourceFile, targetPath) {
46
+ const dependencies = this.analyzeDependencies(sourceFile);
47
+ return dependencies.some((dep) => dep.to === targetPath);
48
+ }
49
+ /**
50
+ * Build a comprehensive symbol map for an NgModule.
51
+ *
52
+ * This is the heart of the "Trust the Map" architecture.
53
+ * It creates the definitive map of what's available in a module's scope.
54
+ *
55
+ * @param moduleFile - The source file containing the NgModule
56
+ * @param project - Optional ts-morph Project to resolve symbols across files
57
+ * @returns Complete symbol map
58
+ */
59
+ buildSymbolMap(moduleFile, project) {
60
+ const symbolMap = {
61
+ declared: new Map(),
62
+ imported: new Map(),
63
+ exported: new Map(),
64
+ available: new Map(),
65
+ };
66
+ // Find the NgModule class
67
+ const moduleClass = this.findNgModuleClass(moduleFile);
68
+ if (!moduleClass) {
69
+ return symbolMap;
70
+ }
71
+ // Extract symbols from the @NgModule decorator
72
+ const decorator = this.findDecorator(moduleClass, 'NgModule');
73
+ if (!decorator) {
74
+ return symbolMap;
75
+ }
76
+ // Parse the decorator to find declarations, imports, exports
77
+ const decoratorText = decorator.getText();
78
+ // Extract declared symbols
79
+ const declarations = this.extractArrayProperty(decoratorText, 'declarations');
80
+ declarations.forEach((className) => {
81
+ let symbolInfo = this.extractSymbolInfo(moduleFile, className);
82
+ if (!symbolInfo && project) {
83
+ const foundFile = project
84
+ .getSourceFiles()
85
+ .find((sf) => this.extractSymbolInfo(sf, className));
86
+ symbolInfo = foundFile
87
+ ? this.extractSymbolInfo(foundFile, className)
88
+ : undefined;
89
+ }
90
+ if (symbolInfo) {
91
+ symbolMap.declared.set(className, symbolInfo);
92
+ symbolMap.available.set(className, symbolInfo);
93
+ }
94
+ });
95
+ // Extract imported symbols (from other modules)
96
+ const imports = this.extractArrayProperty(decoratorText, 'imports');
97
+ const knownModules = new Set(['CommonModule', 'FormsModule']);
98
+ imports.forEach((moduleName) => {
99
+ if (knownModules.has(moduleName)) {
100
+ const builtInSymbol = {
101
+ className: moduleName,
102
+ selectors: [],
103
+ inputs: [],
104
+ outputs: [],
105
+ type: 'module',
106
+ filePath: '@angular/common',
107
+ };
108
+ symbolMap.imported.set(moduleName, builtInSymbol);
109
+ symbolMap.available.set(moduleName, builtInSymbol);
110
+ }
111
+ if (project && !knownModules.has(moduleName)) {
112
+ const importedModuleSymbols = this.loadModuleExports(moduleName, project, moduleFile);
113
+ importedModuleSymbols.forEach((symbolInfo, symbolName) => {
114
+ symbolMap.imported.set(symbolName, symbolInfo);
115
+ symbolMap.available.set(symbolName, symbolInfo);
116
+ });
117
+ }
118
+ });
119
+ // Extract exported symbols
120
+ const exports = this.extractArrayProperty(decoratorText, 'exports');
121
+ exports.forEach((className) => {
122
+ const symbolInfo = symbolMap.declared.get(className) ?? symbolMap.imported.get(className);
123
+ if (symbolInfo) {
124
+ symbolMap.exported.set(className, symbolInfo);
125
+ }
126
+ });
127
+ return symbolMap;
128
+ }
129
+ /**
130
+ * Load exported symbols from an imported module.
131
+ * Recursively resolves module imports to build complete symbol map.
132
+ *
133
+ * @param moduleName - The module class name to load
134
+ * @param project - The ts-morph project
135
+ * @param _currentFile - The current source file (reserved for future use in resolving relative imports)
136
+ * @returns Map of exported symbols
137
+ */
138
+ loadModuleExports(moduleName, project, _currentFile) {
139
+ const exports = new Map();
140
+ const allSourceFiles = project.getSourceFiles();
141
+ // Find the module class across all source files
142
+ const moduleResult = allSourceFiles
143
+ .map((sf) => ({ file: sf, class: sf.getClass(moduleName) }))
144
+ .find(({ class: cls }) => cls && this.findDecorator(cls, 'NgModule'));
145
+ if (!moduleResult?.class) {
146
+ return exports;
147
+ }
148
+ const { file: moduleFile, class: moduleClass } = moduleResult;
149
+ // Get the @NgModule decorator
150
+ const decorator = this.findDecorator(moduleClass, 'NgModule');
151
+ if (!decorator) {
152
+ return exports;
153
+ }
154
+ // Extract exported symbols from the module
155
+ const exportedSymbols = this.extractArrayProperty(decorator.getText(), 'exports');
156
+ exportedSymbols.forEach((symbolName) => {
157
+ let symbolInfo = this.extractSymbolInfo(moduleFile, symbolName);
158
+ if (!symbolInfo) {
159
+ const foundFile = allSourceFiles.find((sf) => this.extractSymbolInfo(sf, symbolName));
160
+ symbolInfo = foundFile
161
+ ? this.extractSymbolInfo(foundFile, symbolName)
162
+ : undefined;
163
+ }
164
+ if (symbolInfo) {
165
+ exports.set(symbolName, symbolInfo);
166
+ }
167
+ });
168
+ return exports;
169
+ }
170
+ /**
171
+ * Get all transitive dependencies for a source file.
172
+ * Follows dependency chain recursively.
173
+ *
174
+ * @param sourceFile - The source file
175
+ * @param project - The ts-morph project
176
+ * @param visited - Set of already visited files (for cycle detection)
177
+ * @returns Array of all transitive dependencies
178
+ */
179
+ getTransitiveDependencies(sourceFile, project, visited = new Set()) {
180
+ const filePath = sourceFile.getFilePath();
181
+ // Prevent infinite recursion
182
+ if (visited.has(filePath)) {
183
+ return [];
184
+ }
185
+ visited.add(filePath);
186
+ const directDependencies = this.analyzeDependencies(sourceFile);
187
+ const localDeps = directDependencies.filter((dep) => dep.to.startsWith('.') || dep.to.startsWith('/'));
188
+ const transitiveDeps = localDeps.flatMap((dep) => {
189
+ const depPath = dep.to.replace(/^\.\//, '').replace(/\.ts$/, '');
190
+ const depSourceFile = project.getSourceFiles().find((sf) => {
191
+ const sfPath = sf.getFilePath();
192
+ return (sfPath.includes(depPath + '.ts') ||
193
+ sfPath.endsWith('/' + depPath + '.ts'));
194
+ });
195
+ return depSourceFile
196
+ ? this.getTransitiveDependencies(depSourceFile, project, visited)
197
+ : [];
198
+ });
199
+ return [...directDependencies, ...transitiveDeps];
200
+ }
201
+ /**
202
+ * Detect circular dependencies in a project.
203
+ *
204
+ * @param project - The ts-morph project
205
+ * @returns Array of circular dependency chains
206
+ */
207
+ detectCircularDependencies(project) {
208
+ const cycles = [];
209
+ const sourceFiles = project.getSourceFiles();
210
+ for (const sourceFile of sourceFiles) {
211
+ const filePath = sourceFile.getFilePath();
212
+ const visited = new Set();
213
+ const path = [];
214
+ this.detectCyclesFromFile(sourceFile, project, visited, path, cycles, filePath);
215
+ }
216
+ // Deduplicate cycles (same cycle can be found from different starting points)
217
+ return this.deduplicateCycles(cycles);
218
+ }
219
+ /**
220
+ * Detect cycles starting from a specific file.
221
+ * Recursively traverses local dependencies to find circular import chains.
222
+ * Severity based on cycle length: >3 files = error, ≤3 files = warning.
223
+ */
224
+ detectCyclesFromFile(sourceFile, project, visited, path, cycles, targetFile) {
225
+ const filePath = sourceFile.getFilePath();
226
+ // If we've returned to the target file, we found a cycle
227
+ if (path.length > 0 && filePath === targetFile) {
228
+ cycles.push({
229
+ cycle: [...path, filePath],
230
+ severity: path.length > 3 ? 'error' : 'warning',
231
+ });
232
+ return;
233
+ }
234
+ // Prevent infinite recursion on already visited paths
235
+ if (visited.has(filePath)) {
236
+ return;
237
+ }
238
+ visited.add(filePath);
239
+ path.push(filePath);
240
+ // Follow dependencies - filter to local project files only (not node_modules)
241
+ const localDeps = this.analyzeDependencies(sourceFile).filter((dep) => dep.to.startsWith('.') || dep.to.startsWith('/'));
242
+ localDeps.forEach((dep) => {
243
+ // Normalize import path: strip leading ./ and .ts extension
244
+ const depPath = dep.to.replace(/^\.\//, '').replace(/\.ts$/, '');
245
+ const depSourceFile = project.getSourceFiles().find((sf) => {
246
+ const sfPath = sf.getFilePath();
247
+ // Handle both relative imports with and without .ts extension
248
+ return (sfPath.includes(depPath + '.ts') ||
249
+ sfPath.endsWith('/' + depPath + '.ts'));
250
+ });
251
+ if (depSourceFile) {
252
+ // Recurse with fresh visited set and path copy to track independent branches
253
+ this.detectCyclesFromFile(depSourceFile, project, new Set(visited), [...path], cycles, targetFile);
254
+ }
255
+ });
256
+ }
257
+ /**
258
+ * Deduplicate cycle arrays (same cycle in different order).
259
+ * Example: [A→B→C→A] and [B→C→A→B] represent the same cycle.
260
+ * Uses sorted paths to create unique signatures for comparison.
261
+ */
262
+ deduplicateCycles(cycles) {
263
+ const seen = new Set();
264
+ return cycles.filter((item) => {
265
+ // Normalize cycle by sorting paths and creating unique signature
266
+ const sorted = [...item.cycle].sort();
267
+ const signature = sorted.join('->');
268
+ if (seen.has(signature)) {
269
+ return false;
270
+ }
271
+ seen.add(signature);
272
+ return true;
273
+ });
274
+ }
275
+ /**
276
+ * Extract comprehensive symbol information from a class.
277
+ * Identifies Angular artifact types (``, ``, ``) and extracts metadata.
278
+ *
279
+ * CRITICAL: Handles the edge case of `` on setters with aliases.
280
+ *
281
+ * @param sourceFile - The source file
282
+ * @param className - The class name to analyze
283
+ * @returns Symbol information or undefined
284
+ */
285
+ extractSymbolInfo(sourceFile, className) {
286
+ const classDecl = sourceFile.getClass(className);
287
+ if (!classDecl) {
288
+ return undefined;
289
+ }
290
+ const filePath = sourceFile.getFilePath();
291
+ // Map decorator types to extraction methods
292
+ const decoratorHandlers = [
293
+ { name: 'Component', extract: this.extractComponentInfo.bind(this) },
294
+ { name: 'Directive', extract: this.extractDirectiveInfo.bind(this) },
295
+ { name: 'Pipe', extract: this.extractPipeInfo.bind(this) },
296
+ ];
297
+ for (const { name, extract } of decoratorHandlers) {
298
+ const decorator = this.findDecorator(classDecl, name);
299
+ if (decorator) {
300
+ return extract(classDecl, decorator, filePath);
301
+ }
302
+ }
303
+ return undefined;
304
+ }
305
+ /**
306
+ * Extract component information including selectors and inputs.
307
+ */
308
+ extractComponentInfo(classDecl, decorator, filePath) {
309
+ const decoratorText = decorator.getText();
310
+ const selector = this.extractStringProperty(decoratorText, 'selector');
311
+ return {
312
+ className: classDecl.getName() ?? 'UnknownComponent',
313
+ selectors: selector ? [selector] : [],
314
+ inputs: this.extractInputs(classDecl),
315
+ outputs: this.extractOutputs(classDecl),
316
+ type: 'component',
317
+ filePath,
318
+ };
319
+ }
320
+ /**
321
+ * Extract directive information including selectors and inputs.
322
+ */
323
+ extractDirectiveInfo(classDecl, decorator, filePath) {
324
+ const decoratorText = decorator.getText();
325
+ const selector = this.extractStringProperty(decoratorText, 'selector');
326
+ // For attribute selectors like '[myDirective]', we want both forms
327
+ const selectors = [];
328
+ if (selector) {
329
+ selectors.push(selector);
330
+ // If it's an attribute selector, also add the bare name
331
+ const bareSelector = selector.replace(/^\[|\]$/g, '');
332
+ if (bareSelector !== selector) {
333
+ selectors.push(bareSelector);
334
+ }
335
+ }
336
+ return {
337
+ className: classDecl.getName() ?? 'UnknownDirective',
338
+ selectors,
339
+ inputs: this.extractInputs(classDecl),
340
+ outputs: this.extractOutputs(classDecl),
341
+ type: 'directive',
342
+ filePath,
343
+ };
344
+ }
345
+ /**
346
+ * Extract pipe information.
347
+ */
348
+ extractPipeInfo(classDecl, decorator, filePath) {
349
+ const decoratorText = decorator.getText();
350
+ const name = this.extractStringProperty(decoratorText, 'name');
351
+ return {
352
+ className: classDecl.getName() ?? 'UnknownPipe',
353
+ selectors: name ? [name] : [],
354
+ inputs: [],
355
+ outputs: [],
356
+ type: 'pipe',
357
+ filePath,
358
+ };
359
+ }
360
+ /**
361
+ * Extract all `` properties from a class.
362
+ *
363
+ * CRITICAL: Handles the edge case of `` on setters with aliases.
364
+ * Example: ``('customValue') set value(val: any) { ... }
365
+ * This should extract 'customValue', not 'value'.
366
+ */
367
+ extractInputs(classDecl) {
368
+ // Helper to extract decorated names with optional aliases
369
+ const extractDecorated = (nodes, decoratorName) => {
370
+ const results = [];
371
+ nodes.forEach((node) => {
372
+ const decorator = this.findDecorator(node, decoratorName);
373
+ if (decorator) {
374
+ const alias = this.extractDecoratorAlias(decorator);
375
+ results.push(alias ?? node.getName());
376
+ }
377
+ });
378
+ return results;
379
+ };
380
+ // Extract from properties, setters (CRITICAL for fixture test!), and getters
381
+ return [
382
+ ...extractDecorated(classDecl.getProperties(), 'Input'),
383
+ ...extractDecorated(classDecl.getSetAccessors(), 'Input'),
384
+ ...extractDecorated(classDecl.getGetAccessors(), 'Input'),
385
+ ];
386
+ }
387
+ /**
388
+ * Extract all `` properties from a class.
389
+ */
390
+ extractOutputs(classDecl) {
391
+ const outputs = [];
392
+ classDecl.getProperties().forEach((prop) => {
393
+ const outputDecorator = this.findDecorator(prop, 'Output');
394
+ if (outputDecorator) {
395
+ const alias = this.extractDecoratorAlias(outputDecorator);
396
+ outputs.push(alias ?? prop.getName());
397
+ }
398
+ });
399
+ return outputs;
400
+ }
401
+ /**
402
+ * Extract alias from a decorator.
403
+ * Example: ``('customValue') -> 'customValue'
404
+ */
405
+ extractDecoratorAlias(decorator) {
406
+ const args = decorator.getArguments();
407
+ const firstArg = args[0];
408
+ // Remove quotes from string literal if argument exists
409
+ return firstArg?.getText().replace(/^['"`]|['"`]$/g, '');
410
+ }
411
+ /**
412
+ * Find a decorator on a node by name.
413
+ */
414
+ findDecorator(node, name) {
415
+ const decorators = node.getDecorators();
416
+ return decorators.find((d) => d.getName() === name);
417
+ }
418
+ /**
419
+ * Find the NgModule class in a source file.
420
+ */
421
+ findNgModuleClass(sourceFile) {
422
+ const classes = sourceFile.getClasses();
423
+ return classes.find((cls) => this.findDecorator(cls, 'NgModule') !== undefined);
424
+ }
425
+ /**
426
+ * Extract a string property value from decorator text.
427
+ * Example: selector: 'app-root' -> 'app-root'
428
+ */
429
+ extractStringProperty(text, propertyName) {
430
+ const regex = new RegExp(`${propertyName}\\s*:\\s*['"\`]([^'"\`]+)['"\`]`);
431
+ const match = text.match(regex);
432
+ return match ? match[1] : undefined;
433
+ }
434
+ /**
435
+ * Extract an array property value from decorator text.
436
+ * Example: declarations: [Foo, Bar] -> ['Foo', 'Bar']
437
+ */
438
+ extractArrayProperty(text, propertyName) {
439
+ const regex = new RegExp(`${propertyName}\\s*:\\s*\\[([^\\]]*)\\]`);
440
+ const match = text.match(regex);
441
+ if (!match?.[1]) {
442
+ return [];
443
+ }
444
+ const arrayContent = match[1];
445
+ return arrayContent
446
+ .split(',')
447
+ .map((item) => item.trim())
448
+ .filter((item) => item.length > 0);
449
+ }
450
+ }
451
+ //# sourceMappingURL=dependency-analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency-analyzer.js","sourceRoot":"","sources":["../../src/analysis/dependency-analyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @angular-modernizer/api - External Template Loader
3
+ *
4
+ * Loads external Angular templates from templateUrl.
5
+ *
6
+ * Philosophy: "Support Both Inline and External"
7
+ * - Handles templateUrl: './component.html'
8
+ * - Resolves relative paths correctly
9
+ * - Graceful fallback on errors
10
+ */
11
+ /**
12
+ * External Template Loader - Loads templates from templateUrl.
13
+ *
14
+ * Supports both relative and absolute template paths.
15
+ */
16
+ export declare class ExternalTemplateLoader {
17
+ /**
18
+ * Load external template file.
19
+ *
20
+ * Handles templateUrl: './user.component.html'
21
+ *
22
+ * @param templateUrl - Template URL from `` metadata
23
+ * @param componentPath - Absolute path to the component file
24
+ * @returns Template content or empty string on error
25
+ */
26
+ loadExternalTemplate(templateUrl: string, componentPath: string): Promise<string>;
27
+ /**
28
+ * Check if a template path exists.
29
+ *
30
+ * @param templateUrl - Template URL from `` metadata
31
+ * @param componentPath - Absolute path to the component file
32
+ * @returns True if template file exists
33
+ */
34
+ templateExists(templateUrl: string, componentPath: string): Promise<boolean>;
35
+ /**
36
+ * Resolve template path from component path and templateUrl.
37
+ *
38
+ * @param templateUrl - Template URL from `` metadata
39
+ * @param componentPath - Absolute path to the component file
40
+ * @returns Absolute path to template file
41
+ */
42
+ resolveTemplatePath(templateUrl: string, componentPath: string): string;
43
+ }
44
+ //# sourceMappingURL=external-template-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-template-loader.d.ts","sourceRoot":"","sources":["../../src/analysis/external-template-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH;;;;GAIG;AACH,qBAAa,sBAAsB;IACjC;;;;;;;;OAQG;IACG,oBAAoB,CACxB,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,CAAC;IAelB;;;;;;OAMG;IACG,cAAc,CAClB,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,OAAO,CAAC;IAWnB;;;;;;OAMG;IACH,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM;CAGxE"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * @angular-modernizer/api - External Template Loader
3
+ *
4
+ * Loads external Angular templates from templateUrl.
5
+ *
6
+ * Philosophy: "Support Both Inline and External"
7
+ * - Handles templateUrl: './component.html'
8
+ * - Resolves relative paths correctly
9
+ * - Graceful fallback on errors
10
+ */
11
+ import * as path from 'node:path';
12
+ import * as fs from 'node:fs/promises';
13
+ /**
14
+ * External Template Loader - Loads templates from templateUrl.
15
+ *
16
+ * Supports both relative and absolute template paths.
17
+ */
18
+ export class ExternalTemplateLoader {
19
+ /**
20
+ * Load external template file.
21
+ *
22
+ * Handles templateUrl: './user.component.html'
23
+ *
24
+ * @param templateUrl - Template URL from `` metadata
25
+ * @param componentPath - Absolute path to the component file
26
+ * @returns Template content or empty string on error
27
+ */
28
+ async loadExternalTemplate(templateUrl, componentPath) {
29
+ // Resolve template path relative to component
30
+ const templatePath = path.resolve(path.dirname(componentPath), templateUrl);
31
+ try {
32
+ return await fs.readFile(templatePath, 'utf-8');
33
+ }
34
+ catch (error) {
35
+ const errorMessage = error instanceof Error ? error.message : String(error);
36
+ console.warn(` Failed to load template: ${templatePath}`);
37
+ console.warn(` Error: ${errorMessage}`);
38
+ return ''; // Conservative: no template = include all imports
39
+ }
40
+ }
41
+ /**
42
+ * Check if a template path exists.
43
+ *
44
+ * @param templateUrl - Template URL from `` metadata
45
+ * @param componentPath - Absolute path to the component file
46
+ * @returns True if template file exists
47
+ */
48
+ async templateExists(templateUrl, componentPath) {
49
+ const templatePath = path.resolve(path.dirname(componentPath), templateUrl);
50
+ try {
51
+ await fs.access(templatePath);
52
+ return true;
53
+ }
54
+ catch {
55
+ return false;
56
+ }
57
+ }
58
+ /**
59
+ * Resolve template path from component path and templateUrl.
60
+ *
61
+ * @param templateUrl - Template URL from `` metadata
62
+ * @param componentPath - Absolute path to the component file
63
+ * @returns Absolute path to template file
64
+ */
65
+ resolveTemplatePath(templateUrl, componentPath) {
66
+ return path.resolve(path.dirname(componentPath), templateUrl);
67
+ }
68
+ }
69
+ //# sourceMappingURL=external-template-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-template-loader.js","sourceRoot":"","sources":["../../src/analysis/external-template-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEvC;;;;GAIG;AACH,MAAM,OAAO,sBAAsB;IACjC;;;;;;;;OAQG;IACH,KAAK,CAAC,oBAAoB,CACxB,WAAmB,EACnB,aAAqB;QAErB,8CAA8C;QAC9C,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,WAAW,CAAC,CAAC;QAE5E,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAClD,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,MAAM,YAAY,GAChB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACzD,OAAO,CAAC,IAAI,CAAC,gCAAgC,YAAY,EAAE,CAAC,CAAC;YAC7D,OAAO,CAAC,IAAI,CAAC,cAAc,YAAY,EAAE,CAAC,CAAC;YAC3C,OAAO,EAAE,CAAC,CAAC,kDAAkD;QAC/D,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,cAAc,CAClB,WAAmB,EACnB,aAAqB;QAErB,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,WAAW,CAAC,CAAC;QAE5E,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YAC9B,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,mBAAmB,CAAC,WAAmB,EAAE,aAAqB;QAC5D,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,WAAW,CAAC,CAAC;IAChE,CAAC;CACF"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * @angular-modernizer/api - Selector Mapper
3
+ *
4
+ * Reusable selector-to-className mapping utility.
5
+ * Extracted from Phase 3's selector map caching for reuse across components.
6
+ *
7
+ * Philosophy: "Build Once, Use Everywhere"
8
+ * - O(n) initial build, O(1) lookups
9
+ * - Lazy initialization (only builds when first needed)
10
+ * - Universal coverage (standard `` + custom decorators)
11
+ */
12
+ import type { Project } from 'ts-morph';
13
+ /**
14
+ * Selector Mapper - Maps component selectors to class names.
15
+ *
16
+ * Provides O(1) selector lookups using a cached map built from project files.
17
+ * Supports both standard `` decorators and custom decorators (e.g., ``).
18
+ */
19
+ export declare class SelectorMapper {
20
+ private selectorMap;
21
+ /**
22
+ * Find a component class name by its selector.
23
+ *
24
+ * Builds the selector map lazily on first call, then reuses for O(1) lookups.
25
+ *
26
+ * @param project - ts-morph Project
27
+ * @param selector - Component selector (e.g., 'app-user-profile')
28
+ * @returns Class name (e.g., 'UserProfileComponent') or undefined if not found
29
+ */
30
+ findComponentBySelector(project: Project, selector: string): string | undefined;
31
+ /**
32
+ * Get the complete selector map.
33
+ *
34
+ * Builds the map lazily if not yet built.
35
+ *
36
+ * @param project - ts-morph Project
37
+ * @returns Map of selector → className
38
+ */
39
+ getSelectorMap(project: Project): Map<string, string>;
40
+ /**
41
+ * Clear the cached selector map.
42
+ *
43
+ * Useful for testing or when project files have changed significantly.
44
+ */
45
+ clearCache(): void;
46
+ /**
47
+ * Build a comprehensive selector map for the entire project.
48
+ *
49
+ * Scans all source files once to build selector → className mapping.
50
+ * Performance: O(n) initial build, O(1) lookup per selector.
51
+ *
52
+ * @param project - ts-morph Project
53
+ * @returns Map of selector → className
54
+ * @private
55
+ */
56
+ private buildSelectorMap;
57
+ /**
58
+ * Extract the selector from a `` decorator.
59
+ *
60
+ * @param decorator - The `` decorator
61
+ * @returns The selector string or undefined
62
+ * @private
63
+ */
64
+ private extractSelectorFromDecorator;
65
+ /**
66
+ * Find a decorator by name on a class declaration.
67
+ *
68
+ * Supports both standard decorators (``) and custom decorators (``).
69
+ *
70
+ * @param classDecl - Class declaration
71
+ * @param decoratorName - Decorator name (without @)
72
+ * @returns Decorator or undefined
73
+ * @private
74
+ */
75
+ private findDecorator;
76
+ }
77
+ //# sourceMappingURL=selector-mapper.d.ts.map