* Handle local file
( filePath: string, fileType: string, userId: string, executionContext?: ExecutionContext, maxDownloadBytes = MAX_DOWNLOAD_SIZE_BYTES, maxParsedOutputBytes?: number )
| 800 | * Handle local file |
| 801 | */ |
| 802 | async function handleLocalFile( |
| 803 | filePath: string, |
| 804 | fileType: string, |
| 805 | userId: string, |
| 806 | executionContext?: ExecutionContext, |
| 807 | maxDownloadBytes = MAX_DOWNLOAD_SIZE_BYTES, |
| 808 | maxParsedOutputBytes?: number |
| 809 | ): Promise<ParseResult> { |
| 810 | try { |
| 811 | const storageKey = isInternalFileUrl(filePath) ? extractStorageKey(filePath) : filePath |
| 812 | const filename = storageKey.split('/').pop() || storageKey |
| 813 | |
| 814 | const context = inferContextFromKey(storageKey) |
| 815 | const hasAccess = await verifyFileAccess( |
| 816 | storageKey, |
| 817 | userId, |
| 818 | undefined, // customConfig |
| 819 | context, // context |
| 820 | true // isLocal |
| 821 | ) |
| 822 | |
| 823 | if (!hasAccess) { |
| 824 | logger.warn('Unauthorized local file parse attempt', { userId, filename }) |
| 825 | return { |
| 826 | success: false, |
| 827 | error: 'File not found', |
| 828 | filePath, |
| 829 | } |
| 830 | } |
| 831 | |
| 832 | const fullPath = path.join(UPLOAD_DIR_SERVER, storageKey) |
| 833 | |
| 834 | logger.info('Processing local file:', fullPath) |
| 835 | |
| 836 | try { |
| 837 | await fsPromises.access(fullPath) |
| 838 | } catch { |
| 839 | throw new Error(`File not found: ${filename}`) |
| 840 | } |
| 841 | |
| 842 | const stats = await fsPromises.stat(fullPath) |
| 843 | assertKnownSizeWithinLimit(stats.size, maxDownloadBytes, 'local file') |
| 844 | |
| 845 | const result = await parseFile(fullPath) |
| 846 | const content = assertParsedContentWithinLimit(result.content, maxParsedOutputBytes) |
| 847 | const fileBuffer = await fsPromises.readFile(fullPath) |
| 848 | const hash = createHash('md5').update(fileBuffer).digest('hex') |
| 849 | |
| 850 | const extension = path.extname(filename).toLowerCase().substring(1) |
| 851 | const mimeType = fileType || getMimeTypeFromExtension(extension) |
| 852 | |
| 853 | // Store file in execution storage if executionContext is provided |
| 854 | let userFile: UserFile | undefined |
| 855 | if (executionContext) { |
| 856 | try { |
| 857 | userFile = await uploadExecutionFile( |
| 858 | executionContext, |
| 859 | fileBuffer, |
no test coverage detected