@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.
- package/LICENSE +21 -0
- package/README.md +507 -0
- package/dist/analysis/complexity-metrics-calculator.d.ts +99 -0
- package/dist/analysis/complexity-metrics-calculator.d.ts.map +1 -0
- package/dist/analysis/complexity-metrics-calculator.js +195 -0
- package/dist/analysis/complexity-metrics-calculator.js.map +1 -0
- package/dist/analysis/dependency-analyzer.d.ts +227 -0
- package/dist/analysis/dependency-analyzer.d.ts.map +1 -0
- package/dist/analysis/dependency-analyzer.js +451 -0
- package/dist/analysis/dependency-analyzer.js.map +1 -0
- package/dist/analysis/external-template-loader.d.ts +44 -0
- package/dist/analysis/external-template-loader.d.ts.map +1 -0
- package/dist/analysis/external-template-loader.js +69 -0
- package/dist/analysis/external-template-loader.js.map +1 -0
- package/dist/analysis/selector-mapper.d.ts +77 -0
- package/dist/analysis/selector-mapper.d.ts.map +1 -0
- package/dist/analysis/selector-mapper.js +146 -0
- package/dist/analysis/selector-mapper.js.map +1 -0
- package/dist/analysis/service-detector.d.ts +164 -0
- package/dist/analysis/service-detector.d.ts.map +1 -0
- package/dist/analysis/service-detector.js +231 -0
- package/dist/analysis/service-detector.js.map +1 -0
- package/dist/analysis/service-pattern-recognizer.d.ts +247 -0
- package/dist/analysis/service-pattern-recognizer.d.ts.map +1 -0
- package/dist/analysis/service-pattern-recognizer.js +444 -0
- package/dist/analysis/service-pattern-recognizer.js.map +1 -0
- package/dist/analysis/symbol-locator.d.ts +81 -0
- package/dist/analysis/symbol-locator.d.ts.map +1 -0
- package/dist/analysis/symbol-locator.js +128 -0
- package/dist/analysis/symbol-locator.js.map +1 -0
- package/dist/analysis/template-analyzer-usage.d.ts +144 -0
- package/dist/analysis/template-analyzer-usage.d.ts.map +1 -0
- package/dist/analysis/template-analyzer-usage.js +474 -0
- package/dist/analysis/template-analyzer-usage.js.map +1 -0
- package/dist/analysis/template-analyzer.d.ts +80 -0
- package/dist/analysis/template-analyzer.d.ts.map +1 -0
- package/dist/analysis/template-analyzer.js +146 -0
- package/dist/analysis/template-analyzer.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/investigation/angular-symbol-finder.d.ts +76 -0
- package/dist/investigation/angular-symbol-finder.d.ts.map +1 -0
- package/dist/investigation/angular-symbol-finder.js +199 -0
- package/dist/investigation/angular-symbol-finder.js.map +1 -0
- package/dist/investigation/call-graph-builder.d.ts +85 -0
- package/dist/investigation/call-graph-builder.d.ts.map +1 -0
- package/dist/investigation/call-graph-builder.js +196 -0
- package/dist/investigation/call-graph-builder.js.map +1 -0
- package/dist/investigation/codebase-searcher.d.ts +99 -0
- package/dist/investigation/codebase-searcher.d.ts.map +1 -0
- package/dist/investigation/codebase-searcher.js +201 -0
- package/dist/investigation/codebase-searcher.js.map +1 -0
- package/dist/investigation/stack-trace-parser.d.ts +70 -0
- package/dist/investigation/stack-trace-parser.d.ts.map +1 -0
- package/dist/investigation/stack-trace-parser.js +117 -0
- package/dist/investigation/stack-trace-parser.js.map +1 -0
- package/dist/investigation/type-resolver.d.ts +59 -0
- package/dist/investigation/type-resolver.d.ts.map +1 -0
- package/dist/investigation/type-resolver.js +111 -0
- package/dist/investigation/type-resolver.js.map +1 -0
- package/dist/investigation/usage-finder.d.ts +69 -0
- package/dist/investigation/usage-finder.d.ts.map +1 -0
- package/dist/investigation/usage-finder.js +132 -0
- package/dist/investigation/usage-finder.js.map +1 -0
- package/dist/metrics/complexity-metrics.d.ts +196 -0
- package/dist/metrics/complexity-metrics.d.ts.map +1 -0
- package/dist/metrics/complexity-metrics.js +445 -0
- package/dist/metrics/complexity-metrics.js.map +1 -0
- package/dist/public-api.d.ts +77 -0
- package/dist/public-api.d.ts.map +1 -0
- package/dist/public-api.js +50 -0
- package/dist/public-api.js.map +1 -0
- package/dist/transformation/import-manager.d.ts +276 -0
- package/dist/transformation/import-manager.d.ts.map +1 -0
- package/dist/transformation/import-manager.js +488 -0
- package/dist/transformation/import-manager.js.map +1 -0
- package/dist/transformation/ng-morph-adapter.d.ts +111 -0
- package/dist/transformation/ng-morph-adapter.d.ts.map +1 -0
- package/dist/transformation/ng-morph-adapter.js +179 -0
- package/dist/transformation/ng-morph-adapter.js.map +1 -0
- package/dist/transformation/ngmodule-manager.d.ts +145 -0
- package/dist/transformation/ngmodule-manager.d.ts.map +1 -0
- package/dist/transformation/ngmodule-manager.js +356 -0
- package/dist/transformation/ngmodule-manager.js.map +1 -0
- package/package.json +62 -0
- package/src/analysis/complexity-metrics-calculator.ts +253 -0
- package/src/analysis/dependency-analyzer.ts +720 -0
- package/src/analysis/external-template-loader.ts +79 -0
- package/src/analysis/selector-mapper.ts +186 -0
- package/src/analysis/service-detector.ts +280 -0
- package/src/analysis/service-pattern-recognizer.ts +545 -0
- package/src/analysis/symbol-locator.ts +170 -0
- package/src/analysis/template-analyzer-usage.ts +614 -0
- package/src/analysis/template-analyzer.ts +208 -0
- package/src/index.ts +51 -0
- package/src/investigation/angular-symbol-finder.ts +263 -0
- package/src/investigation/call-graph-builder.ts +298 -0
- package/src/investigation/codebase-searcher.ts +286 -0
- package/src/investigation/stack-trace-parser.ts +166 -0
- package/src/investigation/type-resolver.ts +144 -0
- package/src/investigation/usage-finder.ts +198 -0
- package/src/metrics/complexity-metrics.ts +617 -0
- package/src/public-api.ts +119 -0
- package/src/transformation/import-manager.ts +626 -0
- package/src/transformation/ng-morph-adapter.ts +252 -0
- package/src/transformation/ngmodule-manager.ts +450 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @angular-modernizer/api - Template Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Dumb Collector - extracts ALL elements from Angular templates.
|
|
5
|
+
* Zero filtering, zero intelligence. Based on the "Trust the Map" principle.
|
|
6
|
+
*
|
|
7
|
+
* Philosophy: "Collect Everything, Filter Later"
|
|
8
|
+
* - No business logic in collectors
|
|
9
|
+
* - Plugins decide what matters
|
|
10
|
+
* - Raw data is more valuable than pre-filtered data
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Template Analyzer - extracts all usages from Angular templates.
|
|
14
|
+
*
|
|
15
|
+
* This is a "Dumb Collector" that doesn't filter or interpret.
|
|
16
|
+
* It just collects everything and lets plugins decide what's important.
|
|
17
|
+
*/
|
|
18
|
+
export class TemplateAnalyzer {
|
|
19
|
+
/**
|
|
20
|
+
* Analyze a template string and extract all usages.
|
|
21
|
+
*
|
|
22
|
+
* @param template - The template string to analyze
|
|
23
|
+
* @returns Array of template usages
|
|
24
|
+
*
|
|
25
|
+
* Philosophy: "Collect Everything, Filter Later"
|
|
26
|
+
* - Extracts ALL elements, attributes, pipes, directives
|
|
27
|
+
* - No filtering, no business logic
|
|
28
|
+
* - Plugins decide what's important using the SymbolMapper
|
|
29
|
+
*/
|
|
30
|
+
analyze(template) {
|
|
31
|
+
const usages = [];
|
|
32
|
+
const lines = template.split('\n');
|
|
33
|
+
// Extract element tags (e.g., <fixture-child>, <div>, <custom-component>)
|
|
34
|
+
const elementRegex = /<([a-zA-Z][\w-]*)/g;
|
|
35
|
+
// Extract pipes (e.g., {{ value | pipeName }}, {{ value | pipeName: arg }})
|
|
36
|
+
const pipeRegex = /\|\s*([a-zA-Z]\w*)/g;
|
|
37
|
+
lines.forEach((line, lineIndex) => {
|
|
38
|
+
// Extract elements
|
|
39
|
+
let match;
|
|
40
|
+
while ((match = elementRegex.exec(line)) !== null) {
|
|
41
|
+
const tagName = match[1];
|
|
42
|
+
if (tagName) {
|
|
43
|
+
usages.push({
|
|
44
|
+
type: 'element',
|
|
45
|
+
name: tagName,
|
|
46
|
+
line: lineIndex + 1,
|
|
47
|
+
column: match.index,
|
|
48
|
+
raw: match[0],
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Extract attributes - use multiple patterns for better coverage
|
|
53
|
+
// Pattern 1: Structural directives (*ngIf, *ngFor)
|
|
54
|
+
const structuralDirectiveRegex = /\*([a-zA-Z][\w-]*)/g;
|
|
55
|
+
while ((match = structuralDirectiveRegex.exec(line)) !== null) {
|
|
56
|
+
usages.push({
|
|
57
|
+
type: 'structural-directive',
|
|
58
|
+
name: `*${match[1]}`,
|
|
59
|
+
line: lineIndex + 1,
|
|
60
|
+
column: match.index,
|
|
61
|
+
raw: match[0],
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
// Pattern 2: Angular 17+ control flow (@if, @for, @switch, @empty, @let)
|
|
65
|
+
const controlFlowRegex = /@(if|else if|for|switch|case|default|empty|let)\b/g;
|
|
66
|
+
while ((match = controlFlowRegex.exec(line)) !== null) {
|
|
67
|
+
usages.push({
|
|
68
|
+
type: 'control-flow',
|
|
69
|
+
name: match[1],
|
|
70
|
+
line: lineIndex + 1,
|
|
71
|
+
column: match.index,
|
|
72
|
+
raw: match[0],
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
// Pattern 3: Property bindings ([propName]="value")
|
|
76
|
+
const propertyBindingRegex = /\[([a-zA-Z][\w-]*)\]/g;
|
|
77
|
+
while ((match = propertyBindingRegex.exec(line)) !== null) {
|
|
78
|
+
usages.push({
|
|
79
|
+
type: 'directive',
|
|
80
|
+
name: `[${match[1]}]`,
|
|
81
|
+
line: lineIndex + 1,
|
|
82
|
+
column: match.index,
|
|
83
|
+
raw: match[0],
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
// Pattern 3: Bare attribute selectors (fixtureAttribute, ngModel)
|
|
87
|
+
// Look for attribute names that are NOT standard HTML attributes
|
|
88
|
+
const bareAttributeRegex = /\s+([a-z][\w-]*(?:[A-Z][\w-]*)+)\s*(?:=|>|\s|$)/g;
|
|
89
|
+
while ((match = bareAttributeRegex.exec(line)) !== null) {
|
|
90
|
+
const attrName = match[1];
|
|
91
|
+
// Only add if it looks like a directive (has camelCase or kebab-case)
|
|
92
|
+
if (attrName && (attrName.includes('-') || /[A-Z]/.test(attrName))) {
|
|
93
|
+
usages.push({
|
|
94
|
+
type: 'directive',
|
|
95
|
+
name: attrName,
|
|
96
|
+
line: lineIndex + 1,
|
|
97
|
+
column: match.index,
|
|
98
|
+
raw: match[0].trim(),
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Extract pipes
|
|
103
|
+
const pipeMatches = line.matchAll(pipeRegex);
|
|
104
|
+
for (const pipeMatch of pipeMatches) {
|
|
105
|
+
const pipeName = pipeMatch[1];
|
|
106
|
+
if (pipeName) {
|
|
107
|
+
usages.push({
|
|
108
|
+
type: 'pipe',
|
|
109
|
+
name: pipeName,
|
|
110
|
+
line: lineIndex + 1,
|
|
111
|
+
column: pipeMatch.index,
|
|
112
|
+
raw: pipeMatch[0],
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
return usages;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Extract inline template from component decorator.
|
|
121
|
+
*
|
|
122
|
+
* @param decoratorText - The `` decorator text
|
|
123
|
+
* @returns The template string or undefined
|
|
124
|
+
*/
|
|
125
|
+
extractInlineTemplate(decoratorText) {
|
|
126
|
+
// Match template: `...` or template: '...' (including multiline)
|
|
127
|
+
const templateRegex = /template\s*:\s*(['`])([\s\S]*?)\1/;
|
|
128
|
+
const match = templateRegex.exec(decoratorText);
|
|
129
|
+
if (match) {
|
|
130
|
+
return match[2];
|
|
131
|
+
}
|
|
132
|
+
return undefined;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Check if a template uses a specific selector.
|
|
136
|
+
*
|
|
137
|
+
* @param template - The template string
|
|
138
|
+
* @param selector - The selector to search for
|
|
139
|
+
* @returns True if selector is used
|
|
140
|
+
*/
|
|
141
|
+
usesSelector(template, selector) {
|
|
142
|
+
const usages = this.analyze(template);
|
|
143
|
+
return usages.some((usage) => usage.name === selector);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=template-analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-analyzer.js","sourceRoot":"","sources":["../../src/analysis/template-analyzer.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main entry point for @angular-modernizer/api
|
|
3
|
+
*/
|
|
4
|
+
export * from './public-api.js';
|
|
5
|
+
export * from './transformation/ng-morph-adapter.js';
|
|
6
|
+
export * from './transformation/ngmodule-manager.js';
|
|
7
|
+
export * from './transformation/import-manager.js';
|
|
8
|
+
export * from './analysis/service-pattern-recognizer.js';
|
|
9
|
+
export * from './analysis/service-detector.js';
|
|
10
|
+
export type { ServiceDetectionResult } from './analysis/service-pattern-recognizer.js';
|
|
11
|
+
export * from './analysis/dependency-analyzer.js';
|
|
12
|
+
export * from './analysis/template-analyzer.js';
|
|
13
|
+
export * from './analysis/template-analyzer-usage.js';
|
|
14
|
+
export * from './analysis/selector-mapper.js';
|
|
15
|
+
export * from './analysis/external-template-loader.js';
|
|
16
|
+
export { SymbolLocator, type SymbolInfo as ProjectSymbolInfo, } from './analysis/symbol-locator.js';
|
|
17
|
+
export { StackTraceParser, type StackFrame, } from './investigation/stack-trace-parser.js';
|
|
18
|
+
export { UsageFinder, type SymbolUsage, type UsageType, type FindUsagesOptions, } from './investigation/usage-finder.js';
|
|
19
|
+
export { CallGraphBuilder, type CallNode, type CallGraphOptions, type CallGraphResult, } from './investigation/call-graph-builder.js';
|
|
20
|
+
export { TypeResolver, type ResolvedTypeInfo, } from './investigation/type-resolver.js';
|
|
21
|
+
export { AngularSymbolFinder, type AngularSymbolResult, type AngularSymbolType, } from './investigation/angular-symbol-finder.js';
|
|
22
|
+
export { CodebaseSearcher, type SearchResult, type SearchOptions, type SymbolKind, } from './investigation/codebase-searcher.js';
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,iBAAiB,CAAC;AAChC,cAAc,sCAAsC,CAAC;AACrD,cAAc,sCAAsC,CAAC;AACrD,cAAc,oCAAoC,CAAC;AACnD,cAAc,0CAA0C,CAAC;AACzD,cAAc,gCAAgC,CAAC;AAC/C,YAAY,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAC;AACvF,cAAc,mCAAmC,CAAC;AAClD,cAAc,iCAAiC,CAAC;AAChD,cAAc,uCAAuC,CAAC;AACtD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wCAAwC,CAAC;AACvD,OAAO,EACL,aAAa,EACb,KAAK,UAAU,IAAI,iBAAiB,GACrC,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,gBAAgB,EAChB,KAAK,UAAU,GAChB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,WAAW,EACX,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,iBAAiB,GACvB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,gBAAgB,EAChB,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACrB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,YAAY,EACZ,KAAK,gBAAgB,GACtB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,mBAAmB,EACnB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,GACvB,MAAM,0CAA0C,CAAC;AAClD,OAAO,EACL,gBAAgB,EAChB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,UAAU,GAChB,MAAM,sCAAsC,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main entry point for @angular-modernizer/api
|
|
3
|
+
*/
|
|
4
|
+
export * from './public-api.js';
|
|
5
|
+
export * from './transformation/ng-morph-adapter.js';
|
|
6
|
+
export * from './transformation/ngmodule-manager.js';
|
|
7
|
+
export * from './transformation/import-manager.js';
|
|
8
|
+
export * from './analysis/service-pattern-recognizer.js';
|
|
9
|
+
export * from './analysis/service-detector.js';
|
|
10
|
+
export * from './analysis/dependency-analyzer.js';
|
|
11
|
+
export * from './analysis/template-analyzer.js';
|
|
12
|
+
export * from './analysis/template-analyzer-usage.js';
|
|
13
|
+
export * from './analysis/selector-mapper.js';
|
|
14
|
+
export * from './analysis/external-template-loader.js';
|
|
15
|
+
export { SymbolLocator, } from './analysis/symbol-locator.js';
|
|
16
|
+
export { StackTraceParser, } from './investigation/stack-trace-parser.js';
|
|
17
|
+
export { UsageFinder, } from './investigation/usage-finder.js';
|
|
18
|
+
export { CallGraphBuilder, } from './investigation/call-graph-builder.js';
|
|
19
|
+
export { TypeResolver, } from './investigation/type-resolver.js';
|
|
20
|
+
export { AngularSymbolFinder, } from './investigation/angular-symbol-finder.js';
|
|
21
|
+
export { CodebaseSearcher, } from './investigation/codebase-searcher.js';
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,iBAAiB,CAAC;AAChC,cAAc,sCAAsC,CAAC;AACrD,cAAc,sCAAsC,CAAC;AACrD,cAAc,oCAAoC,CAAC;AACnD,cAAc,0CAA0C,CAAC;AACzD,cAAc,gCAAgC,CAAC;AAE/C,cAAc,mCAAmC,CAAC;AAClD,cAAc,iCAAiC,CAAC;AAChD,cAAc,uCAAuC,CAAC;AACtD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wCAAwC,CAAC;AACvD,OAAO,EACL,aAAa,GAEd,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,gBAAgB,GAEjB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,WAAW,GAIZ,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,gBAAgB,GAIjB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,YAAY,GAEb,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,mBAAmB,GAGpB,MAAM,0CAA0C,CAAC;AAClD,OAAO,EACL,gBAAgB,GAIjB,MAAM,sCAAsC,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @angular-modernizer/api - Angular Symbol Finder
|
|
3
|
+
*
|
|
4
|
+
* Finds Angular symbols (components, directives, pipes, services, guards,
|
|
5
|
+
* interceptors, resolvers, modules, tokens) by selector, template name, class
|
|
6
|
+
* name, or token name. Supports standard Angular decorators as well as
|
|
7
|
+
* ngUWI-specific external decorators (@ExportComponent, @ExportFunction).
|
|
8
|
+
*
|
|
9
|
+
* @remarks
|
|
10
|
+
* The project must already have the relevant source files added before calling
|
|
11
|
+
* `findSymbol`. Queries are matched case-sensitively for class names, and
|
|
12
|
+
* substring-matched for selectors/pipe names (e.g. searching "app-list" also
|
|
13
|
+
* returns "app-list-item" selectors).
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const finder = new AngularSymbolFinder(project);
|
|
18
|
+
* const results = finder.findSymbol('app-user');
|
|
19
|
+
* // results[0] → { file, className, angularType: 'component', selector: 'app-user', metadata: {...} }
|
|
20
|
+
*
|
|
21
|
+
* const pipes = finder.findSymbol('dateFormat', 'pipe');
|
|
22
|
+
* // pipes[0] → { file, className: 'DateFormatPipe', angularType: 'pipe', pipeName: 'dateFormat', metadata: {...} }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
import type { Project } from 'ts-morph';
|
|
26
|
+
/** The Angular symbol type classification. */
|
|
27
|
+
export type AngularSymbolType = 'component' | 'directive' | 'pipe' | 'service' | 'guard' | 'interceptor' | 'resolver' | 'module' | 'token';
|
|
28
|
+
/** A resolved Angular symbol. */
|
|
29
|
+
export interface AngularSymbolResult {
|
|
30
|
+
/** Absolute file path containing the class. */
|
|
31
|
+
file: string;
|
|
32
|
+
/** Class name (e.g. `UserComponent`). */
|
|
33
|
+
className: string;
|
|
34
|
+
/** Angular symbol type. */
|
|
35
|
+
angularType: AngularSymbolType;
|
|
36
|
+
/** CSS selector for components and directives (stripped of brackets). */
|
|
37
|
+
selector?: string;
|
|
38
|
+
/** Template name for pipes (value of `@Pipe({ name: '...' })`). */
|
|
39
|
+
pipeName?: string;
|
|
40
|
+
/** Raw decorator metadata (key-value pairs extracted from the decorator). */
|
|
41
|
+
metadata: Record<string, string>;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Finds Angular symbols across all source files in a ts-morph `Project`.
|
|
45
|
+
*/
|
|
46
|
+
export declare class AngularSymbolFinder {
|
|
47
|
+
private readonly project;
|
|
48
|
+
constructor(project: Project);
|
|
49
|
+
/**
|
|
50
|
+
* Find Angular symbols matching `query`.
|
|
51
|
+
*
|
|
52
|
+
* @param query - Selector (e.g. `app-user`, `appHighlight`), pipe name
|
|
53
|
+
* (e.g. `dateFormat`), class name (e.g. `UserComponent`), or partial
|
|
54
|
+
* selector substring.
|
|
55
|
+
* @param type - Optional filter; when provided only results of the given type
|
|
56
|
+
* are returned.
|
|
57
|
+
* @returns Array of matching `AngularSymbolResult` objects, empty when none
|
|
58
|
+
* are found.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```typescript
|
|
62
|
+
* // By selector
|
|
63
|
+
* finder.findSymbol('app-user');
|
|
64
|
+
*
|
|
65
|
+
* // By class name with type filter
|
|
66
|
+
* finder.findSymbol('UserService', 'service');
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
findSymbol(query: string, type?: AngularSymbolType): AngularSymbolResult[];
|
|
70
|
+
/**
|
|
71
|
+
* Attempts to classify a class declaration as an Angular symbol.
|
|
72
|
+
* Returns `null` when the class carries no recognised Angular decorator.
|
|
73
|
+
*/
|
|
74
|
+
private classifyClass;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=angular-symbol-finder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"angular-symbol-finder.d.ts","sourceRoot":"","sources":["../../src/investigation/angular-symbol-finder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAA+B,MAAM,UAAU,CAAC;AAErE,8CAA8C;AAC9C,MAAM,MAAM,iBAAiB,GACzB,WAAW,GACX,WAAW,GACX,MAAM,GACN,SAAS,GACT,OAAO,GACP,aAAa,GACb,UAAU,GACV,QAAQ,GACR,OAAO,CAAC;AAEZ,iCAAiC;AACjC,MAAM,WAAW,mBAAmB;IAClC,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IAEb,yCAAyC;IACzC,SAAS,EAAE,MAAM,CAAC;IAElB,2BAA2B;IAC3B,WAAW,EAAE,iBAAiB,CAAC;IAE/B,yEAAyE;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAuGD;;GAEG;AACH,qBAAa,mBAAmB;IAClB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,OAAO;IAE7C;;;;;;;;;;;;;;;;;;;OAmBG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,iBAAiB,GAAG,mBAAmB,EAAE;IA4B1E;;;OAGG;IACH,OAAO,CAAC,aAAa;CA2CtB"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @angular-modernizer/api - Angular Symbol Finder
|
|
3
|
+
*
|
|
4
|
+
* Finds Angular symbols (components, directives, pipes, services, guards,
|
|
5
|
+
* interceptors, resolvers, modules, tokens) by selector, template name, class
|
|
6
|
+
* name, or token name. Supports standard Angular decorators as well as
|
|
7
|
+
* ngUWI-specific external decorators (@ExportComponent, @ExportFunction).
|
|
8
|
+
*
|
|
9
|
+
* @remarks
|
|
10
|
+
* The project must already have the relevant source files added before calling
|
|
11
|
+
* `findSymbol`. Queries are matched case-sensitively for class names, and
|
|
12
|
+
* substring-matched for selectors/pipe names (e.g. searching "app-list" also
|
|
13
|
+
* returns "app-list-item" selectors).
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const finder = new AngularSymbolFinder(project);
|
|
18
|
+
* const results = finder.findSymbol('app-user');
|
|
19
|
+
* // results[0] → { file, className, angularType: 'component', selector: 'app-user', metadata: {...} }
|
|
20
|
+
*
|
|
21
|
+
* const pipes = finder.findSymbol('dateFormat', 'pipe');
|
|
22
|
+
* // pipes[0] → { file, className: 'DateFormatPipe', angularType: 'pipe', pipeName: 'dateFormat', metadata: {...} }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
/** Decorator names that map to Angular symbol types. */
|
|
26
|
+
const DECORATOR_TYPE_MAP = {
|
|
27
|
+
Component: 'component',
|
|
28
|
+
ExportComponent: 'component',
|
|
29
|
+
Directive: 'directive',
|
|
30
|
+
Pipe: 'pipe',
|
|
31
|
+
Injectable: 'service',
|
|
32
|
+
ExportFunction: 'service',
|
|
33
|
+
NgModule: 'module',
|
|
34
|
+
Guard: 'guard',
|
|
35
|
+
Interceptor: 'interceptor',
|
|
36
|
+
Resolver: 'resolver',
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Extracts the string value of a named property from a decorator's argument
|
|
40
|
+
* object literal (e.g. `selector: 'app-foo'` → `'app-foo'`).
|
|
41
|
+
*/
|
|
42
|
+
function extractDecoratorProperty(decorator, property) {
|
|
43
|
+
try {
|
|
44
|
+
const args = decorator.getArguments();
|
|
45
|
+
if (args.length === 0) {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
const arg = args[0];
|
|
49
|
+
if (arg === undefined) {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
const text = arg.getText();
|
|
53
|
+
const match = new RegExp(`${property}\\s*:\\s*['"\`]([^'"\`]+)['"\`]`).exec(text);
|
|
54
|
+
return match?.[1];
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Extracts all string-valued properties from a decorator's first argument
|
|
62
|
+
* as a flat `Record<string, string>`.
|
|
63
|
+
*/
|
|
64
|
+
function extractDecoratorMetadata(decorator) {
|
|
65
|
+
const metadata = {};
|
|
66
|
+
try {
|
|
67
|
+
const args = decorator.getArguments();
|
|
68
|
+
const firstArg = args[0];
|
|
69
|
+
if (args.length === 0 || firstArg === undefined) {
|
|
70
|
+
return metadata;
|
|
71
|
+
}
|
|
72
|
+
const text = firstArg.getText();
|
|
73
|
+
const pattern = /(\w+)\s*:\s*['"`]([^'"`]+)['"`]/g;
|
|
74
|
+
let match;
|
|
75
|
+
while ((match = pattern.exec(text)) !== null) {
|
|
76
|
+
const key = match[1];
|
|
77
|
+
const value = match[2];
|
|
78
|
+
if (key !== undefined && value !== undefined) {
|
|
79
|
+
metadata[key] = value;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// ignore
|
|
85
|
+
}
|
|
86
|
+
return metadata;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Strips attribute-selector brackets from a selector string.
|
|
90
|
+
* `[appHighlight]` → `appHighlight`; `app-user` → `app-user`.
|
|
91
|
+
*/
|
|
92
|
+
function normalizeSelector(raw) {
|
|
93
|
+
return raw.replace(/^\[(.+)\]$/, '$1');
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Returns `true` when the query matches the given selector (substring) or
|
|
97
|
+
* class name (exact).
|
|
98
|
+
*/
|
|
99
|
+
function matchesQuery(query, className, selector, pipeName) {
|
|
100
|
+
if (className === query) {
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
if (selector?.includes(query)) {
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
if (pipeName !== undefined && pipeName === query) {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Finds Angular symbols across all source files in a ts-morph `Project`.
|
|
113
|
+
*/
|
|
114
|
+
export class AngularSymbolFinder {
|
|
115
|
+
project;
|
|
116
|
+
constructor(project) {
|
|
117
|
+
this.project = project;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Find Angular symbols matching `query`.
|
|
121
|
+
*
|
|
122
|
+
* @param query - Selector (e.g. `app-user`, `appHighlight`), pipe name
|
|
123
|
+
* (e.g. `dateFormat`), class name (e.g. `UserComponent`), or partial
|
|
124
|
+
* selector substring.
|
|
125
|
+
* @param type - Optional filter; when provided only results of the given type
|
|
126
|
+
* are returned.
|
|
127
|
+
* @returns Array of matching `AngularSymbolResult` objects, empty when none
|
|
128
|
+
* are found.
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```typescript
|
|
132
|
+
* // By selector
|
|
133
|
+
* finder.findSymbol('app-user');
|
|
134
|
+
*
|
|
135
|
+
* // By class name with type filter
|
|
136
|
+
* finder.findSymbol('UserService', 'service');
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
findSymbol(query, type) {
|
|
140
|
+
const results = [];
|
|
141
|
+
for (const sourceFile of this.project.getSourceFiles()) {
|
|
142
|
+
for (const cls of sourceFile.getClasses()) {
|
|
143
|
+
const result = this.classifyClass(cls);
|
|
144
|
+
if (result === null) {
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
if (type !== undefined && result.angularType !== type) {
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
if (matchesQuery(query, result.className, result.selector, result.pipeName)) {
|
|
151
|
+
results.push(result);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return results;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Attempts to classify a class declaration as an Angular symbol.
|
|
159
|
+
* Returns `null` when the class carries no recognised Angular decorator.
|
|
160
|
+
*/
|
|
161
|
+
classifyClass(cls) {
|
|
162
|
+
for (const decorator of cls.getDecorators()) {
|
|
163
|
+
const decoratorName = decorator.getName();
|
|
164
|
+
const angularType = DECORATOR_TYPE_MAP[decoratorName];
|
|
165
|
+
if (angularType === undefined) {
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
const className = cls.getName() ?? '(anonymous)';
|
|
169
|
+
const file = cls.getSourceFile().getFilePath();
|
|
170
|
+
const metadata = extractDecoratorMetadata(decorator);
|
|
171
|
+
let selector;
|
|
172
|
+
let pipeName;
|
|
173
|
+
if (angularType === 'component' || angularType === 'directive') {
|
|
174
|
+
const rawSelector = extractDecoratorProperty(decorator, 'selector');
|
|
175
|
+
if (rawSelector !== undefined) {
|
|
176
|
+
selector = normalizeSelector(rawSelector);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (angularType === 'pipe') {
|
|
180
|
+
pipeName = extractDecoratorProperty(decorator, 'name');
|
|
181
|
+
}
|
|
182
|
+
const result = {
|
|
183
|
+
file,
|
|
184
|
+
className,
|
|
185
|
+
angularType,
|
|
186
|
+
metadata,
|
|
187
|
+
};
|
|
188
|
+
if (selector !== undefined) {
|
|
189
|
+
result.selector = selector;
|
|
190
|
+
}
|
|
191
|
+
if (pipeName !== undefined) {
|
|
192
|
+
result.pipeName = pipeName;
|
|
193
|
+
}
|
|
194
|
+
return result;
|
|
195
|
+
}
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=angular-symbol-finder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"angular-symbol-finder.js","sourceRoot":"","sources":["../../src/investigation/angular-symbol-finder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @angular-modernizer/api - Call Graph Builder
|
|
3
|
+
*
|
|
4
|
+
* Builds a call graph for a named method or function within a ts-morph Project.
|
|
5
|
+
* Supports traversal upward (callers) and downward (callees) with configurable depth.
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* Used in bug investigation to understand how an error propagates through the
|
|
9
|
+
* codebase. Combine with `find-usages` to trace the full call path from the
|
|
10
|
+
* entry point to the failing code.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const builder = new CallGraphBuilder(project);
|
|
15
|
+
* const graph = builder.buildCallGraph('getUser', '/src/app/user.service.ts', {
|
|
16
|
+
* direction: 'both',
|
|
17
|
+
* depth: 2,
|
|
18
|
+
* });
|
|
19
|
+
* // graph.callers → who calls getUser
|
|
20
|
+
* // graph.callees → what getUser calls
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
import type { Project } from 'ts-morph';
|
|
24
|
+
/** A node in the call graph tree. */
|
|
25
|
+
export interface CallNode {
|
|
26
|
+
/** Method or function name. */
|
|
27
|
+
name: string;
|
|
28
|
+
/** Absolute file path where this method is declared. */
|
|
29
|
+
file: string;
|
|
30
|
+
/** 1-based line number of the declaration. */
|
|
31
|
+
line: number;
|
|
32
|
+
/** Nested callers or callees (recursive to configured depth). */
|
|
33
|
+
children: CallNode[];
|
|
34
|
+
}
|
|
35
|
+
/** Options for `buildCallGraph`. */
|
|
36
|
+
export interface CallGraphOptions {
|
|
37
|
+
/**
|
|
38
|
+
* Traversal direction.
|
|
39
|
+
* - `'up'` — callers only (who calls the target)
|
|
40
|
+
* - `'down'` — callees only (what the target calls)
|
|
41
|
+
* - `'both'` — both directions
|
|
42
|
+
* @default 'both'
|
|
43
|
+
*/
|
|
44
|
+
direction?: 'up' | 'down' | 'both';
|
|
45
|
+
/**
|
|
46
|
+
* How many levels deep to traverse.
|
|
47
|
+
* @default 2
|
|
48
|
+
*/
|
|
49
|
+
depth?: number;
|
|
50
|
+
}
|
|
51
|
+
/** Result of `buildCallGraph`. */
|
|
52
|
+
export interface CallGraphResult {
|
|
53
|
+
/** The resolved target node, or `null` when not found. */
|
|
54
|
+
target: Omit<CallNode, 'children'> | null;
|
|
55
|
+
/** Nodes that call the target (populated for `'up'` and `'both'`). */
|
|
56
|
+
callers: CallNode[];
|
|
57
|
+
/** Nodes called by the target (populated for `'down'` and `'both'`). */
|
|
58
|
+
callees: CallNode[];
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Builds caller/callee graphs for methods and functions across a ts-morph Project.
|
|
62
|
+
*/
|
|
63
|
+
export declare class CallGraphBuilder {
|
|
64
|
+
private readonly project;
|
|
65
|
+
/**
|
|
66
|
+
* @param project - A ts-morph `Project` instance with source files already added.
|
|
67
|
+
*/
|
|
68
|
+
constructor(project: Project);
|
|
69
|
+
/**
|
|
70
|
+
* Builds a call graph rooted at the named method or function.
|
|
71
|
+
*
|
|
72
|
+
* @param method - Name of the method or function to analyse.
|
|
73
|
+
* @param file - Absolute path of the source file containing the method.
|
|
74
|
+
* @param options - Traversal direction and depth. Defaults to `both` / depth `2`.
|
|
75
|
+
* @returns A `CallGraphResult` with the target and its caller/callee trees.
|
|
76
|
+
*/
|
|
77
|
+
buildCallGraph(method: string, file: string, options?: CallGraphOptions): CallGraphResult;
|
|
78
|
+
private resolveTarget;
|
|
79
|
+
private buildCallees;
|
|
80
|
+
private buildCallers;
|
|
81
|
+
private findDeclarationInProject;
|
|
82
|
+
private extractCallName;
|
|
83
|
+
private deduplicateNodes;
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=call-graph-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"call-graph-builder.d.ts","sourceRoot":"","sources":["../../src/investigation/call-graph-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAA0C,MAAM,UAAU,CAAC;AAGhF,qCAAqC;AACrC,MAAM,WAAW,QAAQ;IACvB,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IAEb,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IAEb,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IAEb,iEAAiE;IACjE,QAAQ,EAAE,QAAQ,EAAE,CAAC;CACtB;AAED,oCAAoC;AACpC,MAAM,WAAW,gBAAgB;IAC/B;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;IAEnC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,kCAAkC;AAClC,MAAM,WAAW,eAAe;IAC9B,0DAA0D;IAC1D,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,GAAG,IAAI,CAAC;IAE1C,sEAAsE;IACtE,OAAO,EAAE,QAAQ,EAAE,CAAC;IAEpB,wEAAwE;IACxE,OAAO,EAAE,QAAQ,EAAE,CAAC;CACrB;AAID;;GAEG;AACH,qBAAa,gBAAgB;IAIf,OAAO,CAAC,QAAQ,CAAC,OAAO;IAHpC;;OAEG;gBAC0B,OAAO,EAAE,OAAO;IAE7C;;;;;;;OAOG;IACH,cAAc,CACZ,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,gBAAqB,GAC7B,eAAe;IA4BlB,OAAO,CAAC,aAAa;IAuBrB,OAAO,CAAC,YAAY;IAuDpB,OAAO,CAAC,YAAY;IA+DpB,OAAO,CAAC,wBAAwB;IAgBhC,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,gBAAgB;CAWzB"}
|