Skip to content

Instantly share code, notes, and snippets.

@ksdme
Last active June 16, 2021 09:59
Show Gist options
  • Save ksdme/514f318eb1e15319b68e9c55c2aadae2 to your computer and use it in GitHub Desktop.
Save ksdme/514f318eb1e15319b68e9c55c2aadae2 to your computer and use it in GitHub Desktop.
Downloads a file from a given url resource and upload it to a specified S3 bucket. Default to picking a random name for the file and making it public-read. Inspired from https://github.com/bookyacom/tos3/blob/master/index.js
import assert from 'assert'
import AWS from 'aws-sdk'
const {
AWS_S3_ENDPOINT_URL,
AWS_ACCESS_KEY_ID,
AWS_SECRET_ACCESS_KEY,
} = process.env
assert(Boolean(AWS_S3_ENDPOINT_URL))
assert(Boolean(AWS_ACCESS_KEY_ID))
assert(Boolean(AWS_SECRET_ACCESS_KEY))
export default new AWS.S3({
endpoint: AWS_S3_ENDPOINT_URL,
accessKeyId: AWS_ACCESS_KEY_ID,
secretAccessKey: AWS_SECRET_ACCESS_KEY,
})
import fileType from 'file-type'
import got from 'got'
import path from 'path'
import { v4 } from 'uuid'
import s3 from './s3'
const {
AWS_IMAGES_BUCKET,
} = process.env
/*
Downloads a file from a given url resource and upload it to a
specified S3 bucket. Default to picking a random name for the
file and making it public-read.
*/
export const transfer = async (
url: string,
name?: string,
bucket?: string,
acl?: string,
) => {
// Set the defaults for the transfer.
name = name ?? v4()
acl = acl ?? 'public-read',
bucket = bucket ?? AWS_IMAGES_BUCKET
// Download the file.
const response = await got(url, {
responseType: 'buffer',
maxRedirects: 8,
timeout: 15000,
})
// Get the buffer response.
const chunk = response.body
// Get information about the file to change the name of the object,
// if applicable. If an extension could not be deduced, the file name
// will end with a period.
const type = await fileType.fromBuffer(chunk)
const ext = type?.ext ?? path.extname(url).replace('.', '') ?? ''
return new Promise((resolve, reject) => {
const configuration = {
Bucket: AWS_IMAGES_BUCKET!,
ACL: acl,
Body: chunk,
Key: `${name}.${ext}`,
ContentType: type?.mime,
}
// Upload the file with configuration and return the
// location of the file when complete.
s3.upload(configuration, (error: any, data: any) => {
if (error) {
return reject(error)
}
return resolve(data.Location)
})
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment