(fileId: string, userId: string)
| 414 | } |
| 415 | |
| 416 | async function processFileInBackground(fileId: string, userId: string) { |
| 417 | assertSafeFileId(fileId); |
| 418 | const job = activeJobs.get(fileId); |
| 419 | if (!job || job.fileId !== fileId) { |
| 420 | throw handleApiError( |
| 421 | 404, |
| 422 | `Job not found for file ID ${fileId}`, |
| 423 | "Import job not found.", |
| 424 | ); |
| 425 | } |
| 426 | |
| 427 | updateJob(job, { |
| 428 | status: ImportStatus.Processing, |
| 429 | }); |
| 430 | |
| 431 | const userTempDir = path.join(tmpdir(), "ziit-chunks", userId); |
| 432 | const chunksDir = path.join(userTempDir, fileId); |
| 433 | const combinedFilePath = path.join(userTempDir, `${fileId}-combined.json`); |
| 434 | assertWithinUserDir(userTempDir, chunksDir); |
| 435 | assertWithinUserDir(userTempDir, combinedFilePath); |
| 436 | |
| 437 | try { |
| 438 | handleLog( |
| 439 | `Starting background processing for user ${userId}, fileId ${fileId}`, |
| 440 | ); |
| 441 | |
| 442 | if (!existsSync(chunksDir)) { |
| 443 | throw new Error(`Chunks directory does not exist: ${chunksDir}`); |
| 444 | } |
| 445 | |
| 446 | const chunkFiles = fs |
| 447 | .readdirSync(chunksDir) |
| 448 | .filter((file) => file.startsWith("chunk-")) |
| 449 | .sort((a, b) => { |
| 450 | const indexA = parseInt(a.split("-")[1] ?? "0"); |
| 451 | const indexB = parseInt(b.split("-")[1] ?? "0"); |
| 452 | return indexA - indexB; |
| 453 | }); |
| 454 | |
| 455 | let combinedContent = Buffer.alloc(0); |
| 456 | for (const chunkFile of chunkFiles) { |
| 457 | const chunkPath = path.join(chunksDir, chunkFile); |
| 458 | if (!existsSync(chunkPath)) { |
| 459 | throw new Error(`Chunk file not found: ${chunkPath}`); |
| 460 | } |
| 461 | const chunkData = fs.readFileSync(chunkPath); |
| 462 | combinedContent = Buffer.concat([combinedContent, chunkData]); |
| 463 | } |
| 464 | fs.writeFileSync(combinedFilePath, combinedContent); |
| 465 | handleLog( |
| 466 | `Combined ${chunkFiles.length} chunks for file ${fileId} (${( |
| 467 | combinedContent.length / |
| 468 | (1024 * 1024) |
| 469 | ).toFixed(2)} MB).`, |
| 470 | ); |
| 471 | |
| 472 | const fileContent = new TextDecoder().decode(combinedContent); |
| 473 | const parsedData = JSON.parse(fileContent); |
no test coverage detected