import type { BulkStructureEntityType, BulkStructureNode, BulkStructureParseResult, BulkStructureRoot } from '../types/bulkStructure'; /** * Parses bulk text into a generic hierarchical structure. * * The parser is responsible for: * * - reading indentation * - determining the entity type from the indentation level * - validating hierarchy * - building parent/child relationships * * It does not generate ranks, IDs or GraphQL payloads and does not * persist anything. Those responsibilities belong to later layers. * * Example with rootType = 'phase': * * Input: * * Phase 1 * Milestone 1 * Activity 1 * Task 1 * Activity 2 * Phase 2 * * Output: * * { * valid: true, * errors: [], * data: [ * { * type: 'phase', * name: 'Phase 1', * children: [ * { * type: 'milestone', * name: 'Milestone 1', * children: [ * { * type: 'activity', * name: 'Activity 1', * children: [ * { * type: 'task', * name: 'Task 1', * children: [] * } * ] * }, * { * type: 'activity', * name: 'Activity 2', * children: [] * } * ] * } * ] * }, * { * type: 'phase', * name: 'Phase 2', * children: [] * } * ] * } * * nodesAtLevel keeps track of the latest valid node at every depth. * * After: * * Phase 1 * Milestone 1 * Activity 1 * * it contains: * * nodesAtLevel[0] = Phase 1 * nodesAtLevel[1] = Milestone 1 * nodesAtLevel[2] = Activity 1 * * If another activity is encountered at level 2, its parent is simply * nodesAtLevel[1], which is the current milestone. * * nodesAtLevel.length = level + 1 removes stale deeper nodes whenever * the parser moves back up the hierarchy. * * It also allows skipped hierarchy to be detected. * * Example: * * Phase 1 * Activity 1 * * Activity 1 is level 2 but nodesAtLevel[1] does not exist, so the * parser returns EXPECTED_PARENT_BEFORE for the missing milestone. */ export declare function parseBulkStructure(text: string, rootType: BulkStructureRoot): BulkStructureParseResult; /** * Flattens the parsed hierarchy into a depth-first list. * * Example: * * Input: * * [ * { * type: 'phase', * name: 'Phase 1', * children: [ * { * type: 'milestone', * name: 'Milestone 1', * children: [] * } * ] * } * ] * * Output: * * [ * Phase 1, * Milestone 1 * ] * * The original nodes are returned; they are not cloned. * * This is useful when an operation needs to inspect all nodes but does * not care about the parent/child hierarchy. */ export declare function flattenBulkStructure(nodes: BulkStructureNode[]): BulkStructureNode[]; /** * Counts every entity type contained in the parsed hierarchy. * * Example input: * * Phase 1 * Milestone 1 * Activity 1 * Task 1 * Activity 2 * * Output: * * { * phase: 1, * milestone: 1, * activity: 2, * task: 1 * } * * flattenBulkStructure() is used first so the counting logic does not * need to know anything about hierarchy or parent/child relationships. */ export declare function countByType(nodes: BulkStructureNode[]): Record;