Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add function to allow user to set destination in transfer manager #2497

Merged
merged 2 commits into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions src/transfer-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<UploadOptions, 'destination'>;
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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),
Expand Down
19 changes: 19 additions & 0 deletions test/transfer-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
MultiPartUploadError,
MultiPartUploadHelper,
UploadOptions,
UploadManyFilesOptions,

Check warning on line 29 in test/transfer-manager.ts

View workflow job for this annotation

GitHub Actions / lint

'UploadManyFilesOptions' is defined but never used
TransferManager,
Storage,
DownloadResponse,
Expand Down Expand Up @@ -173,6 +174,24 @@

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', () => {
Expand Down
Loading