@ttwtf/ng-parser
Version:
Advanced Angular parser with RAG-optimized output and extensible visitor architecture
610 lines (462 loc) • 17.6 kB
Markdown
# ng-parser
Advanced Angular parser with RAG-optimized output and extensible visitor architecture.
[](https://opensource.org/licenses/MIT)
## Features
- 🔍 **Deep Angular Analysis** - Components, Services, Modules, Directives, Pipes
- 🧩 **Two-Layer Architecture** - Core parsing + Extensible custom visitors
- 🎯 **Modern Angular Support** - Standalone components, Signals (Angular 18-20)
- 📊 **Knowledge Graph** - Entities, relationships, hierarchical clustering
- 🎨 **Template & Style Analysis** - Parse HTML templates and SCSS files with full dependency tracking
- 🌐 **Git Integration** - Automatic source URLs for GitHub, GitLab, Bitbucket, Azure DevOps
- 🎯 **Global Styles** - Auto-detect and parse global SCSS files (styles.scss, theme.scss, etc.)
- 🤖 **RAG Optimized** - JSON outputs optimized for LLM consumption
- ⚡ **Maintainable** - Built on official @angular/compiler-cli
- 🔌 **Extensible** - Create custom visitors for your analysis needs
- 🛡️ **Built-in Visitors** - RxJS patterns, Security, Performance analysis
## Installation
```bash
npm install @ttwtf/ng-parser
```
**Peer Dependencies** (automatically uses your project's Angular version):
```bash
npm install @angular/compiler @angular/compiler-cli @angular/core
```
**Supported versions**: Angular 18.x, 19.x, 20.x
## Quick Start
### CLI (Recommended)
```bash
# Parse an Angular project (core parsing only, fastest)
ng-parser parse ./src
# Enable specific visitors
ng-parser parse ./src --visitors rxjs,security
# Export to file
ng-parser parse ./src -o analysis.json
# Export all formats (JSON, SimpleJSON, HTML)
ng-parser parse ./src -f all -o ./output/my-project
```
See [CLI Documentation](./CLI.md) for complete CLI reference.
### Programmatic API
```typescript
import { NgParser } from '@ttwtf/ng-parser';
const parser = new NgParser({ rootDir: './src' });
const result = await parser.parse();
console.log(`Found ${result.metadata.totalEntities} Angular entities`);
console.log(`Found ${result.metadata.totalRelationships} relationships`);
// Access parsed entities
for (const entity of result.entities.values()) {
console.log(`[${entity.type}] ${entity.name}`);
}
```
### With Built-in Visitors
```typescript
import {
NgParser,
RxJSPatternVisitor,
SecurityVisitor,
PerformanceVisitor
} from '@ttwtf/ng-parser';
const parser = new NgParser({ rootDir: './src' });
// Register pattern extraction visitors
parser.registerVisitor(new RxJSPatternVisitor());
parser.registerVisitor(new SecurityVisitor());
parser.registerVisitor(new PerformanceVisitor());
const result = await parser.parse();
// Access visitor results (raw patterns, not evaluations)
const rxjsResults = result.customAnalysis.get('RxJSPatternVisitor');
console.log(`RxJS observables found: ${rxjsResults.totalObservables}`);
console.log(`In components: ${rxjsResults.observablesInComponents}`);
const securityResults = result.customAnalysis.get('SecurityVisitor');
console.log(`Security patterns found: ${securityResults.totalPatterns}`);
console.log(`By pattern:`, securityResults.byPattern);
```
### Export to Multiple Formats
```typescript
// JSON export (complete data, optimized)
const json = result.toJSON();
// SimpleJSON export (ng-analyzer compatible)
const simple = result.toSimpleJSON();
// HTML export (interactive D3.js visualization)
const html = result.toHTML();
```
## Two-Layer Architecture
ng-parser uses a **strict two-layer separation** between parsing and analysis:
### Layer 1: Core Angular Parsers (Built-in, Non-Extensible)
**Pure extraction** of Angular concepts with guaranteed quality:
- ✅ **ComponentParser** - Standalone, signals, inputs/outputs, lifecycle
- ✅ **ServiceParser** - Dependency injection, providedIn
- ✅ **ModuleParser** - Declarations, imports, exports, providers
- ✅ **DirectiveParser** - Inputs, outputs, standalone
- ✅ **PipeParser** - Pure/impure, standalone
- ✅ **TemplateParser** - HTML template analysis (inline & external)
- ✅ **StyleParser** - SCSS `@import` and `@use` extraction
- ✅ **GitRemoteParser** - Git repository detection and source URL generation
**Role:** Transform source code → structured data (AST, entities, relationships)
### Layer 2: Custom Visitors (Extensible, User-Defined)
**Pattern extraction** from parsed entities - NO evaluation or recommendations:
- **RxJSPatternVisitor** - Extracts Observable/Subject usage and lifecycle hooks
- **SecurityVisitor** - Extracts innerHTML, eval(), HTTP URLs, potential secrets
- **PerformanceVisitor** - Extracts change detection, trackBy, imports, constructors
**Role:** Extract additional patterns → structured facts (no judgments)
> **Important:** Visitors perform **extraction only**. They don't evaluate severity, don't recommend fixes, and don't judge code quality. They simply identify and categorize patterns. Analysis/evaluation tools can be built on top of the extracted data.
**Create your own visitors** to extract domain-specific patterns!
## Built-in Visitors
### RxJSPatternVisitor
Extracts RxJS usage patterns:
```typescript
const rxjsResults = result.customAnalysis.get('RxJSPatternVisitor');
console.log(`Total observables: ${rxjsResults.totalObservables}`);
console.log(`In components: ${rxjsResults.observablesInComponents}`);
console.log(`Components with ngOnDestroy:`, rxjsResults.componentsWithNgOnDestroy);
console.log(`Components without ngOnDestroy:`, rxjsResults.componentsWithoutNgOnDestroy);
// Access individual patterns
rxjsResults.patterns.forEach(pattern => {
console.log(`${pattern.type} in ${pattern.entityName} - has ngOnDestroy: ${pattern.hasNgOnDestroy}`);
});
```
**Extracts:**
- Observable/Subject/BehaviorSubject/ReplaySubject properties
- Component lifecycle (presence of ngOnDestroy)
- Location of each pattern
### SecurityVisitor
Extracts security-relevant patterns:
```typescript
const securityResults = result.customAnalysis.get('SecurityVisitor');
console.log(`Total patterns: ${securityResults.totalPatterns}`);
console.log(`By pattern:`, securityResults.byPattern);
// Example output: { innerHTML: 3, eval: 1, potential_secret: 2, http_url: 5 }
```
**Extracts:**
- innerHTML/outerHTML usage
- bypassSecurityTrust* calls
- eval() and Function() usage
- HTTP URLs (non-HTTPS)
- Potential hardcoded secrets (API keys, passwords, tokens)
- XSRF protection configuration
### PerformanceVisitor
Extracts performance-relevant patterns:
```typescript
const perfResults = result.customAnalysis.get('PerformanceVisitor');
console.log(`Total patterns: ${perfResults.totalPatterns}`);
console.log(`By pattern:`, perfResults.byPattern);
// Example output:
// {
// change_detection_default: 15,
// ngfor_without_trackby: 8,
// function_in_template: 3
// }
```
**Extracts:**
- Change detection strategy (Default/OnPush)
- *ngFor with/without trackBy
- Function calls in templates
- HTTP calls in constructors
- Loops in constructors
- Large library imports (lodash, moment, rxjs)
- Array operation chains
- Storage operations in loops
## Advanced Features
### Template Analysis
Parse both inline and external HTML templates automatically:
```typescript
// Component with external template
@Component({
templateUrl: './my-component.html',
// ...
})
// Parser automatically extracts:
const component = result.entities.get('component:...:MyComponent');
console.log(component.templateLocation); // File path + Git URL
console.log(component.templateAnalysis); // Analysis results
```
**Extracted data:**
- **Used components**: Custom component selectors found in template
- **Used directives**: Structural (`*ngIf`, `*ngFor`) and attribute directives
- **Used pipes**: All pipes with names (`| date`, `| async`, custom pipes)
- **Bindings**: Property `[prop]`, event `(click)`, two-way `[(ngModel)]`, etc.
- **Template refs**: `#myRef` references
- **Complexity score**: Based on nesting depth and structural directives
```json
{
"templateAnalysis": {
"usedComponents": ["app-child", "app-card"],
"usedDirectives": ["*ngIf", "*ngFor", "appHighlight"],
"usedPipes": ["date", "async", "customPipe"],
"bindings": [
{"type": "property", "name": "disabled", "expression": "!isValid"},
{"type": "event", "name": "click", "expression": "onSave()"}
],
"templateRefs": ["form", "input"],
"complexity": 85
}
}
```
### Style Analysis
Parse SCSS files and extract dependencies:
```typescript
// Component with styles
@Component({
styleUrls: [
'./my-component.scss',
'./my-component-responsive.scss'
]
})
// Parser extracts all @import and @use statements
const component = result.entities.get('component:...:MyComponent');
console.log(component.styleAnalysis);
```
**Extracted data:**
- **@import statements**: Path, full statement, line number, resolved path
- **@use statements**: Path, namespace, statement, line number, resolved path
- **File locations**: All style files with Git URLs
```json
{
"styleAnalysis": {
"files": [
{
"filePath": "src/app/components/my-component.scss",
"sourceUrl": "https://github.com/.../my-component.scss",
"imports": [
{
"path": "../styles/mixins",
"statement": "@import '../styles/mixins'",
"line": 3
}
],
"uses": [
{
"path": "../styles/variables",
"statement": "@use '../styles/variables' as vars",
"namespace": "vars",
"line": 1
}
]
}
]
}
}
```
### Global Styles
Automatically detects and parses global SCSS files:
**Auto-detected files** (no configuration needed):
- `styles.scss`, `style.scss`
- `theme.scss`
- `variables.scss`, `_variables.scss`
**Searched locations:**
- Project root
- `src/` directory
```typescript
const result = await parser.parse();
console.log(result.metadata.globalStyles);
```
```json
{
"metadata": {
"globalStyles": [
{
"filePath": "src/styles.scss",
"sourceUrl": "https://github.com/.../src/styles.scss",
"imports": [
{"path": "./theme", "statement": "@import './theme'", "line": 2}
],
"uses": [
{"path": "sass:color", "statement": "@use 'sass:color'", "line": 1}
]
}
]
}
}
```
### Git Integration
Automatic Git repository detection with source URLs:
**Supported providers:**
- GitHub
- GitLab
- Bitbucket
- Azure DevOps
**Features:**
- Auto-detects repository from `.git` directory
- Generates source URLs for all files
- Line-specific URLs for entities (e.g., `#L42`)
- Branch-aware URLs
- Works with SSH and HTTPS remotes
```typescript
const result = await parser.parse();
console.log(result.metadata.repository);
// {
// provider: 'github',
// url: 'https://github.com/user/repo',
// branch: 'main',
// rootDir: '/path/to/project'
// }
// All entities include source URLs
const entity = result.entities.get('component:...:MyComponent');
console.log(entity.location.sourceUrl);
// "https://github.com/user/repo/blob/main/src/app/my-component.ts#L15"
```
## Creating Custom Visitors
Extend ng-parser with your own pattern extraction:
```typescript
import { BaseVisitor, type VisitorContext, type Entity } from '@ttwtf/ng-parser';
import * as ts from 'typescript';
interface MyPattern {
pattern: 'my_pattern_type';
entityName: string;
location: any;
}
interface MyResult {
patterns: MyPattern[];
totalPatterns: number;
}
class MyCustomVisitor extends BaseVisitor<MyResult> {
readonly name = 'MyCustomVisitor';
readonly description = 'Extracts custom patterns';
readonly priority = 50;
readonly version = '1.0.0';
private patterns: MyPattern[] = [];
// Visit TypeScript AST nodes to extract patterns
async visitNode(node: ts.Node, context: VisitorContext): Promise<void> {
if (ts.isClassDeclaration(node)) {
// Extract pattern - NO evaluation
this.patterns.push({
pattern: 'my_pattern_type',
entityName: node.name?.getText() || 'unknown',
location: { /* ... */ }
});
}
}
// Visit Angular entities to extract patterns
async visitEntity(entity: Entity, context: VisitorContext): Promise<void> {
if (entity.type === 'component') {
// Extract fact about component
const hasTemplate = !!entity.template;
// Store the FACT, don't evaluate if it's good/bad
}
}
getResults(): MyResult {
return {
patterns: this.patterns,
totalPatterns: this.patterns.length
};
}
reset(): void {
super.reset();
this.patterns = [];
}
}
// Use it
parser.registerVisitor(new MyCustomVisitor());
```
**Remember:** Visitors should **extract patterns**, not evaluate them. Leave analysis and recommendations to separate tools that consume the extracted data.
## Export Formats
### JSON Export
Complete data export with all information:
```typescript
const json = result.toJSON();
```
**Contains:** All entities, relationships, metadata, custom analysis, warnings, errors, metrics
**Optimizations:**
- Removes empty arrays and default values
- Optimized entity structure
- Ready for LLM consumption
### SimpleJSON Export
ng-analyzer compatible format:
```typescript
const simple = result.toSimpleJSON();
```
**Features:**
- Simplified structure for basic analysis
- Compatible with legacy ng-analyzer tools
- Lightweight output
### HTML Export
Interactive visualization with D3.js:
```typescript
const html = result.toHTML();
```
**Features:**
- 🎨 Interactive D3.js force-directed dependency graph
- 🔍 Searchable entity explorer
- 📊 Visitor results dashboards (RxJS, Security, Performance)
- 🔗 Clickable Git source URLs
- 📱 Responsive design (mobile-friendly)
- 💾 Self-contained (works offline, no build required)
**Use cases:**
- Team onboarding - Visual learning for new developers
- Architecture presentations - Interactive demos in meetings
- Code reviews - Shareable offline documentation
- CI/CD docs - Auto-generated project documentation
## Examples
Complete working examples in `examples/`:
| Example | Description |
|---------|-------------|
| **01-quick-start.ts** | Basic parsing with built-in visitors |
| **02-custom-visitors.ts** | Creating custom analysis visitors |
| **03-complete-analysis.ts** | Complete workflow with all features |
Run examples:
```bash
# Quick start
npx ts-node examples/01-quick-start.ts
# Custom visitors
npx ts-node examples/02-custom-visitors.ts
# Complete analysis
npx ts-node examples/03-complete-analysis.ts
```
## Configuration
```typescript
const parser = new NgParser({
rootDir: './src', // Required: source directory
includeTests: false, // Optional: include test files
maxDepth: 20, // Optional: directory depth limit
});
```
## Use Cases
- 🤖 **RAG/LLM Training** - Generate structured documentation for AI models
- 📊 **Code Analysis Foundations** - Extract patterns for analysis tools to evaluate
- 🔍 **Codebase Exploration** - Understand large Angular projects structure
- 🔒 **Security Pattern Detection** - Identify security-relevant code for auditing tools
- ⚡ **Performance Pattern Detection** - Extract patterns for performance analysis
- 📝 **Documentation** - Auto-generate architecture docs from parsed entities
- 🔄 **Migration Analysis** - Extract patterns to prepare for Angular upgrades
- 🏗️ **Analysis Tool Development** - Build custom analyzers on top of extracted data
## Requirements
- **Node.js** ≥ 18.0.0
- **TypeScript** ≥ 5.4.0
- **Angular** ≥ 18.0.0 (peer dependency)
## Documentation
- **[CLI Documentation](./CLI.md)** - Command-line interface reference
- **[Getting Started Guide](./GETTING_STARTED.md)** - Step-by-step tutorial
- **[Examples](./examples/README.md)** - Complete examples with sample app
- **[Architecture Guide](./ARCHITECTURE.md)** - Two-layer architecture explained
- **[Code Review Standards](./CODE_REVIEW.md)** - Quality standards
- **[API Reference](./API_REFERENCE.md)** - Complete API documentation
- **[Changelog](./CHANGELOG.md)** - Version history
## Version Strategy
ng-parser uses **peerDependencies** to support multiple Angular versions with a single codebase:
- ✅ Your project's Angular version is automatically used
- ✅ No version conflicts
- ✅ Supports Angular 18, 19, and 20
- ✅ Minimal maintenance overhead
## FAQ
**Q: Can I analyze a specific file instead of the whole project?**
Currently ng-parser works at the project level. For single-file analysis, use TypeScript Compiler API directly.
**Q: What if I only want specific visitors?**
Only register the visitors you need:
```typescript
parser.registerVisitor(new SecurityVisitor()); // Only security analysis
```
**Q: How do I access specific entity types?**
```typescript
const components = Array.from(result.entities.values())
.filter(e => e.type === 'component');
```
**Q: Can I use this in a CI/CD pipeline?**
Yes! ng-parser works great in automated workflows for code quality checks.
## Contributing
Contributions welcome! Please read our [Code Review Standards](./CODE_REVIEW.md) before submitting PRs.
## License
MIT © [Your Name]
## Support
- 📖 [Full Documentation](./examples/README.md)
- 🐛 [Report Issues](https://github.com/your-repo/ng-parser/issues)
- 💬 [Discussions](https://github.com/your-repo/ng-parser/discussions)
**Made with ❤️ for the Angular community**