( key: string, parts: AzureMultipartPart[], customConfig?: BlobConfig )
| 689 | * Complete multipart upload by committing all blocks |
| 690 | */ |
| 691 | export async function completeMultipartUpload( |
| 692 | key: string, |
| 693 | parts: AzureMultipartPart[], |
| 694 | customConfig?: BlobConfig |
| 695 | ): Promise<{ location: string; path: string; key: string }> { |
| 696 | const { BlobServiceClient, StorageSharedKeyCredential } = await import('@azure/storage-blob') |
| 697 | let blobServiceClient: BlobServiceClientType |
| 698 | let containerName: string |
| 699 | |
| 700 | if (customConfig) { |
| 701 | if (customConfig.connectionString) { |
| 702 | blobServiceClient = BlobServiceClient.fromConnectionString(customConfig.connectionString) |
| 703 | } else if (customConfig.accountName && customConfig.accountKey) { |
| 704 | const credential = new StorageSharedKeyCredential( |
| 705 | customConfig.accountName, |
| 706 | customConfig.accountKey |
| 707 | ) |
| 708 | blobServiceClient = new BlobServiceClient( |
| 709 | `https://${customConfig.accountName}.blob.core.windows.net`, |
| 710 | credential |
| 711 | ) |
| 712 | } else { |
| 713 | throw new Error('Invalid custom blob configuration') |
| 714 | } |
| 715 | containerName = customConfig.containerName |
| 716 | } else { |
| 717 | blobServiceClient = await getBlobServiceClient() |
| 718 | containerName = BLOB_CONFIG.containerName |
| 719 | } |
| 720 | |
| 721 | const containerClient = blobServiceClient.getContainerClient(containerName) |
| 722 | const blockBlobClient = containerClient.getBlockBlobClient(key) |
| 723 | |
| 724 | const sortedBlockIds = parts |
| 725 | .sort((a, b) => a.partNumber - b.partNumber) |
| 726 | .map((part) => part.blockId) |
| 727 | |
| 728 | await blockBlobClient.commitBlockList(sortedBlockIds, { |
| 729 | metadata: { |
| 730 | multipartUpload: 'completed', |
| 731 | uploadCompletedAt: new Date().toISOString(), |
| 732 | }, |
| 733 | }) |
| 734 | |
| 735 | const location = blockBlobClient.url |
| 736 | const path = `/api/files/serve/${encodeURIComponent(key)}` |
| 737 | |
| 738 | return { |
| 739 | location, |
| 740 | path, |
| 741 | key, |
| 742 | } |
| 743 | } |
| 744 | |
| 745 | /** |
| 746 | * Abort multipart upload by deleting the blob if it exists |
no test coverage detected