From 36e1ee7782e8e6f73e44e08da379cbb17e278e9d Mon Sep 17 00:00:00 2001 From: "Kho Yee, Choy" Date: Sat, 23 Nov 2024 06:11:35 +0900 Subject: [PATCH] fix (Storage/FileUploader): FileUploader does not upload processed file contents in certain scenarios (#6050) * fix: FileUploader should upload processed file regardless of key/path --- .changeset/mighty-ladybugs-chew.md | 5 ++ .../process-file-access-level/index.page.tsx | 13 ++++- .../process-file-access-level/index.page.tsx | 13 ++++- .../utils/__tests__/getInput.spec.ts | 54 ++++++++++++++----- .../components/FileUploader/utils/getInput.ts | 2 +- 5 files changed, 70 insertions(+), 17 deletions(-) create mode 100644 .changeset/mighty-ladybugs-chew.md diff --git a/.changeset/mighty-ladybugs-chew.md b/.changeset/mighty-ladybugs-chew.md new file mode 100644 index 00000000000..3a1d62eb86e --- /dev/null +++ b/.changeset/mighty-ladybugs-chew.md @@ -0,0 +1,5 @@ +--- +'@aws-amplify/ui-react-storage': patch +--- + +fix (Storage/FileUploader): FileUploader does not upload processed file contents in certain scenarios diff --git a/examples/next/pages/ui/components/storage/file-uploader/process-file-access-level/index.page.tsx b/examples/next/pages/ui/components/storage/file-uploader/process-file-access-level/index.page.tsx index f2e3caad4d0..991d0ddd35a 100644 --- a/examples/next/pages/ui/components/storage/file-uploader/process-file-access-level/index.page.tsx +++ b/examples/next/pages/ui/components/storage/file-uploader/process-file-access-level/index.page.tsx @@ -9,7 +9,13 @@ Amplify.configure(awsExports); const processFile: FileUploaderProps['processFile'] = async ({ file }) => { const fileExtension = file.name.split('.').pop(); - return file + // pretend the input `file` has been compressed: + const blob = new Blob(['Compressed data'], { type: 'text/plain' }); + const compressedFile = new File([blob], undefined, { + type: 'text/plain', + }); + + return compressedFile .arrayBuffer() .then((filebuffer) => window.crypto.subtle.digest('SHA-1', filebuffer)) .then((hashBuffer) => { @@ -17,7 +23,10 @@ const processFile: FileUploaderProps['processFile'] = async ({ file }) => { const hashHex = hashArray .map((a) => a.toString(16).padStart(2, '0')) .join(''); - return { file, key: `${hashHex}.${fileExtension}` }; + return { + file: compressedFile, + key: `${hashHex}.${fileExtension}`, + }; }); }; diff --git a/examples/next/pages/ui/components/storage/storage-manager/process-file-access-level/index.page.tsx b/examples/next/pages/ui/components/storage/storage-manager/process-file-access-level/index.page.tsx index b7e61805b11..9ede3b37d1c 100644 --- a/examples/next/pages/ui/components/storage/storage-manager/process-file-access-level/index.page.tsx +++ b/examples/next/pages/ui/components/storage/storage-manager/process-file-access-level/index.page.tsx @@ -12,7 +12,13 @@ Amplify.configure(awsExports); const processFile: StorageManagerProps['processFile'] = async ({ file }) => { const fileExtension = file.name.split('.').pop(); - return file + // pretend the input `file` has been compressed: + const blob = new Blob(['Compressed data'], { type: 'text/plain' }); + const compressedFile = new File([blob], undefined, { + type: 'text/plain', + }); + + return compressedFile .arrayBuffer() .then((filebuffer) => window.crypto.subtle.digest('SHA-1', filebuffer)) .then((hashBuffer) => { @@ -20,7 +26,10 @@ const processFile: StorageManagerProps['processFile'] = async ({ file }) => { const hashHex = hashArray .map((a) => a.toString(16).padStart(2, '0')) .join(''); - return { file, key: `${hashHex}.${fileExtension}` }; + return { + file: compressedFile, + key: `${hashHex}.${fileExtension}`, + }; }); }; diff --git a/packages/react-storage/src/components/FileUploader/utils/__tests__/getInput.spec.ts b/packages/react-storage/src/components/FileUploader/utils/__tests__/getInput.spec.ts index fa5537ea91e..bf9d4eacb09 100644 --- a/packages/react-storage/src/components/FileUploader/utils/__tests__/getInput.spec.ts +++ b/packages/react-storage/src/components/FileUploader/utils/__tests__/getInput.spec.ts @@ -148,39 +148,69 @@ describe('getInput', () => { expect(output).toStrictEqual(expected); }); - it('includes additional values returned from `processFile` in `options`', async () => { + it('correctly parses values returned from `processFile`', async () => { const contentDisposition = 'attachment'; const metadata = { key }; + const processedFile = new File([''], `myfile.txt`); - const expected: UploadDataWithPathInput = { - data: file, + const input = getInput({ + ...pathStringInput, + processFile: ({ key, ...rest }) => ({ + ...rest, + key: `${processFilePrefix}${key}`, + file: processedFile, + metadata, + contentDisposition, + }), + }); + + const output = await input(); + + expect(output).toMatchObject({ + data: expect.any(File), options: { contentDisposition, contentType: file.type, metadata, - onProgress, + onProgress: expect.any(Function), useAccelerateEndpoint: undefined, }, path: `${stringPath}${processFilePrefix}${key}`, - }; + }); + expect(output.data).toBe(processedFile); + }); + + it('correctly parses values returned from `processFile` when in accessLevel mode', async () => { + const contentDisposition = 'attachment'; + const metadata = { key }; + const processedFile = new File([], `myfile.txt`); const input = getInput({ - ...pathStringInput, + ...accessLevelWithoutPathInput, processFile: ({ key, ...rest }) => ({ + ...rest, key: `${processFilePrefix}${key}`, metadata, contentDisposition, - ...rest, + file: processedFile, }), }); const output = await input(); - expect(output).toStrictEqual(expected); - expect(output.options?.metadata).toStrictEqual(metadata); - expect(output.options?.contentDisposition).toStrictEqual( - contentDisposition - ); + expect(output).toMatchObject({ + data: expect.any(File), + options: { + accessLevel, + contentDisposition, + contentType: file.type, + metadata, + onProgress: expect.any(Function), + useAccelerateEndpoint: undefined, + }, + }); + + expect(output.data).toBe(processedFile); }); it('defaults `options.contentType` to "binary/octet-stream" when no file type is provided', async () => { diff --git a/packages/react-storage/src/components/FileUploader/utils/getInput.ts b/packages/react-storage/src/components/FileUploader/utils/getInput.ts index 39e96df7d69..4aa0e2910e7 100644 --- a/packages/react-storage/src/components/FileUploader/utils/getInput.ts +++ b/packages/react-storage/src/components/FileUploader/utils/getInput.ts @@ -61,7 +61,7 @@ export const getInput = ({ hasCallbackPath ? path({ identityId }) : path }${processedKey}`; - inputResult = { data: file, path: resolvedPath, options }; + inputResult = { data, path: resolvedPath, options }; } return inputResult;