| 26 | * importable). |
| 27 | */ |
| 28 | export class AstroExtractor { |
| 29 | private filePath: string; |
| 30 | private source: string; |
| 31 | private nodes: Node[] = []; |
| 32 | private edges: Edge[] = []; |
| 33 | private unresolvedReferences: UnresolvedReference[] = []; |
| 34 | private errors: ExtractionError[] = []; |
| 35 | |
| 36 | constructor(filePath: string, source: string) { |
| 37 | this.filePath = filePath; |
| 38 | this.source = source; |
| 39 | } |
| 40 | |
| 41 | /** |
| 42 | * Extract from Astro source |
| 43 | */ |
| 44 | extract(): ExtractionResult { |
| 45 | const startTime = Date.now(); |
| 46 | |
| 47 | try { |
| 48 | // Create component node for the .astro file itself |
| 49 | const componentNode = this.createComponentNode(); |
| 50 | |
| 51 | // Extract and process the frontmatter block (--- fenced, TypeScript) |
| 52 | const frontmatter = this.extractFrontmatter(); |
| 53 | if (frontmatter) { |
| 54 | this.processScriptContent(frontmatter, componentNode.id, 'frontmatter'); |
| 55 | } |
| 56 | |
| 57 | // Extract and process <script> blocks (client-side, TypeScript-capable) |
| 58 | for (const block of this.extractScriptBlocks()) { |
| 59 | this.processScriptContent(block, componentNode.id, 'script'); |
| 60 | } |
| 61 | |
| 62 | // Ranges the template scans must skip: frontmatter + <script>/<style> |
| 63 | const coveredRanges = this.getCoveredRanges(frontmatter); |
| 64 | |
| 65 | // Extract function calls from template expressions ({fn(...)}) |
| 66 | this.extractTemplateCalls(componentNode.id, coveredRanges); |
| 67 | |
| 68 | // Extract component usages from template (<ComponentName>) |
| 69 | this.extractTemplateComponents(componentNode.id, coveredRanges); |
| 70 | } catch (error) { |
| 71 | this.errors.push({ |
| 72 | message: `Astro extraction error: ${error instanceof Error ? error.message : String(error)}`, |
| 73 | severity: 'error', |
| 74 | code: 'parse_error', |
| 75 | }); |
| 76 | } |
| 77 | |
| 78 | return { |
| 79 | nodes: this.nodes, |
| 80 | edges: this.edges, |
| 81 | unresolvedReferences: this.unresolvedReferences, |
| 82 | errors: this.errors, |
| 83 | durationMs: Date.now() - startTime, |
| 84 | }; |
| 85 | } |
nothing calls this directly
no outgoing calls
no test coverage detected