Skip to content

Commit

Permalink
JavaScript (v3): S3 - Standardize S3 examples as per the audit. 🧵 1/2 (…
Browse files Browse the repository at this point in the history
  • Loading branch information
cpyle0819 authored Oct 2, 2024
1 parent 4c5489e commit c319089
Show file tree
Hide file tree
Showing 55 changed files with 2,026 additions and 601 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ describe("detect-labels handler", () => {
{
s3: {
bucket: {
name: "my-bucket",
name: "amzn-s3-demo-bucket",
},
object: {
key: "my_image.jpeg",
Expand Down
6 changes: 6 additions & 0 deletions javascriptv3/example_code/libs/tests/util-string.unit.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ describe("util-string", () => {
const u2 = getUniqueName(value);
expect(u1).not.toEqual(u2);
});

it("should return undefined if a falsy value is passed in", () => {
expect(getUniqueName()).toBeUndefined();
expect(getUniqueName("")).toBeUndefined();
expect(getUniqueName(0)).toBeUndefined();
});
});

describe("postfix", () => {
Expand Down
7 changes: 7 additions & 0 deletions javascriptv3/example_code/libs/utils/util-node.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import { fileURLToPath } from "url";

export const getEnv = (/** @type {string} */ key) => process.env[key];
export const setEnv = (/** @type {string} */ key, value) => {
process.env[key] = value;
};

/**
* Check if the running file was run directly.
* @param {string | URL} fileUrl
*/
export const isMain = (fileUrl) => process.argv[1] === fileURLToPath(fileUrl);
8 changes: 7 additions & 1 deletion javascriptv3/example_code/libs/utils/util-string.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@ import { v4 as uuidv4 } from "uuid";
/**
* @param {string} name
*/
export const getUniqueName = (name) => `${uuidv4()}-${name.toLowerCase()}`;
export const getUniqueName = (name) => {
if (!name) {
return;
}

return `${name.toLowerCase()}-${uuidv4()}`;
};

/**
* @param {int} length
Expand Down
34 changes: 17 additions & 17 deletions javascriptv3/example_code/s3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,28 +45,28 @@ Code examples that show you how to perform the essential operations within a ser

Code excerpts that show you how to call individual service functions.

- [CopyObject](actions/copy-object.js#L6)
- [CreateBucket](actions/create-bucket.js#L6)
- [CopyObject](actions/copy-object.js#L4)
- [CreateBucket](actions/create-bucket.js#L4)
- [DeleteBucket](actions/delete-bucket.js#L6)
- [DeleteBucketPolicy](actions/delete-bucket-policy.js#L6)
- [DeleteBucketWebsite](actions/delete-bucket-website.js#L6)
- [DeleteObject](actions/delete-object.js#L6)
- [DeleteObjects](actions/delete-objects.js#L6)
- [GetBucketAcl](actions/get-bucket-acl.js#L6)
- [GetBucketCors](actions/get-bucket-cors.js#L6)
- [GetBucketPolicy](actions/get-bucket-policy.js#L6)
- [GetBucketWebsite](actions/get-bucket-website.js#L6)
- [GetObject](actions/get-object.js#L6)
- [DeleteBucketPolicy](actions/delete-bucket-policy.js#L4)
- [DeleteBucketWebsite](actions/delete-bucket-website.js#L4)
- [DeleteObject](actions/delete-object.js#L4)
- [DeleteObjects](actions/delete-objects.js#L4)
- [GetBucketAcl](actions/get-bucket-acl.js#L4)
- [GetBucketCors](actions/get-bucket-cors.js#L4)
- [GetBucketPolicy](actions/get-bucket-policy.js#L4)
- [GetBucketWebsite](actions/get-bucket-website.js#L4)
- [GetObject](actions/get-object.js#L4)
- [GetObjectLegalHold](actions/get-object-legal-hold.js)
- [GetObjectLockConfiguration](actions/get-object-lock-configuration.js)
- [GetObjectRetention](actions/get-object-retention.js)
- [ListBuckets](actions/list-buckets.js#L6)
- [ListObjectsV2](actions/list-objects.js#L6)
- [PutBucketAcl](actions/put-bucket-acl.js#L6)
- [PutBucketCors](actions/put-bucket-cors.js#L6)
- [PutBucketPolicy](actions/put-bucket-policy.js#L6)
- [PutBucketWebsite](actions/put-bucket-website.js#L6)
- [PutObject](actions/put-object.js#L6)
- [ListObjectsV2](actions/list-objects.js#L4)
- [PutBucketAcl](actions/put-bucket-acl.js#L4)
- [PutBucketCors](actions/put-bucket-cors.js#L4)
- [PutBucketPolicy](actions/put-bucket-policy.js#L4)
- [PutBucketWebsite](actions/put-bucket-website.js#L4)
- [PutObject](actions/put-object.js#L4)
- [PutObjectLegalHold](actions/put-object-legal-hold.js)
- [PutObjectLockConfiguration](actions/put-object-lock-configuration.js)
- [PutObjectRetention](actions/put-object-retention.js)
Expand Down
84 changes: 66 additions & 18 deletions javascriptv3/example_code/s3/actions/copy-object.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,81 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import { fileURLToPath } from "url";

// snippet-start:[s3.JavaScript.buckets.copyObjectV3]
import { S3Client, CopyObjectCommand } from "@aws-sdk/client-s3";

const client = new S3Client({});
import {
S3Client,
CopyObjectCommand,
ObjectNotInActiveTierError,
waitUntilObjectExists,
} from "@aws-sdk/client-s3";

/**
* Copy an Amazon S3 object from one bucket to another.
* Copy an S3 object from one bucket to another.
*
* @param {{
* sourceBucket: string,
* sourceKey: string,
* destinationBucket: string,
* destinationKey: string }} config
*/
export const main = async () => {
const command = new CopyObjectCommand({
CopySource: "SOURCE_BUCKET/SOURCE_OBJECT_KEY",
Bucket: "DESTINATION_BUCKET",
Key: "NEW_OBJECT_KEY",
});
export const main = async ({
sourceBucket,
sourceKey,
destinationBucket,
destinationKey,
}) => {
const client = new S3Client({});

try {
const response = await client.send(command);
console.log(response);
} catch (err) {
console.error(err);
await client.send(
new CopyObjectCommand({
CopySource: `${sourceBucket}/${sourceKey}`,
Bucket: destinationBucket,
Key: destinationKey,
}),
);
await waitUntilObjectExists(
{ client },
{ Bucket: destinationBucket, Key: destinationKey },
);
console.log(
`Successfully copied ${sourceBucket}/${sourceKey} to ${destinationBucket}/${destinationKey}`,
);
} catch (caught) {
if (caught instanceof ObjectNotInActiveTierError) {
console.error(
`Could not copy ${sourceKey} from ${sourceBucket}. Object is not in the active tier.`,
);
} else {
throw caught;
}
}
};
// snippet-end:[s3.JavaScript.buckets.copyObjectV3]

// Invoke main function if this file was run directly.
// Call function if run directly
import { fileURLToPath } from "url";
import { parseArgs } from "util";

if (process.argv[1] === fileURLToPath(import.meta.url)) {
main();
const options = {
sourceBucket: {
type: "string",
default: "source-bucket",
},
sourceKey: {
type: "string",
default: "todo.txt",
},
destinationBucket: {
type: "string",
default: "destination-bucket",
},
destinationKey: {
type: "string",
default: "todo.txt",
},
};
const { values } = parseArgs({ options });
main(values);
}
66 changes: 50 additions & 16 deletions javascriptv3/example_code/s3/actions/create-bucket.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,64 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import { fileURLToPath } from "url";

// snippet-start:[s3.JavaScript.buckets.createBucketV3]
import { CreateBucketCommand, S3Client } from "@aws-sdk/client-s3";

const client = new S3Client({});
import {
BucketAlreadyExists,
BucketAlreadyOwnedByYou,
CreateBucketCommand,
S3Client,
waitUntilBucketExists,
} from "@aws-sdk/client-s3";

export const main = async () => {
const command = new CreateBucketCommand({
// The name of the bucket. Bucket names are unique and have several other constraints.
// See https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
Bucket: "bucket-name",
});
/**
* Create an Amazon S3 bucket.
* @param {{ bucketName: string }} config
*/
export const main = async ({ bucketName }) => {
const client = new S3Client({});

try {
const { Location } = await client.send(command);
const { Location } = await client.send(
new CreateBucketCommand({
// The name of the bucket. Bucket names are unique and have several other constraints.
// See https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
Bucket: bucketName,
}),
);
await waitUntilBucketExists({ client }, { Bucket: bucketName });
console.log(`Bucket created with location ${Location}`);
} catch (err) {
console.error(err);
} catch (caught) {
if (caught instanceof BucketAlreadyExists) {
console.error(
`The bucket "${bucketName}" already exists in another AWS account. Bucket names must be globally unique.`,
);
}
// WARNING: If you try to create a bucket in the North Virginia region,
// and you already own a bucket in that region with the same name, this
// error will not be thrown. Instead, the call will return successfully
// and the ACL on that bucket will be reset.
else if (caught instanceof BucketAlreadyOwnedByYou) {
console.error(
`The bucket "${bucketName}" already exists in this AWS account.`,
);
} else {
throw caught;
}
}
};
// snippet-end:[s3.JavaScript.buckets.createBucketV3]

// Invoke main function if this file was run directly.
// Call function if run directly
import { fileURLToPath } from "url";
import { parseArgs } from "util";

if (process.argv[1] === fileURLToPath(import.meta.url)) {
main();
const options = {
bucketName: {
type: "string",
default: "bucket-name",
},
};
const { values } = parseArgs({ options });
main(values);
}
60 changes: 44 additions & 16 deletions javascriptv3/example_code/s3/actions/delete-bucket-policy.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,57 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import { fileURLToPath } from "url";

// snippet-start:[s3.JavaScript.policy.deleteBucketPolicyV3]
import { DeleteBucketPolicyCommand, S3Client } from "@aws-sdk/client-s3";

const client = new S3Client({});
import {
DeleteBucketPolicyCommand,
S3Client,
S3ServiceException,
} from "@aws-sdk/client-s3";

// This will remove the policy from the bucket.
export const main = async () => {
const command = new DeleteBucketPolicyCommand({
Bucket: "test-bucket",
});
/**
* Remove the policy from an Amazon S3 bucket.
* @param {{ bucketName: string }}
*/
export const main = async ({ bucketName }) => {
const client = new S3Client({});

try {
const response = await client.send(command);
console.log(response);
} catch (err) {
console.error(err);
await client.send(
new DeleteBucketPolicyCommand({
Bucket: bucketName,
}),
);
console.log(`Bucket policy deleted from "${bucketName}".`);
} catch (caught) {
if (
caught instanceof S3ServiceException &&
caught.name === "NoSuchBucket"
) {
console.error(
`Error from S3 while deleting policy from ${bucketName}. The bucket doesn't exist.`,
);
} else if (caught instanceof S3ServiceException) {
console.error(
`Error from S3 while deleting policy from ${bucketName}. ${caught.name}: ${caught.message}`,
);
} else {
throw caught;
}
}
};
// snippet-end:[s3.JavaScript.policy.deleteBucketPolicyV3]

// Invoke main function if this file was run directly.
// Call function if run directly
import { fileURLToPath } from "url";
import { parseArgs } from "util";

if (process.argv[1] === fileURLToPath(import.meta.url)) {
main();
const options = {
bucketName: {
type: "string",
default: "amzn-s3-demo-bucket",
},
};
const { values } = parseArgs({ options });
main(values);
}
Loading

0 comments on commit c319089

Please sign in to comment.