{"version":3,"sources":["../../src/services/storage/blob/blobStorage.service.ts","../../src/shared/utils/errorHandler.ts","../../src/services/storage/blob/blobHelpers.ts","../../src/services/storage/blob/blocIdStorage.ts","../../src/services/storage/s3/s3Storage.service.ts","../../src/services/storage/s3/s3Helpers.ts","../../src/shared/utils/constants.ts","../../src/services/objectStorageFactory.service.ts","../../src/services/objectStorage.service.ts"],"names":["stream","BlobServiceClient","BlobSASPermissions","errorMessages","AccessDenied","AccountProblem","AllAccessDisabled","BucketAlreadyExists","BucketNotEmpty","EntityTooLarge","ExpiredToken","InternalError","InvalidAccessKeyId","InvalidBucketName","InvalidObjectState","InvalidToken","NoSuchBucket","NoSuchKey","PreconditionFailed","RequestTimeout","ServiceUnavailable","SignatureDoesNotMatch","SlowDown","TemporaryRedirect","ObjectNotFound","DEFAULT","ErrorHandler","handleError","errorCode","errorMessage","errorObj","errorResponse","code","message","timestamp","Date","toISOString","error","name","stack","BlobPropertiesResponseToObjectResponse","blobProperties","lastModified","contentLength","contentType","eTag","etag","metadata","contentEncoding","cacheControl","contentDisposition","contentLanguage","BlockIdStorage","blockIdMap","getInstance","instance","addBlockId","blobName","blockId","push","getBlockIds","clearBlockIds","BlobStorageService","constructor","containerName","blobServiceClient","connectionString","process","env","DATA_LAKE_BUCKET","AZURE_DATALAKE_CONNECTION_STRING","AZURE_STORAGE_CONNECTION_STRING","fromConnectionString","createUploadWriteStream","streamPassThrough","PassThrough","containerClient","getContainerClient","blockBlobClient","getBlockBlobClient","uploadPromise","uploadStream","undefined","onProgress","ev","console","log","then","Bucket","Key","key","promise","getHeadObject","getProperties","getObject","options","downloadBlockBlobResponse","expression","range","matches","match","length","start","end","map","Number","download","body","readableStreamBody","errorKey","response","status","getSignatureUrl","expiresInMinutes","permissions","startDate","expiryDate","setMinutes","getMinutes","generateSasUrl","parse","startsOn","expiresOn","getUploadUrl","sasUrl","signedUrl","getDownloadUrl","upload","Buffer","isBuffer","delete","data","deleteObject","listChunk","continuationToken","limit","iterator","listBlobsFlat","prefix","byPage","maxPageSize","items","next","value","segment","blobItems","listContents","responseContents","pagination","continueListing","concat","contents","nextContinuationToken","list","blob","properties","size","count","listAll","allItems","deleteObjects","blobNames","deleteBlobPromises","deleted","Promise","all","getHeadBucket","Error","listMultipartUploadsForBucket","blobList","uploads","uploadId","initiated","createdOn","bucketName","listMultipartUploadsForKey","blobClient","listResponse","getBlockList","parts","uncommittedBlocks","block","index","PartNumber","LastModified","ETag","Size","Parts","generateUploadIdMultipart","now","randomNum","Math","floor","random","blockIdBase","toString","uploadMultipart","file","partNumber","partId","padStart","partIdBase64","from","stageBlock","completeMultipartUpload","listMultipartUploads","blockIds","part","commitBlockList","abortMultipartUpload","blockIdStorage","getMultipartUploadPresignedUrl","url","DeleteObjectCommand","GetObjectCommand","HeadBucketCommand","HeadObjectCommand","ListObjectsV2Command","PutObjectCommand","S3Client","S3","UploadPartCommand","defaultProvider","getSignedUrl","listResponseContentsToListResponseItems","responseContent","s3ObjectToObjectResponse","s3Object","Body","Metadata","ContentType","ContentLength","ContentEncoding","CacheControl","ContentDisposition","ContentLanguage","Upload","NodeHttpHandler","sharedHttpHandler","socketTimeout","sharedCredentialsProvider","defaultS3Client","region","AWS_DEFAULT_REGION","requestHandler","credentials","defaultS3","S3StorageService","s3Client","s3","accessKeyId","secretAccessKey","s3Config","AWS_REGION","command","ContinuationToken","Prefix","MaxKeys","send","listChunkLimit","NextContinuationToken","Contents","expiresIn","putObjectCommandParams","UPLOAD_BUCKET_NAME","ACL","params","client","queueSize","partSize","done","createMultipartUpload","UploadId","Uploads","initiator","Initiator","ID","owner","Owner","storageClass","StorageClass","Initiated","listParts","upId","uploadPart","partsResponse","partsList","partList","completeMultipartParams","MultipartUpload","uploadPartParams","parseInt","presignedUrl","OBJECT_STORAGE_SERVICE_TYPES","AWS_S3","AZURE_BLOB_STORAGE","ObjectStorageFactory","provider","toLowerCase","OBJECT_STORAGE_SERVICE","ObjectStorageService","objectStorageOptions","getObjectStorageServiceInstance","Array","isArray"],"mappings":"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","sourcesContent":["/* eslint-disable no-console */\nimport stream from 'stream';\nimport { IObjectStorage, IGetObjectOptions } from '../../../interfaces';\nimport {\n    FileContent,\n    ListResponse,\n    UploadResponse,\n    GetObjectResponse,\n    ListRequestOptions,\n    ListResponseItem,\n    GetUploadUrlResponse,\n    CreateUploadWriteStreamResponse,\n    HeadBucketResponse,\n    ListPartsMultipartUploadResponse,\n    ListMultipartUploadsResponse,\n} from '../../../types';\nimport {\n    BlobServiceClient,\n    BlobSASPermissions,\n    BlobItem,\n    ContainerClient,\n} from '@azure/storage-blob';\n\nimport { Readable } from 'stream';\nimport { ErrorHandler } from '../../../shared/utils/errorHandler';\nimport { BlobPropertiesResponseToObjectResponse } from './blobHelpers';\nimport { BlockIdStorage } from './blocIdStorage';\nexport class BlobStorageService implements IObjectStorage {\n    private blobServiceClient: BlobServiceClient;\n    private containerName: string;\n\n    /**\n     * Retrieves the properties of a blob from the container by its name.\n     *\n     * @param {string} blobName - The name of the blob.\n     * @return {Promise<GetObjectResponse>} A promise that resolves to the blob properties.\n     */\n    constructor(containerName: string) {\n        this.containerName = containerName;\n\n        let connectionString;\n        if (process.env.DATA_LAKE_BUCKET && process.env.DATA_LAKE_BUCKET === this.containerName) {\n            connectionString = process.env.AZURE_DATALAKE_CONNECTION_STRING;\n        }\n        if (!connectionString) {\n            connectionString = process.env.AZURE_STORAGE_CONNECTION_STRING;\n        }\n\n        this.blobServiceClient = BlobServiceClient.fromConnectionString(\n            connectionString!,\n        );\n    }\n\n    /**\n     * Creates a writable stream for uploading a file to the Blob storage.\n     *\n     * @param {string} blobName - The name of the blob to upload.\n     * @return {CreateUploadWriteStreamResponse} An object containing the key of the uploaded blob, the writable stream, and a promise that resolves when the upload is complete.\n     */\n    createUploadWriteStream(blobName: string): CreateUploadWriteStreamResponse {\n        const streamPassThrough = new stream.PassThrough();\n        const containerClient = this.blobServiceClient.getContainerClient(\n            this.containerName,\n        );\n        const blockBlobClient = containerClient.getBlockBlobClient(blobName);\n\n        const uploadPromise = blockBlobClient\n            .uploadStream(streamPassThrough, undefined, undefined, {\n                onProgress: (ev) => console.log(ev),\n            })\n            .then(() => {\n                return { Bucket: this.containerName, Key: blobName };\n            });\n\n        return {\n            key: blobName,\n            stream: streamPassThrough,\n            promise: uploadPromise,\n        };\n    }\n\n    /**\n     * Retrieves the properties of a blob from the container by its name.\n     *\n     * @param {string} blobName - The name of the blob.\n     * @return {Promise<GetObjectResponse>} A promise that resolves to the blob properties.\n     */\n    async getHeadObject(blobName: string): Promise<GetObjectResponse> {\n        try {\n            const containerClient = this.blobServiceClient.getContainerClient(\n                this.containerName,\n            );\n            const blockBlobClient =\n                containerClient.getBlockBlobClient(blobName);\n            const blobProperties = await blockBlobClient.getProperties();\n            return BlobPropertiesResponseToObjectResponse(blobProperties);\n        } catch (error) {\n            throw ErrorHandler.handleError('DEFAULT', '', error as Error);\n        }\n    }\n\n    /**\n     * Retrieves an object from the blob storage service.\n     *\n     * @param {string} blobName - The name of the blob to retrieve.\n     * @param {Object} [options] - The options that you can pass to the library.\n     * @return {Promise<GetObjectResponse>} A promise that resolves to the object data, including the body, metadata, content type, and content length, or rejects with an error if there was an issue.\n     */\n    async getObject(\n        blobName: string,\n        options?: IGetObjectOptions,\n    ): Promise<GetObjectResponse> {\n        try {\n            let downloadBlockBlobResponse;\n            const containerClient = this.blobServiceClient.getContainerClient(\n                this.containerName,\n            );\n            const blockBlobClient =\n                containerClient.getBlockBlobClient(blobName);\n            const expression = options?.range || '';\n            const matches = expression.match(/\\d+/g);\n            if (expression && matches?.length) {\n                const [start, end] = matches.map(Number);\n                downloadBlockBlobResponse = await blockBlobClient.download(\n                    start,\n                    end,\n                );\n            } else {\n                downloadBlockBlobResponse = await blockBlobClient.download(0);\n            }\n            return {\n                body: downloadBlockBlobResponse.readableStreamBody as Readable,\n                metadata: downloadBlockBlobResponse.metadata,\n                contentType: downloadBlockBlobResponse.contentType,\n                contentLength: downloadBlockBlobResponse.contentLength,\n            };\n        } catch (error: any) {\n            let errorKey = 'DEFAULT';\n            if (error?.response?.status === 404) {\n                errorKey = 'ObjectNotFound';\n            }\n            throw ErrorHandler.handleError(errorKey, '', error as Error);\n        }\n    }\n\n    private async getSignatureUrl(\n        blobName: string,\n        expiresInMinutes: number,\n        permissions: string,\n    ): Promise<string> {\n        try {\n            const containerClient = this.blobServiceClient.getContainerClient(\n                this.containerName,\n            );\n            const blockBlobClient =\n                containerClient.getBlockBlobClient(blobName);\n\n            const startDate = new Date();\n            const expiryDate = new Date(startDate);\n            expiryDate.setMinutes(startDate.getMinutes() + expiresInMinutes);\n\n            return blockBlobClient.generateSasUrl({\n                permissions: BlobSASPermissions.parse(permissions),\n                startsOn: startDate,\n                expiresOn: expiryDate,\n            });\n        } catch (error) {\n            throw ErrorHandler.handleError('DEFAULT', '', error as Error);\n        }\n    }\n\n    async getUploadUrl(\n        blobName: string,\n        expiresInMinutes: number,\n    ): Promise<GetUploadUrlResponse> {\n        try {\n            const sasUrl = await this.getSignatureUrl(\n                blobName,\n                expiresInMinutes,\n                'w',\n            );\n            return { key: blobName, signedUrl: sasUrl };\n        } catch (error) {\n            throw ErrorHandler.handleError('DEFAULT', '', error as Error);\n        }\n    }\n\n    /**\n     * Retrieves a signed URL for the blob with the specified name that expires after a certain period.\n     *\n     * @param {string} blobName - The name of the blob to generate the signed URL for.\n     * @param {number} expiresInMinutes - The duration in minutes until the signed URL expires.\n     * @return {Promise<string>} A Promise that resolves with the signed URL.\n     */\n    async getDownloadUrl(\n        blobName: string,\n        expiresInMinutes: number,\n    ): Promise<string> {\n        try {\n            const sasUrl = await this.getSignatureUrl(\n                blobName,\n                expiresInMinutes,\n                'r',\n            );\n            return sasUrl;\n        } catch (error) {\n            throw ErrorHandler.handleError('DEFAULT', '', error as Error);\n        }\n    }\n\n    /**\n     * Uploads a file to the blob storage service.\n     *\n     * @param {string} blobName - The name of the blob to upload.\n     * @param {FileContent} body - The content of the file to upload.\n     * @param {{ [key: string]: string } | undefined} [metadata] - Optional metadata to associate with the blob.\n     * @return {Promise<UploadResponse>} A promise that resolves to the response object containing the key of the uploaded blob, or rejects with an error if there was an issue.\n     */\n    async upload(\n        blobName: string,\n        body: FileContent,\n        metadata: { [key: string]: string } = {},\n    ): Promise<UploadResponse> {\n        try {\n            const containerClient = this.blobServiceClient.getContainerClient(\n                this.containerName,\n            );\n            const blockBlobClient =\n                containerClient.getBlockBlobClient(blobName);\n            Buffer.isBuffer(body)\n                ? await blockBlobClient.upload(body, body.length, { metadata })\n                : await blockBlobClient.uploadStream(\n                      body as Readable,\n                      undefined,\n                      undefined,\n                      { metadata },\n                  );\n\n            return { key: blobName };\n        } catch (error) {\n            throw ErrorHandler.handleError('DEFAULT', '', error as Error);\n        }\n    }\n\n    /**\n     * Deletes a blob from the blob storage service.\n     *\n     * @param {string} blobName - The name of the blob to be deleted.\n     * @return {Promise<boolean>} A promise that resolves to true if the blob is successfully deleted, or rejects with an error if there was an issue.\n     */\n    async delete(data: string): Promise<boolean> {\n        try {\n            const containerClient = this.blobServiceClient.getContainerClient(\n                this.containerName,\n            );\n            return this.deleteObject(containerClient, data);\n        } catch (error) {\n            throw ErrorHandler.handleError('DEFAULT', '', error as Error);\n        }\n    }\n\n    /**\n     * Lists a chunk of blobs from the specified container client based on the provided options and continuation token.\n     *\n     * @param {ListRequestOptions} options - The options for listing the blobs.\n     * @param {string | undefined} continuationToken - The continuation token for pagination.\n     * @param {number} limit - The maximum number of blobs to list in a single page.\n     * @param {ContainerClient} containerClient - The container client to list the blobs from.\n     * @return {Promise<{ items: BlobItem[]; continuationToken?: string }>} - A promise that resolves to an object containing the list of blob items and an optional continuation token.\n     */\n    private async listChunk(\n        options: ListRequestOptions,\n        continuationToken: string | undefined,\n        limit: number,\n        containerClient: ContainerClient,\n    ): Promise<{ items: BlobItem[]; continuationToken?: string }> {\n        const iterator = containerClient\n            .listBlobsFlat({\n                prefix: options.prefix,\n            })\n            .byPage({\n                maxPageSize: limit,\n                continuationToken: continuationToken,\n            });\n\n        const items: BlobItem[] = [];\n        const response = (await iterator.next()).value;\n        items.push(...response.segment.blobItems);\n        return {\n            items,\n            continuationToken: response.continuationToken,\n        };\n    }\n\n    /**\n     * Retrieves a list of blob contents based on the provided options.\n     *\n     * @param {ListRequestOptions} options - The options for listing the blob contents.\n     * @return {Promise<{ contents: BlobItem[]; nextContinuationToken?: string }>} A promise that resolves to the list of blob contents and the next continuation token.\n     */\n    private async listContents(\n        options: ListRequestOptions,\n    ): Promise<{ contents: BlobItem[]; nextContinuationToken?: string }> {\n        let responseContents: BlobItem[] = [];\n        let continuationToken: string | undefined = options.pagination;\n        const limit = options.limit ?? 1000;\n        let continueListing = true;\n        const containerClient = this.blobServiceClient.getContainerClient(\n            this.containerName,\n        );\n        while (continueListing) {\n            const response = await this.listChunk(\n                options,\n                continuationToken,\n                limit - responseContents.length,\n                containerClient,\n            );\n            continuationToken = response.continuationToken;\n            responseContents = responseContents.concat(response.items);\n\n            if (responseContents.length >= limit || !continuationToken) {\n                continueListing = false;\n            }\n        }\n\n        return {\n            contents: responseContents,\n            nextContinuationToken: continuationToken,\n        };\n    }\n\n    /**\n     * Lists blobs in the Azure Blob Storage container with pagination.\n     * @param options - The options for listing blobs.\n     * @returns A promise that resolves to a paginated list of blob names.\n     */\n    async list(options: ListRequestOptions): Promise<ListResponse> {\n        let items: ListResponseItem[] = [];\n        const response = await this.listContents(options);\n\n        items = response.contents.length\n            ? response.contents.map((blob) => {\n                  return {\n                      key: blob.name,\n                      lastModified: blob.properties.lastModified,\n                      size: blob.properties.contentLength!,\n                      eTag: blob.properties.etag,\n                  };\n              })\n            : [];\n\n        return {\n            items,\n            pagination: response.nextContinuationToken?.length\n                ? response.nextContinuationToken\n                : null,\n            count: items.length,\n        };\n    }\n\n    /**\n     * Lists all blobs in the Azure Blob Storage container.\n     * @param options - The options for listing blobs.\n     * @returns A promise that resolves to list of blob names.\n     */\n    async listAll(options: ListRequestOptions): Promise<ListResponse> {\n        let allItems: ListResponseItem[] = [];\n        let pagination: string | undefined = undefined;\n\n        do {\n            const response: ListResponse = await this.list({\n                ...options,\n                pagination,\n            });\n\n            if (response.items?.length)\n                allItems = [...allItems, ...response.items];\n\n            pagination = response.pagination ?? undefined;\n        } while (pagination);\n\n        return { items: allItems, count: allItems.length };\n    }\n\n    /**\n     * Deletes a blob from the blob storage service.\n     *\n     * @param {string} blobName - The name of the blob to be deleted.\n     * @return {Promise<boolean>} A promise that resolves to true if the blob is successfully deleted, or rejects with an error if there was an issue.\n     */\n    async deleteObject(\n        containerClient: ContainerClient,\n        blobName: string,\n    ): Promise<boolean> {\n        try {\n            const blockBlobClient =\n                containerClient.getBlockBlobClient(blobName);\n            await blockBlobClient.delete();\n            return true;\n        } catch (error) {\n            throw ErrorHandler.handleError('DEFAULT', '', error as Error);\n        }\n    }\n\n    /**\n     * Deletes multiple blobs from the blob storage service.\n     *\n     * @param {string[]} blobNames - An array of blob names to be deleted.\n     * @return {Promise<{ key: string; deleted: boolean; error?: string }[]>} - A promise that resolves to an array of objects containing the key, deleted status, and an optional error message for each blob deleted.\n     */\n    async deleteObjects(\n        blobNames: string[],\n    ): Promise<{ key: string; deleted: boolean; error?: string }[]> {\n        const containerClient = this.blobServiceClient.getContainerClient(\n            this.containerName,\n        );\n        const deleteBlobPromises = blobNames.map(async (blobName) => {\n            try {\n                await this.deleteObject(containerClient, blobName);\n                return { key: blobName, deleted: true };\n            } catch (error: any) {\n                return {\n                    key: blobName,\n                    deleted: false,\n                    error: error?.message ?? '',\n                };\n            }\n        });\n        return Promise.all(deleteBlobPromises);\n    }\n\n    /**\n     * Retrieves the properties of the container.\n     *\n     * @return {Promise<HeadBucketResponse>} A promise that resolves to the container properties.\n     */\n    async getHeadBucket(): Promise<HeadBucketResponse> {\n        try {\n            const containerClient = this.blobServiceClient.getContainerClient(\n                this.containerName,\n            );\n            const properties = await containerClient.getProperties();\n            return properties;\n        } catch (error) {\n            throw new Error(\n                'Error in Azure getHeadContainer. Container: ' +\n                    this.containerName +\n                    ' Error: ' +\n                    error,\n            );\n        }\n    }\n\n    async listMultipartUploadsForBucket(): Promise<ListMultipartUploadsResponse> {\n        const containerClient = this.blobServiceClient.getContainerClient(\n            this.containerName,\n        );\n        const blobList = containerClient.listBlobsFlat();\n\n        const uploads = [];\n\n        for await (const blob of blobList) {\n            uploads.push({\n                uploadId: blob.name,\n                key: blob.name,\n                initiated: blob.properties.createdOn || new Date(),\n            });\n        }\n\n        return {\n            bucketName: this.containerName,\n            uploads,\n        };\n    }\n\n    /**\n     * Retrieves the list of parts for a multipart upload.\n     *\n     * @param {string} blobName - The name of the blob (file) in Azure Blob Storage.\n     * @return {Promise<ListPartsMultipartUploadResponse>} A promise that resolves to the list of parts for the multipart upload.\n     */\n    async listMultipartUploadsForKey(\n        blobName: string,\n    ): Promise<ListPartsMultipartUploadResponse> {\n        const containerClient = this.blobServiceClient.getContainerClient(\n            this.containerName,\n        );\n        const blobClient = containerClient.getBlockBlobClient(blobName);\n        const listResponse = await blobClient.getBlockList('all');\n        const parts =\n            listResponse?.uncommittedBlocks?.map((block, index) => ({\n                PartNumber: index + 1,\n                LastModified: new Date(), // Azure Blob Storage doesn't provide the last modified date for individual parts\n                ETag: block.name,\n                Size: block.size,\n            })) || [];\n        return {\n            Parts: parts,\n        };\n    }\n\n    /**\n     * Generates a unique upload ID for multipart uploads.\n     *\n     * @return {Promise<string>} A promise that resolves to a unique upload ID.\n     */\n    async generateUploadIdMultipart(): Promise<string> {\n        const timestamp = Date.now();\n        const randomNum = Math.floor(Math.random() * 100);\n        const blockIdBase = (timestamp - randomNum).toString();\n        return blockIdBase;\n    }\n\n    /**\n     * Uploads a part of a file as a block to Azure Blob Storage and updates the metadata with the block ID.\n     *\n     * @param {string} blobName - The name of the blob (file) that you want to upload in parts to Azure Blob Storage.\n     * @param {FileContent | any} file - The content of the file that you want to upload as a part of a multipart upload.\n     * @param {number} partNumber - The number or index of the part being uploaded.\n     * @param {string} [uploadId] - The ID of the multipart upload. If not provided, a new upload ID will be generated.\n     * @return {Promise<string>} A Promise that resolves to a string representing the base64 encoded block ID of the uploaded part.\n     */\n    async uploadMultipart(\n        blobName: string,\n        file: FileContent | any,\n        partNumber: number,\n        uploadId?: string,\n    ): Promise<string> {\n        const containerClient = this.blobServiceClient.getContainerClient(\n            this.containerName,\n        );\n        const blobClient = containerClient.getBlockBlobClient(blobName);\n\n        const blockIdBase =\n            uploadId || (await this.generateUploadIdMultipart());\n\n        const partId = partNumber.toString().padStart(6, '0');\n        const partIdBase64 = Buffer.from(partId).toString('base64');\n\n        await blobClient.stageBlock(partIdBase64, file, file.length);\n\n        return blockIdBase;\n    }\n\n    /**\n     * Completes a multipart upload by committing the blocks to create the blob.\n     *\n     * @param {string} blobName - The name of the blob for which the multipart upload is being completed.\n     * @param {string} uploadId - The ID of the multipart upload to be completed.\n     * @return {Promise<void>} A Promise that resolves when the multipart upload is successfully completed.\n     * @throws {Error} If no block IDs are found in the metadata.\n     */\n    async completeMultipartUpload(\n        blobName: string,\n        uploadId: string,\n    ): Promise<void> {\n        const containerClient = this.blobServiceClient.getContainerClient(\n            this.containerName,\n        );\n        const blobClient = containerClient.getBlockBlobClient(blobName);\n\n        // Retrieve the block IDs from temporal storage\n        const listMultipartUploads = await this.listMultipartUploadsForKey(blobName)\n        const blockIds = listMultipartUploads?.Parts?.map(part => part.ETag) || [];\n        if (blockIds.length === 0) {\n            throw new Error('No block IDs found in metadata.');\n        }\n\n        // Commit the blocks to create the blob\n        await blobClient.commitBlockList(blockIds);\n    }\n\n    /**\n     * Aborts a multipart upload by deleting the specified blob and clearing its block IDs metadata.\n     *\n     * @param {string} blobName - The name of the blob for which the multipart upload needs to be aborted.\n     * @param {string} uploadId - The ID of the multipart upload to be aborted.\n     * @return {Promise<void>} A promise that resolves when the multipart upload is successfully aborted.\n     */\n    async abortMultipartUpload(\n        blobName: string,\n        uploadId: string,\n    ): Promise<void> {\n        const containerClient = this.blobServiceClient.getContainerClient(\n            this.containerName,\n        );\n        const blobClient = containerClient.getBlockBlobClient(blobName);\n        const blockIdStorage = BlockIdStorage.getInstance();\n        blockIdStorage.clearBlockIds(uploadId);\n\n        await blobClient.delete();\n    }\n\n    async getMultipartUploadPresignedUrl(\n        blobName: string,\n        uploadId: string,\n        partNumber: string,\n        expiresInMinutes: number = 2,\n    ): Promise<string> {\n        const partId = partNumber.toString().padStart(6, '0');\n            const partIdBase64 = Buffer.from(partId).toString('base64');\n            const sasUrl = await this.getSignatureUrl(\n                blobName,\n                expiresInMinutes,\n                'w',\n            );\n            const url = `${sasUrl}&comp=block&blockid=${partIdBase64}`;\n            return url;\n    }\n}\n","import { CustomError } from '../../types/CustomError';\n\nconst errorMessages: { [key: string]: string } = {\n    AccessDenied: 'Access denied',\n    AccountProblem: 'There is a problem with your account',\n    AllAccessDisabled: 'All access to this resource has been disabled',\n    BucketAlreadyExists: 'The requested bucket name is not available',\n    BucketNotEmpty: 'The bucket you tried to delete is not empty',\n    EntityTooLarge: 'The entity you are trying to upload is too large',\n    ExpiredToken: 'The provided token has expired',\n    InternalError: 'An internal server error has occurred',\n    InvalidAccessKeyId:\n        'The AWS access key ID you provided does not exist in our records',\n    InvalidBucketName: 'The specified bucket name is not valid',\n    InvalidObjectState:\n        'The operation is not valid for the current state of the object',\n    InvalidToken: 'The provided token is invalid',\n    NoSuchBucket: 'The specified bucket does not exist',\n    NoSuchKey: 'The specified key does not exist',\n    PreconditionFailed: 'The condition specified in the request is not met',\n    RequestTimeout: 'The request timed out',\n    ServiceUnavailable: 'The service is currently unavailable',\n    SignatureDoesNotMatch:\n        'The request signature we calculated does not match the signature you provided',\n    SlowDown: 'Please reduce your request rate',\n    TemporaryRedirect: 'Temporary redirect',\n    ObjectNotFound: 'ObjectNotFound - The specified key does not exist. (404)',\n    DEFAULT: 'An unknown error occurred',\n};\n\nexport class ErrorHandler {\n    static handleError(\n        errorCode: string,\n        errorMessage?: string,\n        errorObj?: Error,\n    ): CustomError {\n        const errorResponse: CustomError = {\n            code: errorCode,\n            message:\n                errorMessage ||\n                errorMessages[errorCode] ||\n                errorMessages['DEFAULT'],\n            timestamp: new Date().toISOString(),\n            error: errorObj\n                ? {\n                      name: errorObj.name,\n                      message: errorObj.message,\n                      stack: errorObj.stack || null,\n                  }\n                : null,\n        };\n\n        // Return the structured object\n        return errorResponse;\n    }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { GetObjectResponse } from '../../../types';\nimport { BlobGetPropertiesResponse } from '@azure/storage-blob';\n\nexport function BlobPropertiesResponseToObjectResponse(\n    blobProperties: BlobGetPropertiesResponse,\n): GetObjectResponse {\n    return {\n        lastModified: blobProperties.lastModified,\n        contentLength: blobProperties.contentLength,\n        contentType: blobProperties.contentType,\n        eTag: blobProperties.etag,\n        metadata: blobProperties.metadata,\n        contentEncoding: blobProperties.contentEncoding,\n        cacheControl: blobProperties.cacheControl,\n        contentDisposition: blobProperties.contentDisposition,\n        contentLanguage: blobProperties.contentLanguage,\n    };\n}\n","export class BlockIdStorage {\n    private static instance: BlockIdStorage;\n    private blockIdMap: { [blobName: string]: string[] } = {};\n\n    private constructor() {}\n\n    public static getInstance(): BlockIdStorage {\n        if (!BlockIdStorage.instance) {\n            BlockIdStorage.instance = new BlockIdStorage();\n        }\n        return BlockIdStorage.instance;\n    }\n\n    public addBlockId(blobName: string, blockId: string): void {\n        if (!this.blockIdMap[blobName]) {\n            this.blockIdMap[blobName] = [];\n        }\n        this.blockIdMap[blobName].push(blockId);\n    }\n\n    public getBlockIds(blobName: string): string[] {\n        return this.blockIdMap[blobName] || [];\n    }\n\n    public clearBlockIds(blobName: string): void {\n        delete this.blockIdMap[blobName];\n    }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n    DeleteObjectCommand,\n    GetObjectCommand,\n    HeadBucketCommand,\n    HeadObjectCommand,\n    ListObjectsV2Command,\n    ListObjectsV2CommandOutput,\n    PutObjectAclCommandInput,\n    PutObjectCommand,\n    S3Client,\n    S3,\n    S3ClientConfig,\n    UploadPartCommand,\n} from '@aws-sdk/client-s3';\nimport { defaultProvider } from '@aws-sdk/credential-provider-node';\nimport { IObjectStorage } from '../../../interfaces';\nimport {\n    CreateUploadWriteStreamResponse,\n    FileContent,\n    GetObjectResponse,\n    GetUploadUrlResponse,\n    ListRequestOptions,\n    ListResponse,\n    ListResponseItem,\n    UploadResponse,\n    HeadBucketResponse,\n    ObjectStorageOptions,\n    ListPartsMultipartUploadResponse,\n    ListMultipartUploadsResponse,\n} from '../../../types';\nimport { getSignedUrl } from '@aws-sdk/s3-request-presigner';\nimport {\n    listResponseContentsToListResponseItems,\n    s3ObjectToObjectResponse,\n} from './s3Helpers';\nimport stream from 'stream';\nimport { Upload } from '@aws-sdk/lib-storage';\nimport { NodeHttpHandler } from '@smithy/node-http-handler';\n\n/**\n * Shared HTTP handler reused across every S3 client instance.\n * Creating one per service instance is wasteful (sockets, agents, timers).\n */\nconst sharedHttpHandler = new NodeHttpHandler({\n    socketTimeout: 600000,\n});\n\n/**\n * Shared credentials provider chain. The AWS SDK v3 credential providers\n * cache the resolved credentials internally and refresh them automatically\n * before expiration (works out of the box with IRSA, IMDS, AssumeRole, etc.).\n *\n * It is critical to reuse the SAME provider instance across clients so the\n * cache is shared. Creating a new `defaultProvider()` on every instantiation\n * forces a full credential resolution (IMDS/STS round-trips) and can lead to\n * intermittent \"Could not load credentials\" errors under load.\n */\nconst sharedCredentialsProvider = defaultProvider();\n\n/**\n * Default singleton clients used when no per-instance credentials are supplied.\n * Sharing them across `S3StorageService` instances avoids creating a fresh\n * credential chain (and refreshing tokens) on every `new S3StorageService(...)`.\n */\nconst defaultS3Client: S3Client = new S3Client({\n    region: process.env.AWS_DEFAULT_REGION,\n    requestHandler: sharedHttpHandler,\n    credentials: sharedCredentialsProvider,\n});\n\nconst defaultS3: S3 = new S3({\n    region: process.env.AWS_DEFAULT_REGION,\n    requestHandler: sharedHttpHandler,\n    credentials: sharedCredentialsProvider,\n});\n\nexport class S3StorageService implements IObjectStorage {\n    private s3Client: S3Client;\n    private s3: S3;\n    private bucketName: string;\n\n    constructor(bucketName: string, options?: ObjectStorageOptions) {\n        this.bucketName = bucketName;\n        if (\n            options?.credentials?.accessKeyId &&\n            options?.credentials?.secretAccessKey\n        ) {\n            const s3Config: S3ClientConfig = {\n                region: options?.region || process.env.AWS_REGION,\n                requestHandler: sharedHttpHandler,\n                credentials: {\n                    accessKeyId: options.credentials.accessKeyId,\n                    secretAccessKey: options.credentials.secretAccessKey,\n                },\n            };\n            this.s3Client = new S3Client(s3Config);\n            this.s3 = new S3(s3Config);\n        } else {\n            this.s3Client = defaultS3Client;\n            this.s3 = defaultS3;\n        }\n    }\n\n    /**\n     * Retrieves a chunk of objects from the S3 bucket based on the provided options.\n     *\n     * @param {ListRequestOptions} options - The options for listing the objects.\n     * @param {string | undefined} continuationToken - The continuation token for pagination.\n     * @param {number} limit - The maximum number of objects to retrieve.\n     * @return {Promise<ListObjectsV2CommandOutput>} - A promise that resolves to the response containing the list of objects and metadata.\n     */\n    private async listChunk(\n        options: ListRequestOptions,\n        continuationToken: string | undefined,\n        limit: number,\n    ): Promise<ListObjectsV2CommandOutput> {\n        const command = new ListObjectsV2Command({\n            Bucket: this.bucketName,\n            ContinuationToken: continuationToken || options.pagination,\n            Prefix: options.prefix,\n            MaxKeys: limit,\n        });\n\n        return this.s3Client.send(command);\n    }\n\n    /**\n     * Retrieves a list of contents from the S3 bucket based on the provided options.\n     *\n     * @param {ListRequestOptions} options - The options for listing the contents.\n     * @return {Promise<{ contents: unknown[]; nextContinuationToken?: string }>} - A promise that resolves to an object containing the list of contents and an optional next continuation token.\n     */\n    private async listContents(\n        options: ListRequestOptions,\n    ): Promise<{ contents: unknown[]; nextContinuationToken?: string }> {\n        let responseContents: any[] = [];\n        let continuationToken: string | undefined = undefined;\n        const limit = options.limit ?? 1000;\n        let continueListing = true;\n        while (continueListing) {\n            const listChunkLimit = limit - responseContents.length;\n            const response = await this.listChunk(\n                options,\n                continuationToken,\n                listChunkLimit,\n            );\n            continuationToken = response.NextContinuationToken;\n            responseContents = responseContents.concat(response.Contents ?? []);\n\n            if (responseContents.length >= limit || !continuationToken) {\n                continueListing = false;\n            }\n        }\n\n        return {\n            contents: responseContents,\n            nextContinuationToken: continuationToken,\n        };\n    }\n\n    /**\n     * Lists objects in the S3 bucket with pagination.\n     * @param options - The options for listing objects.\n     * @returns A promise that resolves to a paginated list of object keys.\n     */\n    async list(options: ListRequestOptions): Promise<ListResponse> {\n        let items: ListResponseItem[] = [];\n        const response = await this.listContents(options);\n\n        items = response.contents.length\n            ? listResponseContentsToListResponseItems(response.contents)\n            : [];\n\n        return {\n            items,\n            pagination: response.nextContinuationToken ?? null,\n            count: items.length,\n        };\n    }\n\n    /**\n     * Lists all objects in the S3 bucket.\n     * @param options - The options for listing objects.\n     * @returns A promise that resolves to list of object keys.\n     */\n\n    async listAll(options: ListRequestOptions): Promise<ListResponse> {\n        let allItems: ListResponseItem[] = [];\n        let pagination: string | undefined = undefined;\n\n        do {\n            const response: ListResponse = await this.list({\n                ...options,\n                pagination,\n            });\n\n            if (response.items?.length)\n                allItems = [...allItems, ...response.items];\n\n            pagination =\n                response.pagination === null ? undefined : response.pagination;\n        } while (pagination);\n\n        return { items: allItems, count: allItems.length };\n    }\n\n    /**\n     * Retrieves an object from the S3 bucket.\n     * @param key - The key of the object to retrieve.\n     * @returns A promise that resolves to the content of the file.\n     */\n    async getHeadObject(key: string): Promise<GetObjectResponse> {\n        const command = new HeadObjectCommand({\n            Bucket: this.bucketName,\n            Key: key,\n        });\n        const response = await this.s3Client.send(command);\n        return s3ObjectToObjectResponse(response);\n    }\n\n    /**\n     * Retrieves an object from the S3 bucket.\n     * @param key - The key of the object to retrieve.\n     * @returns A promise that resolves to the content of the file.\n     */\n    async getObject(key: string): Promise<GetObjectResponse> {\n        const command = new GetObjectCommand({\n            Bucket: this.bucketName,\n            Key: key,\n        });\n        const response = await this.s3Client.send(command);\n        return s3ObjectToObjectResponse(response);\n    }\n\n    /**\n     * Generates a signed URL for accessing an object in the S3 bucket.\n     * @param key - The key of the object.\n     * @param expiresInMinutes - The number of minutes the signed URL should be valid for. Defaults to 60 minutes.\n     * @returns A promise that resolves to the signed URL.\n     */\n    getDownloadUrl(\n        key: string,\n        expiresInMinutes: number = 60,\n    ): Promise<string> {\n        const expiresIn = expiresInMinutes * 60;\n        const command = new GetObjectCommand({\n            Bucket: this.bucketName,\n            Key: key,\n        });\n        return getSignedUrl(this.s3Client, command, { expiresIn });\n    }\n\n    /**\n     * Retrieves a signed URL for uploading an object to the S3 bucket.\n     *\n     * @param {string} key - The key of the object to be uploaded.\n     * @param {number} [expiresInMinutes=60] - The number of minutes the signed URL should be valid for. Defaults to 60 minutes.\n     * @returns A promise that resolves to the signed URL.\n     */\n    async getUploadUrl(\n        key: string,\n        expiresInMinutes: number = 60,\n    ): Promise<GetUploadUrlResponse> {\n        const expiresIn = expiresInMinutes * 60;\n\n        const putObjectCommandParams: PutObjectAclCommandInput = {\n            Bucket: process.env.UPLOAD_BUCKET_NAME,\n            Key: key,\n            ACL: 'private',\n        };\n\n        const command = new PutObjectCommand(putObjectCommandParams);\n\n        const signedUrl = await getSignedUrl(this.s3Client, command, {\n            expiresIn,\n        });\n\n        return {\n            signedUrl,\n            key: `https://${process.env.UPLOAD_BUCKET_NAME}.s3.${process.env.AWS_DEFAULT_REGION}.amazonaws.com/${key}`,\n        };\n    }\n\n    /**\n     * Uploads an object to the S3 bucket.\n     * @param key - The key of the object to upload.\n     * @param body - The content of the object to upload.\n     * @param metadata - Optional metadata to associate with the object.\n     * @returns A promise that resolves to the response containing the key of the uploaded object.\n     */\n    async upload(\n        key: string,\n        body: FileContent,\n        metadata?: { [key: string]: string },\n    ): Promise<UploadResponse> {\n        const command = new PutObjectCommand({\n            Bucket: this.bucketName,\n            Key: key,\n            Body: body,\n            Metadata: metadata,\n        });\n        await this.s3Client.send(command);\n        return { key };\n    }\n\n    /**\n     * Creates a writable stream for uploading a file to the S3 bucket.\n     *\n     * @param {string} key - The key of the object to upload.\n     * @return {CreateUploadWriteStreamResponse} An object containing the key of the uploaded object, the writable stream, and a promise that resolves when the upload is complete.\n     */\n    createUploadWriteStream(key: string): CreateUploadWriteStreamResponse {\n        const streamPassThrough = new stream.PassThrough();\n        const params = {\n            Bucket: this.bucketName,\n            Key: key,\n            Body: streamPassThrough,\n        };\n\n        const upload = new Upload({\n            client: this.s3Client,\n            params,\n            queueSize: 5,\n            partSize: 8 * 1024 * 1024,\n        });\n\n        return {\n            key,\n            stream: streamPassThrough,\n            promise: upload.done(),\n        };\n    }\n\n    /**\n     * Deletes an object from the S3 bucket.\n     * @param key - The key of the object to delete.\n     * @returns A promise that resolves to true if the object was deleted successfully.\n     */\n    async delete(key: string): Promise<boolean> {\n        const command = new DeleteObjectCommand({\n            Bucket: this.bucketName,\n            Key: key,\n        });\n        await this.s3Client.send(command);\n        return true;\n    }\n\n    async getHeadBucket(): Promise<HeadBucketResponse> {\n        try {\n            const command = new HeadBucketCommand({\n                Bucket: this.bucketName,\n            });\n            return this.s3Client.send(command);\n        } catch (error) {\n            throw new Error(\n                'Error in S3 getHeadContainer. bucketName: ' +\n                    this.bucketName +\n                    ' Error: ' +\n                    error,\n            );\n        }\n    }\n\n    /**\n     * Generates an upload ID for multipart upload in the S3 bucket.\n     *\n     * @param {string} key - The key of the object to upload.\n     * @return {Promise<string>} A promise that resolves to the generated upload ID.\n     * @throws {Error} If no upload ID was generated.\n     */\n    async generateUploadIdMultipart(key: string): Promise<string> {\n        const params = {\n            Bucket: this.bucketName,\n            Key: key,\n        };\n        const response = await this.s3.createMultipartUpload(params);\n        if (!response?.UploadId) throw new Error('No upload ID was generated');\n        return response.UploadId;\n    }\n\n    async listMultipartUploadsForBucket(): Promise<ListMultipartUploadsResponse> {\n        const params = {\n            Bucket: this.bucketName,\n        };\n        const response = await this.s3.listMultipartUploads(params);\n        return {\n            bucketName: this.bucketName,\n            uploads: response.Uploads\n                ? response.Uploads.map((upload) => ({\n                      uploadId: upload.UploadId || '',\n                      key: upload.Key || '',\n                      initiator: upload?.Initiator?.ID || '',\n                      owner: upload?.Owner?.ID || '',\n                      storageClass: upload.StorageClass || '',\n                      initiated: upload.Initiated || '',\n                  }))\n                : [],\n        };\n    }\n\n    /**\n     * Retrieves the list of parts for a multipart upload.\n     *\n     * @param {string} key - The key of the object being uploaded.\n     * @param {string} uploadId - The ID of the multipart upload.\n     * @return {Promise<ListPartsMultipartUploadResponse>} A promise that resolves to the list of parts for the multipart upload.\n     */\n    async listMultipartUploadsForKey(\n        key: string,\n        uploadId: string,\n    ): Promise<ListPartsMultipartUploadResponse> {\n        const params = {\n            Bucket: this.bucketName,\n            Key: key,\n            UploadId: uploadId,\n        };\n        const response = await this.s3.listParts(params);\n\n        const parts = response.Parts\n            ? response.Parts.map((part) => ({\n                  PartNumber: part.PartNumber!,\n                  LastModified: part.LastModified!,\n                  ETag: part.ETag!,\n                  Size: part.Size!,\n              }))\n            : [];\n\n        return {\n            Parts: parts,\n        };\n    }\n\n    async uploadMultipart(\n        key: string,\n        file: FileContent,\n        partNumber: number,\n        uploadId?: string,\n    ): Promise<string> {\n        const upId = uploadId || (await this.generateUploadIdMultipart(key));\n        const params = {\n            Bucket: this.bucketName,\n            Key: key,\n            Body: file,\n            PartNumber: partNumber,\n            UploadId: upId,\n        };\n        await this.s3.uploadPart(params);\n        return upId;\n    }\n\n    async completeMultipartUpload(\n        key: string,\n        uploadId: string,\n    ): Promise<void> {\n        const partsResponse = await this.listMultipartUploadsForKey(\n            key,\n            uploadId,\n        );\n        const partsList =\n            partsResponse?.Parts &&\n            partsResponse.Parts.map(\n                // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars\n                ({ Size, LastModified, ...partList }) => partList,\n            );\n        const completeMultipartParams = {\n            Bucket: this.bucketName,\n            Key: key,\n            UploadId: uploadId,\n            MultipartUpload: {\n                Parts: partsList,\n            },\n        };\n        await this.s3.completeMultipartUpload(completeMultipartParams);\n    }\n\n    async abortMultipartUpload(key: string, uploadId: string): Promise<void> {\n        const params = {\n            Bucket: this.bucketName,\n            Key: key,\n            UploadId: uploadId,\n        };\n        await this.s3.abortMultipartUpload(params);\n    }\n\n    async getMultipartUploadPresignedUrl(\n        key: string,\n        uploadId: string,\n        partNumber: string,\n        expiresInMinutes: number = 60,\n    ): Promise<string> {\n        const uploadPartParams = {\n            Bucket: this.bucketName,\n            Key: key,\n            UploadId: uploadId,\n            PartNumber: parseInt(partNumber, 10),\n        };\n        const expiresIn = expiresInMinutes * 60;\n        const presignedUrl = await getSignedUrl(\n            this.s3Client,\n            new UploadPartCommand(uploadPartParams),\n            { expiresIn },\n        );\n\n        return presignedUrl;\n    }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { GetObjectCommandOutput } from '@aws-sdk/client-s3';\nimport { GetObjectResponse, ListResponseItem } from '../../../types';\nimport { Readable } from 'stream';\n\n/**\n * Converts an array of S3 response contents into an array of ListResponseItem objects.\n *\n * @param {any[]} responseContents - The array of S3 response contents.\n * @return {ListResponseItem[]} The array of ListResponseItem objects.\n */\nexport function listResponseContentsToListResponseItems(\n    responseContents: any[],\n): ListResponseItem[] {\n    return responseContents.map((responseContent) => {\n        return {\n            key: responseContent.Key,\n            lastModified: new Date(responseContent.LastModified),\n            size: responseContent.Size,\n            eTag: responseContent.ETag,\n        };\n    });\n}\n\n/**\n * Converts an S3 object response to a standardized object response.\n *\n * @param {GetObjectCommandOutput} s3Object - The S3 object response to convert.\n * @return {GetObjectResponse} The converted object response.\n */\nexport function s3ObjectToObjectResponse(\n    s3Object: GetObjectCommandOutput,\n): GetObjectResponse {\n    return {\n        body: s3Object.Body as Readable,\n        metadata: s3Object.Metadata,\n        contentType: s3Object.ContentType,\n        contentLength: s3Object.ContentLength as number,\n        contentEncoding: s3Object.ContentEncoding,\n        cacheControl: s3Object.CacheControl,\n        contentDisposition: s3Object.ContentDisposition,\n        contentLanguage: s3Object.ContentLanguage,\n        eTag: s3Object.ETag,\n        lastModified: s3Object.LastModified,\n    };\n}\n","export const OBJECT_STORAGE_SERVICE_TYPES = {\n    AWS_S3: 'aws_s3',\n    AZURE_BLOB_STORAGE: 'azure_blob_storage',\n};\n","import { IObjectStorage } from '../interfaces';\nimport { S3StorageService, BlobStorageService } from './storage';\nimport { ObjectStorageOptions } from '../types';\nimport { OBJECT_STORAGE_SERVICE_TYPES } from '../shared/utils/constants';\n\nexport class ObjectStorageFactory {\n    static async instance(\n        bucketName: string,\n        options?: ObjectStorageOptions,\n    ): Promise<IObjectStorage> {\n        const provider =\n            options?.provider?.toLowerCase() ||\n            process.env.OBJECT_STORAGE_SERVICE?.toLowerCase();\n        switch (provider) {\n            case OBJECT_STORAGE_SERVICE_TYPES.AWS_S3:\n                return new S3StorageService(bucketName, options);\n            case OBJECT_STORAGE_SERVICE_TYPES.AZURE_BLOB_STORAGE:\n                return new BlobStorageService(bucketName);\n            default:\n                throw new Error(\n                    `Unsupported object storage provider: ${provider}`,\n                );\n        }\n    }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { IObjectStorage, IGetObjectOptions } from '../interfaces';\nimport {\n    ListResponse,\n    FileContent,\n    UploadResponse,\n    GetObjectResponse,\n    ListRequestOptions,\n    GetUploadUrlResponse,\n    CreateUploadWriteStreamResponse,\n    HeadBucketResponse,\n    ObjectStorageOptions,\n    ListPartsMultipartUploadResponse,\n    ListMultipartUploadsResponse,\n} from '../types';\nimport { ObjectStorageFactory } from '../services/objectStorageFactory.service';\n\nexport default class ObjectStorageService {\n    static bucketName: string;\n    static objectStorageOptions: ObjectStorageOptions;\n\n    constructor(bucketName: string, options?: ObjectStorageOptions) {\n        ObjectStorageService.bucketName = bucketName;\n        if (options) ObjectStorageService.objectStorageOptions = options;\n    }\n\n    static async getObjectStorageServiceInstance(\n        bucketName: string = ObjectStorageService.bucketName,\n        options:\n            | ObjectStorageOptions\n            | undefined = ObjectStorageService.objectStorageOptions,\n    ): Promise<IObjectStorage> {\n        if (!bucketName)\n            throw new Error('Bucket name not provided or not valid value');\n        return ObjectStorageFactory.instance(bucketName, options);\n    }\n\n    /**\n     * Retrieves a list of objects from the object storage service.\n     *\n     * @param {ListRequestOptions} options - The options to apply to the list operation.\n     * @param {string} [bucketName] - The name of the bucket to list objects from. If not provided, the default bucket name will be used.\n     * @return {Promise<ListResponse>} A promise that resolves to the list of objects.\n     */\n    static async list(\n        options: ListRequestOptions,\n        bucketName?: string,\n    ): Promise<ListResponse> {\n        return ObjectStorageService.getObjectStorageServiceInstance(\n            bucketName,\n        ).then((instance) => instance.list(options));\n    }\n\n    /**\n     * Retrieves a list of all objects from the object storage service.\n     *\n     * @param {ListRequestOptions} options - The options to apply to the list operation.\n     * @param {string} [bucketName] - The name of the bucket to list objects from. If not provided, the default bucket name will be used.\n     * @return {Promise<ListResponse>} A promise that resolves to the list of all objects.\n     */\n    static async listAll(\n        options: ListRequestOptions,\n        bucketName?: string,\n    ): Promise<ListResponse> {\n        return ObjectStorageService.getObjectStorageServiceInstance(\n            bucketName,\n        ).then((instance) => instance.listAll(options));\n    }\n\n    /**\n     * Retrieves an object from the object storage service.\n     *\n     * @param {string} key - The key of the object to retrieve.\n     * @param {string} [bucketName] - The name of the bucket where the object is stored. If not provided, the default bucket name will be used.\n     * @return {Promise<GetObjectResponse>} A promise that resolves to the retrieved object.\n     */\n    static async getObject(\n        key: string,\n        bucketName?: string,\n        options?: IGetObjectOptions,\n    ): Promise<GetObjectResponse> {\n        return ObjectStorageService.getObjectStorageServiceInstance(\n            bucketName,\n        ).then((instance) => instance.getObject(key, options));\n    }\n\n    /**\n     * Retrieves an object info (without file content) from the object storage service.\n     * @param key - The key of the object to retrieve.\n     * @returns A promise that resolves to the info of the file.\n     */\n    static async getHeadObject(\n        key: string,\n        bucketName?: string,\n    ): Promise<GetObjectResponse> {\n        return ObjectStorageService.getObjectStorageServiceInstance(\n            bucketName,\n        ).then((instance) => instance.getHeadObject(key));\n    }\n\n    /**\n     * Retrieves a signed URL for the specified object in the object storage service.\n     *\n     * @param {string} key - The key of the object for which to generate the signed URL.\n     * @param {number} expiresInMinutes - The number of minutes until the signed URL expires.\n     * @param {string} [bucketName] - The name of the bucket where the object is stored. If not provided, the default bucket name will be used.\n     * @return {Promise<string>} A promise that resolves to the generated signed URL.\n     */\n    static async getDownloadUrl(\n        key: string,\n        expiresInMinutes: number,\n        bucketName?: string,\n    ): Promise<string> {\n        return ObjectStorageService.getObjectStorageServiceInstance(\n            bucketName,\n        ).then((instance) => instance.getDownloadUrl(key, expiresInMinutes));\n    }\n\n    /**\n     * Retrieves an upload URL for the specified object in the object storage service.\n     *\n     * @param {string} key - The key of the object for which to generate the upload URL.\n     * @param {number} expiresInMinutes - The number of minutes until the upload URL expires.\n     * @param {string} [bucketName] - The name of the bucket where the object will be stored. If not provided, the default bucket name will be used.\n     * @return {Promise<string>} A promise that resolves to the generated upload URL.\n     */\n    static async getUploadUrl(\n        key: string,\n        expiresInMinutes: number,\n        bucketName?: string,\n    ): Promise<GetUploadUrlResponse> {\n        return ObjectStorageService.getObjectStorageServiceInstance(\n            bucketName,\n        ).then((instance) => instance.getUploadUrl(key, expiresInMinutes));\n    }\n\n    /**\n     * Uploads a file to the object storage service.\n     *\n     * @param {string} key - The key of the object to upload.\n     * @param {FileContent} body - The content of the file to upload.\n     * @param {Object} [metadata] - Optional metadata to associate with the object.\n     * @param {string} [bucketName] - The name of the bucket where the object will be stored. If not provided, the default bucket name will be used.\n     * @return {Promise<UploadResponse>} A promise that resolves to the response of the upload operation.\n     */\n    static async upload(\n        key: string,\n        body: FileContent,\n        metadata?: { [key: string]: string },\n        bucketName?: string,\n    ): Promise<UploadResponse> {\n        return ObjectStorageService.getObjectStorageServiceInstance(\n            bucketName,\n        ).then((instance) => instance.upload(key, body, metadata));\n    }\n\n    /**\n     * Creates an upload write stream for the specified key in the object storage service.\n     *\n     * @param {string} key - The key of the object to create the upload write stream for.\n     * @param {string} [bucketName] - The name of the bucket where the object will be stored. If not provided, the default bucket name will be used.\n     * @return {Promise<CreateUploadWriteStreamResponse>} A promise that resolves to the response of the upload operation.\n     */\n    static async createUploadWriteStream(\n        key: string,\n        bucketName?: string,\n    ): Promise<CreateUploadWriteStreamResponse> {\n        return ObjectStorageService.getObjectStorageServiceInstance(\n            bucketName,\n        ).then((instance) => instance.createUploadWriteStream(key));\n    }\n\n    /**\n     * Deletes an object or multiple objects from the object storage service.\n     *\n     * @param {string | string[]} key - The key or array of keys of the objects to delete.\n     * @param {string} [bucketName] - The name of the bucket where the objects are stored. If not provided, the default bucket name will be used.\n     * @return {Promise<{ key: string; deleted: boolean; error?: string }[] | boolean>} A promise that resolves to an array of objects containing the key, deleted status, and an optional error message for each object deleted, or a boolean value indicating the success of the deletion.\n     */\n    static async delete(\n        key: string | string[],\n        bucketName?: string,\n    ): Promise<{ key: string; deleted: boolean; error?: string }[] | boolean> {\n        return ObjectStorageService.getObjectStorageServiceInstance(\n            bucketName,\n        ).then(async (instance) => {\n            if (Array.isArray(key)) {\n                const deleteBlobPromises = key.map(async (blobName) => {\n                    try {\n                        await instance.delete(blobName);\n                        return { key: blobName, deleted: true };\n                    } catch (error: any) {\n                        return {\n                            key: blobName,\n                            deleted: false,\n                            error: error?.message ?? '',\n                        };\n                    }\n                });\n                return Promise.all(deleteBlobPromises);\n            } else {\n                return instance.delete(key);\n            }\n        });\n    }\n\n    /**\n     * Retrieves the head bucket from the object storage service.\n     *\n     * @param {string} [bucketName] - The name of the bucket. If not provided, the default bucket name will be used.\n     * @return {Promise<HeadBucketResponse>} A promise that resolves to the head bucket response.\n     */\n    static async getHeadBucket(\n        bucketName?: string,\n    ): Promise<HeadBucketResponse> {\n        return ObjectStorageService.getObjectStorageServiceInstance(\n            bucketName,\n        ).then((instance) => instance.getHeadBucket());\n    }\n\n    /**\n     * Generates a unique upload ID for a multipart upload.\n     *\n     * @param {string} key - The key of the object to upload.\n     * @param {string} [bucketName] - The name of the bucket. If not provided, the default bucket name will be used.\n     * @return {Promise<string>} A promise that resolves to the generated upload ID.\n     */\n    static async generateUploadIdMultipart(\n        key: string,\n        bucketName?: string,\n    ): Promise<string> {\n        return ObjectStorageService.getObjectStorageServiceInstance(\n            bucketName,\n        ).then((instance) => instance.generateUploadIdMultipart(key));\n    }\n\n    /**\n     * Retrieves a list of multipart uploads for a specified key in the object storage service.\n     *\n     * @param {string} key - The key of the object to retrieve uploads for.\n     * @param {string} [bucketName] - The name of the bucket. If not provided, the default bucket name will be used.\n     * @param {string} [uploadId] - The upload ID to filter the results by.\n     * @return {Promise<ListPartsMultipartUploadResponse>} A promise that resolves to the list of multipart uploads for the specified key.\n     */\n    static async listMultipartUploadsForKey(\n        key: string,\n        bucketName?: string,\n        uploadId?: string,\n    ): Promise<ListPartsMultipartUploadResponse> {\n        return ObjectStorageService.getObjectStorageServiceInstance(\n            bucketName,\n        ).then((instance) =>\n            instance.listMultipartUploadsForKey(key, uploadId),\n        );\n    }\n\n    /**\n     * Retrieves a list of all multipart uploads for a specified bucket in the object storage service.\n     *\n     * @param {string} [bucketName] - The name of the bucket. If not provided, the default bucket name will be used.\n     * @return {Promise<ListMultipartUploadsResponse>} A promise that resolves to the list of multipart uploads for the specified bucket.\n     */\n    static async listMultipartUploadsForBucket(\n        bucketName?: string,\n    ): Promise<ListMultipartUploadsResponse> {\n        return ObjectStorageService.getObjectStorageServiceInstance(\n            bucketName,\n        ).then((instance) => instance.listMultipartUploadsForBucket());\n    }\n\n    /**\n     * Uploads a multipart file to the specified bucket in the object storage service.\n     *\n     * @param {string} key - The key of the object to upload the multipart file to.\n     * @param {FileContent} file - The content of the file to upload.\n     * @param {number} partNumber - The number of the part being uploaded.\n     * @param {string} [uploadId] - The ID of the multipart upload.\n     * @param {string} [bucketName] - The name of the bucket to upload the file to. If not provided, the default bucket name will be used.\n     * @return {Promise<string>} A Promise that resolves to the base64 encoded block ID of the uploaded part.\n     */\n    static async uploadMultipart(\n        key: string,\n        file: FileContent,\n        partNumber: number,\n        uploadId?: string,\n        bucketName?: string,\n    ): Promise<string> {\n        return ObjectStorageService.getObjectStorageServiceInstance(\n            bucketName,\n        ).then((instance) =>\n            instance.uploadMultipart(key, file, partNumber, uploadId),\n        );\n    }\n\n    /**\n     * Completes a multipart upload for the specified object in the object storage service.\n     *\n     * @param {string} key - The key of the object to complete the multipart upload for.\n     * @param {string} uploadId - The ID of the multipart upload to complete.\n     * @param {string} [bucketName] - The name of the bucket to complete the multipart upload in. If not provided, the default bucket name will be used.\n     * @return {Promise<void>} A Promise that resolves when the multipart upload is completed.\n     */\n    static async completeMultipartUpload(\n        key: string,\n        uploadId: string,\n        bucketName?: string,\n    ): Promise<void> {\n        return ObjectStorageService.getObjectStorageServiceInstance(\n            bucketName,\n        ).then((instance) => instance.completeMultipartUpload(key, uploadId));\n    }\n\n    /**\n     * Aborts a multipart upload for the specified object in the object storage service.\n     *\n     * @param {string} key - The key of the object to abort the multipart upload for.\n     * @param {string} uploadId - The ID of the multipart upload to abort.\n     * @param {string} [bucketName] - The name of the bucket to abort the multipart upload in. If not provided, the default bucket name will be used.\n     * @return {Promise<void>} A Promise that resolves when the multipart upload is aborted.\n     */\n    static async abortMultipartUpload(\n        key: string,\n        uploadId: string,\n        bucketName?: string,\n    ): Promise<void> {\n        return ObjectStorageService.getObjectStorageServiceInstance(\n            bucketName,\n        ).then((instance) => instance.abortMultipartUpload(key, uploadId));\n    }\n\n    /**\n     * Retrieves a presigned URL for a specific part of a multipart upload.\n     *\n     * @param {string} key - The key of the object for which to generate the presigned URL.\n     * @param {string} uploadId - The ID of the multipart upload.\n     * @param {string} partNumber - The number of the part for which to generate the presigned URL.\n     * @param {number} [expiresInMinutes] - The number of minutes until the presigned URL expires. Default is 60 minutes.\n     * @return {Promise<string>} A Promise that resolves to the presigned URL for the specified part of the multipart upload.\n     */\n    static async getMultipartUploadPresignedUrl(\n        key: string,\n        uploadId: string,\n        partNumber: string,\n        expiresInMinutes?: number,\n    ): Promise<string> {\n        return ObjectStorageService.getObjectStorageServiceInstance().then(\n            (instance) =>\n                instance.getMultipartUploadPresignedUrl(\n                    key,\n                    uploadId,\n                    partNumber,\n                    expiresInMinutes,\n                ),\n        );\n    }\n}\n"]}