import type { FigmaNode, ParsedFigmaData } from './parser.js'; import type { VariableDef } from './bounds-cache.js'; import { type InferredLayout } from './layout-inference.js'; /** A value that may reference a Figma Variable */ export type VarRef = { $ref: string; raw: string | number; }; export interface EnrichedASTNode { nodeId: string; name: string; type: string; /** Figma component ID — same ID means instances of the same component */ componentId?: string; /** Structural fingerprint for similarity detection (type-tree, depth 3) */ structureFingerprint?: string; bounds: { x: number; y: number; width: number; height: number; }; layout: InferredLayout; style?: { backgroundColor?: string | VarRef; borderRadius?: number | string | VarRef; opacity?: number; overflow?: string; boxShadow?: string; border?: string; }; text?: { content: string; fontFamily?: string; fontSize?: number; fontWeight?: number | string; color?: string; lineHeight?: number | string; letterSpacing?: number | string; textAlign?: string; /** Rich text segments with mixed styles (e.g. highlighted words) */ styledSegments?: Array<{ text: string; color?: string; fontWeight?: number | string; fontFamily?: string; fontSize?: number; fontStyle?: string; textDecoration?: string; }>; }; image?: { type: 'raster' | 'vector' | 'svg'; imageRef?: string; suggestedFormat: 'png' | 'svg' | 'jpg'; }; flags?: { isGraphicSubtree?: boolean; needsDetailFetch?: boolean; isInvisible?: boolean; hasComplexFills?: boolean; /** This node uses position:absolute to overlay on top of sibling (negative-gap pattern) */ isAbsoluteOverlay?: boolean; }; children?: EnrichedASTNode[]; } export interface EnrichedASTStats { totalNodes: number; figmaLayoutNodes: number; inferredLayoutNodes: number; absoluteNodes: number; needsDetailFetch: number; } export interface VariableStatEntry { variableName: string; count: number; sampleNodeIds: string[]; } export interface EnrichedAST { version: '1.0'; fileKey: string; rootNodeId: string; viewport: { width: number; height: number; }; stats: EnrichedASTStats; variableStats?: VariableStatEntry[]; root: EnrichedASTNode; } /** * Resolves VariableIDs to variable names using the variable definition table. */ export declare class VariableMatcher { private defs; constructor(defs: Record); /** Resolve a VariableID to its semantic name, or undefined if not found */ resolve(variableId: string): string | undefined; } /** * Wrap a raw value with a $ref if the variable binding exists and can be resolved. */ export declare function wrapWithRef(rawValue: T, variableId: string | undefined, matcher: VariableMatcher | undefined): T | VarRef; /** * Generate a structural fingerprint for a FigmaNode subtree. * Used for detecting structurally similar components. * * Format: TEXT → "T", IMAGE/GRAPHIC → "I", FRAME → "F[dir](child1,child2,...)" * Depth limited to maxDepth (default 3), beyond which "*" is used. */ export declare function generateFingerprint(node: FigmaNode, depth?: number, maxDepth?: number): string; /** * Traverse an EnrichedAST and collect all $ref variable names that appear. */ export declare function collectVariableStats(root: EnrichedASTNode): VariableStatEntry[]; /** * Build an EnrichedAST from a ParsedFigmaData node tree. * The nodeTree should already have _absX/_absY injected (from injectBounds). */ export declare function enrichAST(nodeTree: ParsedFigmaData, fileKey: string, rootNodeId: string, variableDefs?: Record): EnrichedAST; //# sourceMappingURL=ast-enricher.d.ts.map