Skip to content

Instantly share code, notes, and snippets.

@d0ruk
Last active March 9, 2020 16:34
Show Gist options
  • Save d0ruk/9add9673019163e91ad19b2cbaef5df8 to your computer and use it in GitHub Desktop.
Save d0ruk/9add9673019163e91ad19b2cbaef5df8 to your computer and use it in GitHub Desktop.
AWS host static folder
const fs = require("fs");
const path = require("path");
const Promise = require("bluebird");
const readdir = require("recursive-readdir");
const { bgRed, bgGreen, bgBlue, bold, white } = require("chalk");
const PKG = require("./package.json");
const AWS = require("aws-sdk");
const s3 = new AWS.S3();
const bucketName = `${PKG.name}-v${PKG.version}`;
const PUBLIC = path.resolve(__dirname, "public");
const POLICY = {
"Version": "2012-10-17",
"Statement": [{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": ["s3:GetObject"],
"Resource":[`arn:aws:s3:::${bucketName}/*`]
}]
}
const readFile = path => (Promise.promisify(fs.readFile))(path),
createBucket = Bucket => s3.createBucket({Bucket}).promise(),
listBucket = Bucket => s3.listObjects({Bucket}).promise(),
deleteBucket = Bucket => s3.deleteBucket({Bucket}).promise(),
deleteObject = (Bucket, Key) => s3.deleteObject({Bucket, Key}).promise(),
headBucket = Bucket => s3.headBucket({Bucket}).promise(),
putBucketPolicy = (Bucket, Policy) => {
return s3.putBucketPolicy({ Bucket, Policy }).promise();
},
putBucketWebsite = Bucket => {
console.log(bgGreen.bold(`Configuring ${Bucket} for static website`));
return s3.putBucketWebsite({
Bucket,
WebsiteConfiguration: {
ErrorDocument: {
Key: "error.html"
},
IndexDocument: {
Suffix: "index.html"
}
}
}).promise();
},
putFile = async (Bucket, filePath) => {
const Key = filePath.replace(PUBLIC + path.sep, "");
const contents = await readFile(filePath);
console.log(bgBlue.white(`Putting file ${Key}`));
return s3.putObject({
Bucket,
Key,
Body: contents
}).promise();
};
async function bucketExists(name) {
try {
await headBucket(name);
return true;
} catch(e) {
return false;
}
}
async function getBucket(name) {
if (await bucketExists(name)) {
try {
console.log(bgBlue.white.bold(`Attempting to delete bucket ${name}`));
await deleteBucket(name);
} catch(e) {
await emptyBucket(name);
await deleteBucket(name);
}
}
console.log(bgBlue.white.bold(`Creating bucket ${name}`));
return createBucket(name)
.then(() => putBucketPolicy(name, JSON.stringify(POLICY)));
}
async function emptyBucket(name) {
console.log(bgBlue.white.bold(`Emptying bucket ${name}`));
const { Contents } = await listBucket(name);
return Promise.map(Contents, ({ Key }) => deleteObject(name, Key));
}
getBucket(bucketName)
.then(() => readdir(PUBLIC))
.then(files => Promise.map(files, putFile.bind(null, bucketName)))
.then(() => putBucketWebsite(bucketName))
.then(console.log)
.catch(console.error)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment