Skip to content

Commit

Permalink
feat: copyObject() can set new metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
bradenmacdonald committed Mar 15, 2024
1 parent c6856d6 commit 53345cc
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 8 deletions.
20 changes: 12 additions & 8 deletions client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -819,7 +819,11 @@ export class Client {
public async copyObject(
source: { sourceBucketName?: string; sourceKey: string; sourceVersionId?: string },
objectName: string,
options?: { bucketName?: string },
options?: {
bucketName?: string;
/** Metadata for the new object. If not specified, metadata will be copied from the source. */
metadata?: ObjectMetadata;
},
): Promise<CopiedObjectInfo> {
const bucketName = this.getBucketName(options);
const sourceBucketName = source.sourceBucketName ?? bucketName;
Expand All @@ -832,13 +836,13 @@ export class Client {
let xAmzCopySource = `${sourceBucketName}/${source.sourceKey}`;
if (source.sourceVersionId) xAmzCopySource += `?versionId=${source.sourceVersionId}`;

const response = await this.makeRequest({
method: "PUT",
bucketName,
objectName,
headers: new Headers({ "x-amz-copy-source": xAmzCopySource }),
returnBody: true,
});
const headers = new Headers(options?.metadata);
if (options?.metadata !== undefined) {
headers.set("x-amz-metadata-directive", "REPLACE");
}
headers.set("x-amz-copy-source", xAmzCopySource);

const response = await this.makeRequest({ method: "PUT", bucketName, objectName, headers, returnBody: true });

const responseText = await response.text();
// Parse the response XML.
Expand Down
34 changes: 34 additions & 0 deletions integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,40 @@ Deno.test({
},
});

Deno.test({
name: "copyObject() copies metadata, but we can override it if we want to",
fn: async () => {
const contents = new Uint8Array([1, 2, 3, 4, 5, 6]);
const sourceKey = "test-copy-metadata-source.txt";
const destKeySame = "test-copy-metadata-same.txt";
const destKeyNew = "test-copy-metadata-new.txt";

// Create the source file:
const metadata = {
"Content-Type": "test/custom",
"x-amz-meta-custom-key": "custom-value",
};
await client.putObject(sourceKey, contents, { metadata });
// Make sure the destination doesn't yet exist:
await client.deleteObject(destKeySame);
assertEquals(await client.exists(destKeySame), false);

// Copy it with the same metadata:
await client.copyObject({ sourceKey }, destKeySame);
const stat = await client.statObject(destKeySame);
assertEquals(stat.metadata, metadata);

// Copy it with the different metadata:
const newMetadata = {
"Content-Type": "application/javascript",
"x-amz-meta-other": "new",
};
await client.copyObject({ sourceKey }, destKeyNew, { metadata: newMetadata });
const statNew = await client.statObject(destKeyNew);
assertEquals(statNew.metadata, newMetadata);
},
});

Deno.test({
name: "bucketExists() can check if a bucket exists",
fn: async () => {
Expand Down

0 comments on commit 53345cc

Please sign in to comment.