-
Notifications
You must be signed in to change notification settings - Fork 566
Open
Description
Currently when copying objects across buckets I'm downloading from the source bucket and re-uploading to the target bucket, but it would be preferable to avoid unnecessary data transfer.
My implementation is as follows:
import log from 'encore.dev/log';
import {
Attrser,
Downloader,
Lister,
Uploader,
} from 'encore.dev/storage/objects';
import { UnexpectedError } from '~common/domain/errors/unexpected-error.class';
export const copyObject = async (data: {
sourceBucket: Downloader & Lister & Attrser;
sourceKey: string;
targetBucket: Uploader;
targetKey: string;
recursive?: boolean;
}) => {
const {
sourceBucket,
sourceKey,
targetBucket,
targetKey,
recursive = false,
} = data;
if (recursive) {
const sourceObjects = sourceBucket.list({
prefix: sourceKey,
});
for await (const sourceObject of sourceObjects) {
await copyObject({
sourceBucket,
sourceKey: sourceObject.name,
targetBucket,
targetKey: sourceObject.name.replace(sourceKey, targetKey),
recursive: false,
});
}
return;
}
try {
// TODO: This is not efficient, we should use the S3 copy API instead, but that is not exposed by encore.dev
const sourceAttrs = await sourceBucket.attrs(sourceKey);
const sourceObject = await sourceBucket.download(sourceKey);
const targetObject = await targetBucket.upload(targetKey, sourceObject, {
contentType: sourceAttrs.contentType,
});
return targetObject;
} catch (error) {
log.error('Error copying object', {
error,
sourceKey,
targetKey,
});
throw new UnexpectedError(
`Error copying object ${sourceKey} to ${targetKey}`,
error,
);
}
};Thanks in advance!
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels