(filePath: string, numLines: number)
| 335 | |
| 336 | // New function to get the first N lines of a file |
| 337 | export async function headFile(filePath: string, numLines: number): Promise<string> { |
| 338 | const fileHandle = await fs.open(filePath, 'r'); |
| 339 | try { |
| 340 | const lines: string[] = []; |
| 341 | let buffer = ''; |
| 342 | let bytesRead = 0; |
| 343 | const chunk = Buffer.alloc(1024); // 1KB buffer |
| 344 | |
| 345 | // Read chunks and count lines until we have enough or reach EOF |
| 346 | while (lines.length < numLines) { |
| 347 | const result = await fileHandle.read(chunk, 0, chunk.length, bytesRead); |
| 348 | if (result.bytesRead === 0) break; // End of file |
| 349 | bytesRead += result.bytesRead; |
| 350 | buffer += chunk.slice(0, result.bytesRead).toString('utf-8'); |
| 351 | |
| 352 | const newLineIndex = buffer.lastIndexOf('\n'); |
| 353 | if (newLineIndex !== -1) { |
| 354 | const completeLines = buffer.slice(0, newLineIndex).split('\n'); |
| 355 | buffer = buffer.slice(newLineIndex + 1); |
| 356 | for (const line of completeLines) { |
| 357 | lines.push(line); |
| 358 | if (lines.length >= numLines) break; |
| 359 | } |
| 360 | } |
| 361 | } |
| 362 | |
| 363 | // If there is leftover content and we still need lines, add it |
| 364 | if (buffer.length > 0 && lines.length < numLines) { |
| 365 | lines.push(buffer); |
| 366 | } |
| 367 | |
| 368 | return lines.join('\n'); |
| 369 | } finally { |
| 370 | await fileHandle.close(); |
| 371 | } |
| 372 | } |
| 373 | |
| 374 | export async function searchFilesWithValidation( |
| 375 | rootPath: string, |
no outgoing calls
no test coverage detected