@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,196 @@
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 { SyntaxKind } from 'ts-morph';
24
+ /**
25
+ * Builds caller/callee graphs for methods and functions across a ts-morph Project.
26
+ */
27
+ export class CallGraphBuilder {
28
+ project;
29
+ /**
30
+ * @param project - A ts-morph `Project` instance with source files already added.
31
+ */
32
+ constructor(project) {
33
+ this.project = project;
34
+ }
35
+ /**
36
+ * Builds a call graph rooted at the named method or function.
37
+ *
38
+ * @param method - Name of the method or function to analyse.
39
+ * @param file - Absolute path of the source file containing the method.
40
+ * @param options - Traversal direction and depth. Defaults to `both` / depth `2`.
41
+ * @returns A `CallGraphResult` with the target and its caller/callee trees.
42
+ */
43
+ buildCallGraph(method, file, options = {}) {
44
+ const direction = options.direction ?? 'both';
45
+ const depth = options.depth ?? 2;
46
+ const target = this.resolveTarget(method, file);
47
+ if (!target) {
48
+ return { target: null, callers: [], callees: [] };
49
+ }
50
+ const targetInfo = {
51
+ name: method,
52
+ file,
53
+ line: target.getStartLineNumber(),
54
+ };
55
+ const callers = direction === 'down'
56
+ ? []
57
+ : this.buildCallers(target, depth, new Set([`${file}:${method}`]));
58
+ const callees = direction === 'up'
59
+ ? []
60
+ : this.buildCallees(target, depth, new Set([`${file}:${method}`]));
61
+ return { target: targetInfo, callers, callees };
62
+ }
63
+ resolveTarget(name, file) {
64
+ const sourceFile = this.project.getSourceFile(file);
65
+ if (!sourceFile) {
66
+ return null;
67
+ }
68
+ // Search class methods
69
+ for (const cls of sourceFile.getClasses()) {
70
+ const method = cls.getMethod(name);
71
+ if (method) {
72
+ return method;
73
+ }
74
+ }
75
+ // Search top-level functions
76
+ const fn = sourceFile.getFunction(name);
77
+ if (fn) {
78
+ return fn;
79
+ }
80
+ return null;
81
+ }
82
+ buildCallees(callable, depth, visited) {
83
+ if (depth <= 0) {
84
+ return [];
85
+ }
86
+ const callees = [];
87
+ const body = callable.getBody();
88
+ if (!body) {
89
+ return [];
90
+ }
91
+ body.forEachDescendant((node) => {
92
+ if (node.getKind() !== SyntaxKind.CallExpression) {
93
+ return;
94
+ }
95
+ const callExpr = node.asKindOrThrow(SyntaxKind.CallExpression);
96
+ const expr = callExpr.getExpression();
97
+ const calleeName = this.extractCallName(expr.getText());
98
+ if (!calleeName) {
99
+ return;
100
+ }
101
+ const targetDecl = this.findDeclarationInProject(calleeName);
102
+ if (!targetDecl) {
103
+ return;
104
+ }
105
+ const targetFile = targetDecl.getSourceFile().getFilePath();
106
+ const key = `${targetFile}:${calleeName}`;
107
+ if (visited.has(key)) {
108
+ return;
109
+ }
110
+ visited.add(key);
111
+ const children = this.buildCallees(targetDecl, depth - 1, new Set(visited));
112
+ callees.push({
113
+ name: calleeName,
114
+ file: targetFile,
115
+ line: targetDecl.getStartLineNumber(),
116
+ children,
117
+ });
118
+ });
119
+ return this.deduplicateNodes(callees);
120
+ }
121
+ buildCallers(callable, depth, visited) {
122
+ if (depth <= 0) {
123
+ return [];
124
+ }
125
+ const callers = [];
126
+ const name = callable.getName();
127
+ if (!name) {
128
+ return [];
129
+ }
130
+ const refs = this.project.getLanguageService().findReferences(callable);
131
+ for (const refSymbol of refs) {
132
+ for (const ref of refSymbol.getReferences()) {
133
+ if (ref.isDefinition()) {
134
+ continue;
135
+ }
136
+ const refNode = ref.getNode();
137
+ const parentMethod = refNode.getFirstAncestor((n) => n.getKind() === SyntaxKind.MethodDeclaration ||
138
+ n.getKind() === SyntaxKind.FunctionDeclaration);
139
+ if (!parentMethod) {
140
+ continue;
141
+ }
142
+ const callerName = parentMethod.getName();
143
+ if (!callerName) {
144
+ continue;
145
+ }
146
+ const callerFile = parentMethod.getSourceFile().getFilePath();
147
+ const key = `${callerFile}:${callerName}`;
148
+ if (visited.has(key)) {
149
+ continue;
150
+ }
151
+ visited.add(key);
152
+ const children = this.buildCallers(parentMethod, depth - 1, new Set(visited));
153
+ callers.push({
154
+ name: callerName,
155
+ file: callerFile,
156
+ line: parentMethod.getStartLineNumber(),
157
+ children,
158
+ });
159
+ }
160
+ }
161
+ return this.deduplicateNodes(callers);
162
+ }
163
+ findDeclarationInProject(name) {
164
+ for (const sourceFile of this.project.getSourceFiles()) {
165
+ for (const cls of sourceFile.getClasses()) {
166
+ const method = cls.getMethod(name);
167
+ if (method) {
168
+ return method;
169
+ }
170
+ }
171
+ const fn = sourceFile.getFunction(name);
172
+ if (fn) {
173
+ return fn;
174
+ }
175
+ }
176
+ return null;
177
+ }
178
+ extractCallName(exprText) {
179
+ // svc.method() → method, method() → method
180
+ const parts = exprText.split('.');
181
+ const last = parts.at(-1);
182
+ return last && /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(last) ? last : null;
183
+ }
184
+ deduplicateNodes(nodes) {
185
+ const seen = new Set();
186
+ return nodes.filter((n) => {
187
+ const key = `${n.file}:${n.name}`;
188
+ if (seen.has(key)) {
189
+ return false;
190
+ }
191
+ seen.add(key);
192
+ return true;
193
+ });
194
+ }
195
+ }
196
+ //# sourceMappingURL=call-graph-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call-graph-builder.js","sourceRoot":"","sources":["../../src/investigation/call-graph-builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * @angular-modernizer/api - Codebase Searcher
3
+ *
4
+ * Searches across all source files in a ts-morph Project using three modes:
5
+ * - `text` — literal string search (case-sensitive substring)
6
+ * - `pattern` — regular-expression search
7
+ * - `symbol` — TypeScript declaration search (class, function, interface,
8
+ * enum, type alias, variable)
9
+ *
10
+ * @remarks
11
+ * The project must already have the relevant source files added before calling
12
+ * `search`. For `symbol` mode only top-level named declarations are indexed;
13
+ * local variables and anonymous expressions are not returned.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const searcher = new CodebaseSearcher(project);
18
+ *
19
+ * // Text search
20
+ * const hits = searcher.search('TODO:', { mode: 'text' });
21
+ *
22
+ * // Regex search
23
+ * const selectors = searcher.search('selector:\\s*["\']([^"\']+)["\']', { mode: 'pattern' });
24
+ *
25
+ * // Symbol search
26
+ * const classes = searcher.search('UserService', { mode: 'symbol' });
27
+ * ```
28
+ */
29
+ import type { Project } from 'ts-morph';
30
+ /** The kind of named declaration returned in symbol-mode results. */
31
+ export type SymbolKind = 'class' | 'function' | 'interface' | 'enum' | 'typeAlias' | 'variable';
32
+ /** A single search result. */
33
+ export interface SearchResult {
34
+ /** Absolute file path. */
35
+ file: string;
36
+ /** 1-based line number of the match. */
37
+ line: number;
38
+ /** 1-based column of the match start. */
39
+ col: number;
40
+ /** The source line (trimmed) containing the match. */
41
+ snippet: string;
42
+ /**
43
+ * Set in `symbol` mode to classify the declaration type.
44
+ * Absent in `text` and `pattern` modes.
45
+ */
46
+ symbolKind?: SymbolKind;
47
+ }
48
+ /** Options for `CodebaseSearcher.search()`. */
49
+ export interface SearchOptions {
50
+ /**
51
+ * - `text` — literal substring match
52
+ * - `pattern` — regular expression match
53
+ * - `symbol` — TypeScript named declaration lookup
54
+ */
55
+ mode: 'text' | 'pattern' | 'symbol';
56
+ /**
57
+ * Optional glob pattern (minimatch) to restrict which files are searched.
58
+ * E.g. `'**\/*.service.ts'`. When omitted all project source files are
59
+ * searched.
60
+ */
61
+ include?: string;
62
+ /**
63
+ * Maximum number of results to return. When omitted all matches are
64
+ * returned.
65
+ */
66
+ maxResults?: number;
67
+ }
68
+ /**
69
+ * Searches source files in a ts-morph `Project` by text, regex, or symbol
70
+ * name.
71
+ */
72
+ export declare class CodebaseSearcher {
73
+ private readonly project;
74
+ constructor(project: Project);
75
+ /**
76
+ * Search for `query` across all (filtered) source files.
77
+ *
78
+ * @param query - The text, regex pattern, or symbol name to find.
79
+ * @param options - Search mode and optional file filter / result limit.
80
+ * @returns Array of `SearchResult` objects ordered by file then line.
81
+ *
82
+ * @example
83
+ * ```typescript
84
+ * searcher.search('UserService', { mode: 'symbol' });
85
+ * searcher.search('TODO', { mode: 'text', include: 'src/**\/*.ts' });
86
+ * ```
87
+ */
88
+ search(query: string, options: SearchOptions): SearchResult[];
89
+ /**
90
+ * Text or pattern search: splits each file into lines and tests each line.
91
+ */
92
+ private searchText;
93
+ /**
94
+ * Symbol search: finds top-level named declarations whose name equals
95
+ * `query`.
96
+ */
97
+ private searchSymbols;
98
+ }
99
+ //# sourceMappingURL=codebase-searcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codebase-searcher.d.ts","sourceRoot":"","sources":["../../src/investigation/codebase-searcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAExC,qEAAqE;AACrE,MAAM,MAAM,UAAU,GAClB,OAAO,GACP,UAAU,GACV,WAAW,GACX,MAAM,GACN,WAAW,GACX,UAAU,CAAC;AAEf,8BAA8B;AAC9B,MAAM,WAAW,YAAY;IAC3B,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IAEb,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IAEb,yCAAyC;IACzC,GAAG,EAAE,MAAM,CAAC;IAEZ,sDAAsD;IACtD,OAAO,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED,+CAA+C;AAC/C,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;IAEpC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAeD;;;GAGG;AACH,qBAAa,gBAAgB;IACf,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,OAAO;IAE7C;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,YAAY,EAAE;IAoB7D;;OAEG;IACH,OAAO,CAAC,UAAU;IAqClB;;;OAGG;IACH,OAAO,CAAC,aAAa;CAwGtB"}
@@ -0,0 +1,201 @@
1
+ /**
2
+ * @angular-modernizer/api - Codebase Searcher
3
+ *
4
+ * Searches across all source files in a ts-morph Project using three modes:
5
+ * - `text` — literal string search (case-sensitive substring)
6
+ * - `pattern` — regular-expression search
7
+ * - `symbol` — TypeScript declaration search (class, function, interface,
8
+ * enum, type alias, variable)
9
+ *
10
+ * @remarks
11
+ * The project must already have the relevant source files added before calling
12
+ * `search`. For `symbol` mode only top-level named declarations are indexed;
13
+ * local variables and anonymous expressions are not returned.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const searcher = new CodebaseSearcher(project);
18
+ *
19
+ * // Text search
20
+ * const hits = searcher.search('TODO:', { mode: 'text' });
21
+ *
22
+ * // Regex search
23
+ * const selectors = searcher.search('selector:\\s*["\']([^"\']+)["\']', { mode: 'pattern' });
24
+ *
25
+ * // Symbol search
26
+ * const classes = searcher.search('UserService', { mode: 'symbol' });
27
+ * ```
28
+ */
29
+ /**
30
+ * Converts a glob pattern (`**\/*.service.ts`) to a RegExp and tests `filePath`.
31
+ * Supports `**` (any path segments) and `*` (single segment wildcard).
32
+ */
33
+ function matchesGlob(filePath, pattern) {
34
+ const escaped = pattern
35
+ .replaceAll(/[.+^${}()|[\]\\]/g, '\\$&')
36
+ .replaceAll('**', '\u0000')
37
+ .replaceAll('*', '[^/]*')
38
+ .replaceAll('\u0000', '.*');
39
+ return new RegExp(`(^|/)${escaped}$`).test(filePath);
40
+ }
41
+ /**
42
+ * Searches source files in a ts-morph `Project` by text, regex, or symbol
43
+ * name.
44
+ */
45
+ export class CodebaseSearcher {
46
+ project;
47
+ constructor(project) {
48
+ this.project = project;
49
+ }
50
+ /**
51
+ * Search for `query` across all (filtered) source files.
52
+ *
53
+ * @param query - The text, regex pattern, or symbol name to find.
54
+ * @param options - Search mode and optional file filter / result limit.
55
+ * @returns Array of `SearchResult` objects ordered by file then line.
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * searcher.search('UserService', { mode: 'symbol' });
60
+ * searcher.search('TODO', { mode: 'text', include: 'src/**\/*.ts' });
61
+ * ```
62
+ */
63
+ search(query, options) {
64
+ const sourceFiles = this.project
65
+ .getSourceFiles()
66
+ .filter((sf) => options.include === undefined ||
67
+ matchesGlob(sf.getFilePath(), options.include));
68
+ const results = options.mode === 'symbol'
69
+ ? this.searchSymbols(query, sourceFiles)
70
+ : this.searchText(query, options.mode, sourceFiles);
71
+ if (options.maxResults !== undefined) {
72
+ return results.slice(0, options.maxResults);
73
+ }
74
+ return results;
75
+ }
76
+ /**
77
+ * Text or pattern search: splits each file into lines and tests each line.
78
+ */
79
+ searchText(query, mode, sourceFiles) {
80
+ const results = [];
81
+ const regex = mode === 'pattern' ? new RegExp(query) : null;
82
+ for (const sf of sourceFiles) {
83
+ const filePath = sf.getFilePath();
84
+ const lines = sf.getFullText().split('\n');
85
+ lines.forEach((lineText, index) => {
86
+ const matched = regex === null ? lineText.includes(query) : regex.test(lineText);
87
+ if (!matched) {
88
+ return;
89
+ }
90
+ const col = regex === null
91
+ ? lineText.indexOf(query) + 1
92
+ : lineText.search(regex) + 1;
93
+ results.push({
94
+ file: filePath,
95
+ line: index + 1,
96
+ col,
97
+ snippet: lineText.trim(),
98
+ });
99
+ });
100
+ }
101
+ return results;
102
+ }
103
+ /**
104
+ * Symbol search: finds top-level named declarations whose name equals
105
+ * `query`.
106
+ */
107
+ searchSymbols(query, sourceFiles) {
108
+ const results = [];
109
+ for (const sf of sourceFiles) {
110
+ const filePath = sf.getFilePath();
111
+ // Classes
112
+ for (const decl of sf.getClasses()) {
113
+ if (decl.getName() === query) {
114
+ const pos = decl.getNameNode()?.getStart() ?? decl.getStart();
115
+ const { line, column } = sf.getLineAndColumnAtPos(pos);
116
+ results.push({
117
+ file: filePath,
118
+ line,
119
+ col: column,
120
+ snippet: (decl.getText().split('\n')[0] ?? '').trim(),
121
+ symbolKind: 'class',
122
+ });
123
+ }
124
+ }
125
+ // Functions
126
+ for (const decl of sf.getFunctions()) {
127
+ if (decl.getName() === query) {
128
+ const pos = decl.getNameNode()?.getStart() ?? decl.getStart();
129
+ const { line, column } = sf.getLineAndColumnAtPos(pos);
130
+ results.push({
131
+ file: filePath,
132
+ line,
133
+ col: column,
134
+ snippet: (decl.getText().split('\n')[0] ?? '').trim(),
135
+ symbolKind: 'function',
136
+ });
137
+ }
138
+ }
139
+ // Interfaces
140
+ for (const decl of sf.getInterfaces()) {
141
+ if (decl.getName() === query) {
142
+ const pos = decl.getNameNode().getStart();
143
+ const { line, column } = sf.getLineAndColumnAtPos(pos);
144
+ results.push({
145
+ file: filePath,
146
+ line,
147
+ col: column,
148
+ snippet: (decl.getText().split('\n')[0] ?? '').trim(),
149
+ symbolKind: 'interface',
150
+ });
151
+ }
152
+ }
153
+ // Enums
154
+ for (const decl of sf.getEnums()) {
155
+ if (decl.getName() === query) {
156
+ const pos = decl.getNameNode().getStart();
157
+ const { line, column } = sf.getLineAndColumnAtPos(pos);
158
+ results.push({
159
+ file: filePath,
160
+ line,
161
+ col: column,
162
+ snippet: (decl.getText().split('\n')[0] ?? '').trim(),
163
+ symbolKind: 'enum',
164
+ });
165
+ }
166
+ }
167
+ // Type aliases
168
+ for (const decl of sf.getTypeAliases()) {
169
+ if (decl.getName() === query) {
170
+ const pos = decl.getNameNode().getStart();
171
+ const { line, column } = sf.getLineAndColumnAtPos(pos);
172
+ results.push({
173
+ file: filePath,
174
+ line,
175
+ col: column,
176
+ snippet: (decl.getText().split('\n')[0] ?? '').trim(),
177
+ symbolKind: 'typeAlias',
178
+ });
179
+ }
180
+ }
181
+ // Variables (top-level const/let/var declarations)
182
+ for (const varStmt of sf.getVariableStatements()) {
183
+ for (const decl of varStmt.getDeclarations()) {
184
+ if (decl.getName() === query) {
185
+ const pos = decl.getNameNode().getStart();
186
+ const { line, column } = sf.getLineAndColumnAtPos(pos);
187
+ results.push({
188
+ file: filePath,
189
+ line,
190
+ col: column,
191
+ snippet: (varStmt.getText().split('\n')[0] ?? '').trim(),
192
+ symbolKind: 'variable',
193
+ });
194
+ }
195
+ }
196
+ }
197
+ }
198
+ return results;
199
+ }
200
+ }
201
+ //# sourceMappingURL=codebase-searcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codebase-searcher.js","sourceRoot":"","sources":["../../src/investigation/codebase-searcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAyDH;;;GAGG;AACH,SAAS,WAAW,CAAC,QAAgB,EAAE,OAAe;IACpD,MAAM,OAAO,GAAG,OAAO;SACpB,UAAU,CAAC,mBAAmB,EAAE,MAAM,CAAC;SACvC,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC;SAC1B,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC;SACxB,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC9B,OAAO,IAAI,MAAM,CAAC,QAAQ,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AACvD,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,gBAAgB;IACE;IAA7B,YAA6B,OAAgB;QAAhB,YAAO,GAAP,OAAO,CAAS;IAAI,CAAC;IAElD;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,KAAa,EAAE,OAAsB;QAC1C,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO;aAC7B,cAAc,EAAE;aAChB,MAAM,CACL,CAAC,EAAE,EAAE,EAAE,CACL,OAAO,CAAC,OAAO,KAAK,SAAS;YAC7B,WAAW,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,CACjD,CAAC;QAEJ,MAAM,OAAO,GACX,OAAO,CAAC,IAAI,KAAK,QAAQ;YACvB,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,WAAW,CAAC;YACxC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAExD,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YACrC,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACK,UAAU,CAChB,KAAa,EACb,IAAwB,EACxB,WAAkD;QAElD,MAAM,OAAO,GAAmB,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAE5D,KAAK,MAAM,EAAE,IAAI,WAAW,EAAE,CAAC;YAC7B,MAAM,QAAQ,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC;YAClC,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAE3C,KAAK,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE;gBAChC,MAAM,OAAO,GACX,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAEnE,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,OAAO;gBACT,CAAC;gBAED,MAAM,GAAG,GACP,KAAK,KAAK,IAAI;oBACZ,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC;oBAC7B,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAEjC,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,KAAK,GAAG,CAAC;oBACf,GAAG;oBACH,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE;iBACzB,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;OAGG;IACK,aAAa,CACnB,KAAa,EACb,WAAkD;QAElD,MAAM,OAAO,GAAmB,EAAE,CAAC;QAEnC,KAAK,MAAM,EAAE,IAAI,WAAW,EAAE,CAAC;YAC7B,MAAM,QAAQ,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC;YAElC,UAAU;YACV,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC;gBACnC,IAAI,IAAI,CAAC,OAAO,EAAE,KAAK,KAAK,EAAE,CAAC;oBAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;oBAC9D,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC;oBACvD,OAAO,CAAC,IAAI,CAAC;wBACX,IAAI,EAAE,QAAQ;wBACd,IAAI;wBACJ,GAAG,EAAE,MAAM;wBACX,OAAO,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;wBACrD,UAAU,EAAE,OAAO;qBACpB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAED,YAAY;YACZ,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC,YAAY,EAAE,EAAE,CAAC;gBACrC,IAAI,IAAI,CAAC,OAAO,EAAE,KAAK,KAAK,EAAE,CAAC;oBAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;oBAC9D,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC;oBACvD,OAAO,CAAC,IAAI,CAAC;wBACX,IAAI,EAAE,QAAQ;wBACd,IAAI;wBACJ,GAAG,EAAE,MAAM;wBACX,OAAO,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;wBACrD,UAAU,EAAE,UAAU;qBACvB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAED,aAAa;YACb,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC,aAAa,EAAE,EAAE,CAAC;gBACtC,IAAI,IAAI,CAAC,OAAO,EAAE,KAAK,KAAK,EAAE,CAAC;oBAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,CAAC;oBAC1C,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC;oBACvD,OAAO,CAAC,IAAI,CAAC;wBACX,IAAI,EAAE,QAAQ;wBACd,IAAI;wBACJ,GAAG,EAAE,MAAM;wBACX,OAAO,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;wBACrD,UAAU,EAAE,WAAW;qBACxB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAED,QAAQ;YACR,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC;gBACjC,IAAI,IAAI,CAAC,OAAO,EAAE,KAAK,KAAK,EAAE,CAAC;oBAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,CAAC;oBAC1C,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC;oBACvD,OAAO,CAAC,IAAI,CAAC;wBACX,IAAI,EAAE,QAAQ;wBACd,IAAI;wBACJ,GAAG,EAAE,MAAM;wBACX,OAAO,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;wBACrD,UAAU,EAAE,MAAM;qBACnB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAED,eAAe;YACf,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC;gBACvC,IAAI,IAAI,CAAC,OAAO,EAAE,KAAK,KAAK,EAAE,CAAC;oBAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,CAAC;oBAC1C,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC;oBACvD,OAAO,CAAC,IAAI,CAAC;wBACX,IAAI,EAAE,QAAQ;wBACd,IAAI;wBACJ,GAAG,EAAE,MAAM;wBACX,OAAO,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;wBACrD,UAAU,EAAE,WAAW;qBACxB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAED,mDAAmD;YACnD,KAAK,MAAM,OAAO,IAAI,EAAE,CAAC,qBAAqB,EAAE,EAAE,CAAC;gBACjD,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC;oBAC7C,IAAI,IAAI,CAAC,OAAO,EAAE,KAAK,KAAK,EAAE,CAAC;wBAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,CAAC;wBAC1C,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC;wBACvD,OAAO,CAAC,IAAI,CAAC;4BACX,IAAI,EAAE,QAAQ;4BACd,IAAI;4BACJ,GAAG,EAAE,MAAM;4BACX,OAAO,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;4BACxD,UAAU,EAAE,UAAU;yBACvB,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * @angular-modernizer/api - Stack Trace Parser
3
+ *
4
+ * Parses Node.js/Angular/Zone.js/browser stack traces and maps frames to project source files.
5
+ *
6
+ * @remarks
7
+ * Frames are classified as project files when their resolved path starts with `projectRoot`
8
+ * and does not pass through `node_modules`. Browser URL frames (http/https) are always
9
+ * classified as non-project files regardless of origin.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * const parser = new StackTraceParser('/my/project/src');
14
+ * const frames = parser.parse(error.stack ?? '');
15
+ * // frames[0].file → '/my/project/src/app/user.service.ts'
16
+ * // frames[0].isProjectFile → true
17
+ *
18
+ * const projectOnly = parser.parseProjectFrames(error.stack ?? '');
19
+ * ```
20
+ */
21
+ /** A single resolved stack frame. */
22
+ export interface StackFrame {
23
+ /** Absolute file path. For browser URL frames, the raw URL string. */
24
+ file: string;
25
+ /** 1-based line number. */
26
+ line: number;
27
+ /** 1-based column number. */
28
+ col: number;
29
+ /** Function or method name. `'<anonymous>'` when not present. */
30
+ functionName: string;
31
+ /**
32
+ * `true` when the frame's path starts with `projectRoot`
33
+ * and does not pass through `node_modules`.
34
+ */
35
+ isProjectFile: boolean;
36
+ }
37
+ /**
38
+ * Parses Node.js/Angular/Zone.js/browser stack traces into structured frames.
39
+ */
40
+ export declare class StackTraceParser {
41
+ private readonly projectRoot;
42
+ /**
43
+ * @param projectRoot - Absolute path to the project root used to classify
44
+ * frames as project files vs. external dependencies.
45
+ */
46
+ constructor(projectRoot: string);
47
+ /**
48
+ * Parses a raw stack trace string into an array of structured frames.
49
+ *
50
+ * @param stackTrace - Raw `Error.stack` string or console-captured stack trace.
51
+ * @returns All frames found, including non-project frames.
52
+ */
53
+ parse(stackTrace: string): StackFrame[];
54
+ /**
55
+ * Parses a stack trace and returns only frames that belong to the project.
56
+ *
57
+ * @param stackTrace - Raw `Error.stack` string or console-captured stack trace.
58
+ * @returns Frames where `isProjectFile` is `true`.
59
+ */
60
+ parseProjectFrames(stackTrace: string): StackFrame[];
61
+ private parseLine;
62
+ private buildFrame;
63
+ private isProjectFile;
64
+ /**
65
+ * Strips the `async ` prefix that ts-jest/V8 sometimes leaves in function names
66
+ * when the regex group captures it as part of the name rather than the keyword.
67
+ */
68
+ private sanitizeFunctionName;
69
+ }
70
+ //# sourceMappingURL=stack-trace-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack-trace-parser.d.ts","sourceRoot":"","sources":["../../src/investigation/stack-trace-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,qCAAqC;AACrC,MAAM,WAAW,UAAU;IACzB,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAC;IAEb,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC;IAEb,6BAA6B;IAC7B,GAAG,EAAE,MAAM,CAAC;IAEZ,iEAAiE;IACjE,YAAY,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,aAAa,EAAE,OAAO,CAAC;CACxB;AAqBD;;GAEG;AACH,qBAAa,gBAAgB;IAKf,OAAO,CAAC,QAAQ,CAAC,WAAW;IAJxC;;;OAGG;gBAC0B,WAAW,EAAE,MAAM;IAEhD;;;;;OAKG;IACH,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,EAAE;IAiBvC;;;;;OAKG;IACH,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,EAAE;IAIpD,OAAO,CAAC,SAAS;IA0BjB,OAAO,CAAC,UAAU;IAelB,OAAO,CAAC,aAAa;IAUrB;;;OAGG;IACH,OAAO,CAAC,oBAAoB;CAM7B"}