Vercel/src/services/blob/aws-s3.ts
2023-11-28 17:53:02 -06:00

90 lines
2.4 KiB
TypeScript

import { generateNanoid } from '@/utility/nanoid';
import {
S3Client,
CopyObjectCommand,
DeleteObjectCommand,
ListObjectsCommand,
PutObjectCommand,
} from '@aws-sdk/client-s3';
const S3_BUCKET = process.env.NEXT_PUBLIC_S3_BUCKET ?? '';
const S3_REGION = process.env.NEXT_PUBLIC_S3_REGION ?? '';
const S3_UPLOAD_ACCESS_KEY =
process.env.NEXT_PUBLIC_S3_UPLOAD_ACCESS_KEY ?? '';
const S3_UPLOAD_SECRET_ACCESS_KEY =
process.env.NEXT_PUBLIC_S3_UPLOAD_SECRET_ACCESS_KEY ?? '';
const S3_ADMIN_ACCESS_KEY =
process.env.S3_ADMIN_ACCESS_KEY;
const S3_ADMIN_SECRET_ACCESS_KEY =
process.env.S3_ADMIN_SECRET_ACCESS_KEY;
const client = () => new S3Client({
region: S3_REGION,
credentials: {
// Fall back on upload credentials when admin credentials aren't available
accessKeyId: S3_ADMIN_ACCESS_KEY ?? S3_UPLOAD_ACCESS_KEY,
secretAccessKey: S3_ADMIN_SECRET_ACCESS_KEY ?? S3_UPLOAD_SECRET_ACCESS_KEY,
},
});
export const AWS_S3_BASE_URL =
`https://${S3_BUCKET}.s3.${S3_REGION}.amazonaws.com`;
export const isUrlFromAwsS3 = (url: string) =>
url.startsWith(AWS_S3_BASE_URL);
const urlForKey = (key?: string) => `${AWS_S3_BASE_URL}/${key}`;
const generateBlobId = () => generateNanoid(16);
export const awsS3UploadFromClient = async (
file: File | Blob,
fileName: string,
extension: string,
addRandomSuffix?: boolean,
) => {
const Key = addRandomSuffix
? `${fileName}-${generateBlobId()}.${extension}`
: `${fileName}.${extension}`;
return client().send(new PutObjectCommand({
Bucket: S3_BUCKET,
Key,
Body: file,
ACL: 'public-read',
}))
.then(() => urlForKey(Key));
};
export const awsS3Copy = async (
fileNameSource: string,
fileNameDestination: string,
addRandomSuffix?: boolean,
) => {
const name = fileNameSource.split('.')[0];
const extension = fileNameSource.split('.')[1];
const Key = addRandomSuffix
? `${name}-${generateBlobId()}.${extension}`
: fileNameDestination;
return client().send(new CopyObjectCommand({
Bucket: S3_BUCKET,
CopySource: fileNameSource,
Key,
ACL: 'public-read',
}))
.then(() => urlForKey(fileNameDestination));
};
export const awsS3Delete = async (Key: string) => {
client().send(new DeleteObjectCommand({
Bucket: S3_BUCKET,
Key,
}));
};
export const awsS3List = async (Prefix: string) =>
client().send(new ListObjectsCommand({
Bucket: S3_BUCKET,
Prefix,
}))
.then((data) => data.Contents?.map(({ Key }) => urlForKey(Key)) ?? []);