( filePath: string, rootDirectory: string, offset?: number, limit?: number, )
| 222 | * @returns ProcessedFileReadResult object. |
| 223 | */ |
| 224 | export async function processSingleFileContent( |
| 225 | filePath: string, |
| 226 | rootDirectory: string, |
| 227 | offset?: number, |
| 228 | limit?: number, |
| 229 | ): Promise<ProcessedFileReadResult> { |
| 230 | try { |
| 231 | if (!fs.existsSync(filePath)) { |
| 232 | // Sync check is acceptable before async read |
| 233 | return { |
| 234 | llmContent: '', |
| 235 | returnDisplay: 'File not found.', |
| 236 | error: `File not found: ${filePath}`, |
| 237 | errorType: FileErrorType.FILE_NOT_FOUND, |
| 238 | }; |
| 239 | } |
| 240 | const stats = await fs.promises.stat(filePath); |
| 241 | if (stats.isDirectory()) { |
| 242 | return { |
| 243 | llmContent: '', |
| 244 | returnDisplay: 'Path is a directory.', |
| 245 | error: `Path is a directory, not a file: ${filePath}`, |
| 246 | errorType: FileErrorType.IS_DIRECTORY, |
| 247 | }; |
| 248 | } |
| 249 | |
| 250 | const fileSizeInBytes = stats.size; |
| 251 | // 20MB limit |
| 252 | const maxFileSize = 20 * 1024 * 1024; |
| 253 | |
| 254 | if (fileSizeInBytes > maxFileSize) { |
| 255 | throw new Error( |
| 256 | `File size exceeds the 20MB limit: ${filePath} (${( |
| 257 | fileSizeInBytes / |
| 258 | (1024 * 1024) |
| 259 | ).toFixed(2)}MB)`, |
| 260 | ); |
| 261 | } |
| 262 | |
| 263 | const fileType = await detectFileType(filePath); |
| 264 | const relativePathForDisplay = path |
| 265 | .relative(rootDirectory, filePath) |
| 266 | .replace(/\\/g, '/'); |
| 267 | |
| 268 | switch (fileType) { |
| 269 | case 'binary': { |
| 270 | return { |
| 271 | llmContent: `Cannot display content of binary file: ${relativePathForDisplay}`, |
| 272 | returnDisplay: `Skipped binary file: ${relativePathForDisplay}`, |
| 273 | }; |
| 274 | } |
| 275 | case 'svg': { |
| 276 | const SVG_MAX_SIZE_BYTES = 1 * 1024 * 1024; |
| 277 | if (stats.size > SVG_MAX_SIZE_BYTES) { |
| 278 | return { |
| 279 | llmContent: `Cannot display content of SVG file larger than 1MB: ${relativePathForDisplay}`, |
| 280 | returnDisplay: `Skipped large SVG file (>1MB): ${relativePathForDisplay}`, |
| 281 | }; |
no test coverage detected