googleapis / nodejs-storage

Node.js client for Google Cloud Storage: unified object storage for developers and enterprises, from live data serving to data analytics/ML to data archiving.
https://cloud.google.com/storage/
Apache License 2.0
888 stars 368 forks source link

How to set destination while using uploadManyFiles in TransferManager #2492

Open arnav-kr opened 1 week ago

arnav-kr commented 1 week ago

I have a local directory and I want to upload its contents to cloud storage, but when using transferManager.uploadManyFiles with either the directory name, or array of files, the destination of the file in cloud storage is taken from the local file path.

local directory structure:

.
└── data
    └── avatars
        └── <image files>

here's my code

import { Storage, TransferManager } from "@google-cloud/storage";

const storage = new Storage();
const transferManager = new TransferManager(storage.bucket("bucket-name"));

const res = await transferManager.uploadManyFiles("data/avatars", {
  prefix: "avatars",
  passthroughOptions: {
    destination: "", // ???
  },
  skipIfExists: true,
});

when uploaded with following code, it becomes

.
└── avatars
    └── data
        └── avatars
            └── <image files>

the prefix property works, but I want to upload files directly to avatars/ there seem to be a passthroughOptions that can take a destination, but when using uploadManyFiles we don't know the exact file names, so can't make the full path

Shouldn't it be that while using prefix, property, the local file path shouldn't be considered?

arnav-kr commented 1 week ago

For a temporary fix, I edited library source to ignore local paths when prefix is supplied, it works, I'd still like to know the intended way of doing so

ddelgrosso1 commented 1 week ago

Hi @arnav-kr thanks for the question. The original intent was to mirror the same directory structure from local to storage. Obviously as you bumped into this can be improved. Currently destination isn't directly settable in uploadMany

https://github.com/googleapis/nodejs-storage/blob/18eef67892af6c7311a12d4c22579e240149eb02/src/transfer-manager.ts#L95-L100.

We can probably add some additional options to offer a greater degree of flexibility such as not mirroring the entire path structure and only using prefix. I can take a look at making these improvements in the near future.

arnav-kr commented 1 week ago

Probably in options, something like a destinationBuilder would make it more flexible, than specifing a string, as this way we can get the filename and process accodingly

...
destinationBuilder: (path, additionalParams) => {
  let dest;
  // perform operation on path
  return dest;
}
...