From dc1e488b50dd7e2deab3e8b28c7d6ece36b90b0e Mon Sep 17 00:00:00 2001 From: Denis DelGrosso <85250797+ddelgrosso1@users.noreply.github.com> Date: Mon, 15 Jul 2024 10:06:36 -0400 Subject: [PATCH] feat: add function to allow user to set destination in transfer manager (#2497) * feat: add function to allow user to set destination in transfer manager * lint --- src/transfer-manager.ts | 12 +++++++++--- test/transfer-manager.ts | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/transfer-manager.ts b/src/transfer-manager.ts index d0fe21f75..f253461d9 100644 --- a/src/transfer-manager.ts +++ b/src/transfer-manager.ts @@ -94,6 +94,10 @@ const GCCL_GCS_CMD_FEATURE = { export interface UploadManyFilesOptions { concurrencyLimit?: number; + customDestinationBuilder?( + path: string, + options: UploadManyFilesOptions + ): string; skipIfExists?: boolean; prefix?: string; passthroughOptions?: Omit; @@ -411,6 +415,8 @@ export class TransferManager { * @typedef {object} UploadManyFilesOptions * @property {number} [concurrencyLimit] The number of concurrently executing promises * to use when uploading the files. + * @property {Function} [customDestinationBuilder] A fuction that will take the current path of a local file + * and return a string representing a custom path to be used to upload the file to GCS. * @property {boolean} [skipIfExists] Do not upload the file if it already exists in * the bucket. This will set the precondition ifGenerationMatch = 0. * @property {string} [prefix] A prefix to append to all of the uploaded files. @@ -490,9 +496,9 @@ export class TransferManager { [GCCL_GCS_CMD_KEY]: GCCL_GCS_CMD_FEATURE.UPLOAD_MANY, }; - passThroughOptionsCopy.destination = filePath - .split(path.sep) - .join(path.posix.sep); + passThroughOptionsCopy.destination = options.customDestinationBuilder + ? options.customDestinationBuilder(filePath, options) + : filePath.split(path.sep).join(path.posix.sep); if (options.prefix) { passThroughOptionsCopy.destination = path.posix.join( ...options.prefix.split(path.sep), diff --git a/test/transfer-manager.ts b/test/transfer-manager.ts index 741e0a91c..af5b2d7c2 100644 --- a/test/transfer-manager.ts +++ b/test/transfer-manager.ts @@ -26,6 +26,7 @@ import { MultiPartUploadError, MultiPartUploadHelper, UploadOptions, + UploadManyFilesOptions, TransferManager, Storage, DownloadResponse, @@ -173,6 +174,24 @@ describe('Transfer Manager', () => { await transferManager.uploadManyFiles([filePath]); }); + + it('allows the user to apply a custom destination transformation when supplied a custom function', async () => { + const paths = ['a', 'b', 'foo/bar', 'bar.txt']; + const expected = ['foo/a', 'b/bar', 'foo/foo/bar', 'bar.txt/bar']; + sandbox.stub(bucket, 'upload').callsFake((path, options) => { + const uploadOpts = options as UploadOptions; + assert(expected.includes(uploadOpts.destination as string)); + }); + + let callCount = 0; + const transformationFunc = (path: string) => { + assert.strictEqual(path, paths[callCount]); + return expected[callCount++]; + }; + await transferManager.uploadManyFiles(paths, { + customDestinationBuilder: transformationFunc, + }); + }); }); describe('downloadManyFiles', () => {