{"version":3,"file":"uploadHandlers.mjs","sources":["../../../../../../../../src/providers/s3/apis/internal/uploadData/multipart/uploadHandlers.ts"],"sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nimport { Amplify, } from '@aws-amplify/core';\nimport { StorageAction } from '@aws-amplify/core/internals/utils';\nimport { resolveS3ConfigAndInput, validateStorageOperationInput, } from '../../../../utils';\nimport { DEFAULT_ACCESS_LEVEL, DEFAULT_QUEUE_SIZE, STORAGE_INPUT_KEY, } from '../../../../utils/constants';\nimport { StorageError } from '../../../../../../errors/StorageError';\nimport { CanceledError } from '../../../../../../errors/CanceledError';\nimport { abortMultipartUpload, completeMultipartUpload, headObject, } from '../../../../utils/client/s3data';\nimport { getStorageUserAgentValue } from '../../../../utils/userAgent';\nimport { logger } from '../../../../../../utils';\nimport { calculateContentCRC32 } from '../../../../utils/crc32';\nimport { IntegrityError } from '../../../../../../errors/IntegrityError';\nimport { uploadPartExecutor } from './uploadPartExecutor';\nimport { getUploadsCacheKey, removeCachedUpload, serializeUploadOptions, } from './uploadCache';\nimport { getConcurrentUploadsProgressTracker } from './progressTracker';\nimport { loadOrCreateMultipartUpload } from './initialUpload';\nimport { getDataChunker } from './getDataChunker';\nimport { calculatePartSize } from './calculatePartSize';\n/**\n * Create closure hiding the multipart upload implementation details and expose the upload job and control functions(\n * onPause, onResume, onCancel).\n *\n * @internal\n */\nexport const getMultipartUploadHandlers = (uploadDataInput, size) => {\n    let resolveCallback;\n    let rejectCallback;\n    let inProgressUpload;\n    let resolvedS3Config;\n    let abortController;\n    let resolvedAccessLevel;\n    let resolvedBucket;\n    let resolvedKeyPrefix;\n    let resolvedIdentityId;\n    let uploadCacheKey;\n    let finalKey;\n    let expectedBucketOwner;\n    // Special flag that differentiates HTTP requests abort error caused by pause() from ones caused by cancel().\n    // The former one should NOT cause the upload job to throw, but cancels any pending HTTP requests.\n    // This should be replaced by a special abort reason. However,the support of this API is lagged behind.\n    let isAbortSignalFromPause = false;\n    const { resumableUploadsCache } = uploadDataInput.options ?? {};\n    const startUpload = async () => {\n        const { options: uploadDataOptions, data } = uploadDataInput;\n        const resolvedS3Options = await resolveS3ConfigAndInput(Amplify, uploadDataInput);\n        abortController = new AbortController();\n        isAbortSignalFromPause = false;\n        resolvedS3Config = resolvedS3Options.s3Config;\n        resolvedBucket = resolvedS3Options.bucket;\n        resolvedIdentityId = resolvedS3Options.identityId;\n        expectedBucketOwner = uploadDataOptions?.expectedBucketOwner;\n        const { inputType, objectKey } = validateStorageOperationInput(uploadDataInput, resolvedIdentityId);\n        const { contentDisposition, contentEncoding, contentType = 'application/octet-stream', metadata, preventOverwrite, onProgress, } = uploadDataOptions ?? {};\n        finalKey = objectKey;\n        // Resolve \"key\" specific options\n        if (inputType === STORAGE_INPUT_KEY) {\n            const accessLevel = uploadDataOptions\n                ?.accessLevel;\n            resolvedKeyPrefix = resolvedS3Options.keyPrefix;\n            finalKey = resolvedKeyPrefix + objectKey;\n            resolvedAccessLevel = resolveAccessLevel(accessLevel);\n        }\n        const { checksum: optionsHash } = await calculateContentCRC32(serializeUploadOptions(uploadDataOptions));\n        if (!inProgressUpload) {\n            const { uploadId, cachedParts, finalCrc32 } = await loadOrCreateMultipartUpload({\n                s3Config: resolvedS3Config,\n                accessLevel: resolvedAccessLevel,\n                bucket: resolvedBucket,\n                keyPrefix: resolvedKeyPrefix,\n                key: objectKey,\n                contentType,\n                contentDisposition,\n                contentEncoding,\n                metadata,\n                data,\n                size,\n                abortSignal: abortController.signal,\n                checksumAlgorithm: uploadDataOptions?.checksumAlgorithm,\n                optionsHash,\n                resumableUploadsCache,\n                expectedBucketOwner,\n            });\n            inProgressUpload = {\n                uploadId,\n                completedParts: cachedParts,\n                finalCrc32,\n            };\n        }\n        uploadCacheKey = size\n            ? getUploadsCacheKey({\n                file: data instanceof File ? data : undefined,\n                accessLevel: resolvedAccessLevel,\n                contentType: uploadDataOptions?.contentType,\n                bucket: resolvedBucket,\n                size,\n                key: objectKey,\n                optionsHash,\n            })\n            : undefined;\n        const dataChunker = getDataChunker(data, size);\n        const completedPartNumberSet = new Set(inProgressUpload.completedParts.map(({ PartNumber }) => PartNumber));\n        const onPartUploadCompletion = (partNumber, eTag, crc32) => {\n            inProgressUpload?.completedParts.push({\n                PartNumber: partNumber,\n                ETag: eTag,\n                // TODO: crc32 can always be added once RN also has an implementation\n                ...(crc32 ? { ChecksumCRC32: crc32 } : {}),\n            });\n        };\n        const concurrentUploadsProgressTracker = getConcurrentUploadsProgressTracker({\n            size,\n            onProgress,\n        });\n        const concurrentUploadPartExecutors = [];\n        for (let index = 0; index < DEFAULT_QUEUE_SIZE; index++) {\n            concurrentUploadPartExecutors.push(uploadPartExecutor({\n                dataChunkerGenerator: dataChunker,\n                completedPartNumberSet,\n                s3Config: resolvedS3Config,\n                abortSignal: abortController.signal,\n                bucket: resolvedBucket,\n                finalKey,\n                uploadId: inProgressUpload.uploadId,\n                onPartUploadCompletion,\n                onProgress: concurrentUploadsProgressTracker.getOnProgressListener(),\n                isObjectLockEnabled: resolvedS3Options.isObjectLockEnabled,\n                useCRC32Checksum: Boolean(inProgressUpload.finalCrc32),\n                expectedBucketOwner,\n            }));\n        }\n        await Promise.all(concurrentUploadPartExecutors);\n        validateCompletedParts(inProgressUpload.completedParts, size);\n        const { ETag: eTag } = await completeMultipartUpload({\n            ...resolvedS3Config,\n            abortSignal: abortController.signal,\n            userAgentValue: getStorageUserAgentValue(StorageAction.UploadData),\n        }, {\n            Bucket: resolvedBucket,\n            Key: finalKey,\n            UploadId: inProgressUpload.uploadId,\n            ChecksumCRC32: inProgressUpload.finalCrc32,\n            IfNoneMatch: preventOverwrite ? '*' : undefined,\n            MultipartUpload: {\n                Parts: sortUploadParts(inProgressUpload.completedParts),\n            },\n            ExpectedBucketOwner: expectedBucketOwner,\n        });\n        if (size) {\n            const { ContentLength: uploadedObjectSize, $metadata } = await headObject(resolvedS3Config, {\n                Bucket: resolvedBucket,\n                Key: finalKey,\n                ExpectedBucketOwner: expectedBucketOwner,\n            });\n            if (uploadedObjectSize && uploadedObjectSize !== size) {\n                throw new StorageError({\n                    name: 'Error',\n                    message: `Upload failed. Expected object size ${size}, but got ${uploadedObjectSize}.`,\n                    metadata: $metadata,\n                });\n            }\n        }\n        if (resumableUploadsCache && uploadCacheKey) {\n            await removeCachedUpload(resumableUploadsCache, uploadCacheKey);\n        }\n        const result = {\n            eTag,\n            contentType,\n            metadata,\n        };\n        return inputType === STORAGE_INPUT_KEY\n            ? { key: objectKey, ...result }\n            : { path: objectKey, ...result };\n    };\n    const startUploadWithResumability = () => startUpload()\n        .then(resolveCallback)\n        .catch(error => {\n        const abortSignal = abortController?.signal;\n        if (abortSignal?.aborted && isAbortSignalFromPause) {\n            logger.debug('upload paused.');\n        }\n        else {\n            // Uncaught errors should be exposed to the users.\n            rejectCallback(error);\n        }\n    });\n    const multipartUploadJob = () => new Promise((resolve, reject) => {\n        resolveCallback = resolve;\n        rejectCallback = reject;\n        startUploadWithResumability();\n    });\n    const onPause = () => {\n        isAbortSignalFromPause = true;\n        abortController?.abort();\n    };\n    const onResume = () => {\n        startUploadWithResumability();\n    };\n    const onCancel = (message) => {\n        // 1. abort in-flight API requests\n        abortController?.abort(message);\n        const cancelUpload = async () => {\n            // 2. clear upload cache.\n            if (uploadCacheKey && resumableUploadsCache) {\n                await removeCachedUpload(resumableUploadsCache, uploadCacheKey);\n            }\n            // 3. clear multipart upload on server side.\n            await abortMultipartUpload(resolvedS3Config, {\n                Bucket: resolvedBucket,\n                Key: finalKey,\n                UploadId: inProgressUpload?.uploadId,\n                ExpectedBucketOwner: expectedBucketOwner,\n            });\n        };\n        cancelUpload().catch(e => {\n            logger.debug('error when cancelling upload task.', e);\n        });\n        rejectCallback(\n        // Internal error that should not be exposed to the users. They should use isCancelError() to check if\n        // the error is caused by cancel().\n        new CanceledError(message ? { message } : undefined));\n    };\n    return {\n        multipartUploadJob,\n        onPause,\n        onResume,\n        onCancel,\n    };\n};\nconst resolveAccessLevel = (accessLevel) => accessLevel ??\n    Amplify.libraryOptions.Storage?.S3?.defaultAccessLevel ??\n    DEFAULT_ACCESS_LEVEL;\nconst validateCompletedParts = (completedParts, size) => {\n    const partsExpected = Math.ceil(size / calculatePartSize(size));\n    const validPartCount = completedParts.length === partsExpected;\n    const sorted = sortUploadParts(completedParts);\n    const validPartNumbers = sorted.every((part, index) => part.PartNumber === index + 1);\n    if (!validPartCount || !validPartNumbers) {\n        throw new IntegrityError();\n    }\n};\nconst sortUploadParts = (parts) => {\n    return [...parts].sort((partA, partB) => partA.PartNumber - partB.PartNumber);\n};\n"],"names":[],"mappings":"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"}