Skip to content

Commit

Permalink
s3 is OPTIONAL not required
Browse files Browse the repository at this point in the history
  • Loading branch information
gv authored and gv committed Nov 24, 2024
1 parent 2bf3faf commit 9fb0ac4
Showing 1 changed file with 72 additions and 25 deletions.
97 changes: 72 additions & 25 deletions src/utils/aws-s3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,88 @@ import {
PutObjectCommand,
PutObjectCommandInput,
S3Client,
S3ServiceException,
} from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
import { config } from "../config";
import { optimizeImage } from "./images";

export const s3Client = new S3Client({
region: config.s3.region,
credentials: {
accessKeyId: config.s3.accessKeyId,
secretAccessKey: config.s3.secretAccessKey,
},
});
// Helper to check if S3 configuration is complete
function isS3Configured(): boolean {
return !!(
config.s3?.region &&
config.s3?.accessKeyId &&
config.s3?.secretAccessKey &&
config.s3?.bucketName
);
}

// Initialize S3 client only if properly configured
export const s3Client: S3Client | null = isS3Configured()
? new S3Client({
region: config.s3.region,
credentials: {
accessKeyId: config.s3.accessKeyId,
secretAccessKey: config.s3.secretAccessKey,
},
})
: null;

export async function uploadImageToS3(filename: string, file: Express.Multer.File) {
const optimizedImage = await optimizeImage(file.buffer);
const params: PutObjectCommandInput = {
Key: filename,
Body: optimizedImage,
ContentType: file.mimetype,
Bucket: config.s3.bucketName,
};
const command = new PutObjectCommand(params);
return s3Client.send(command);
export async function uploadImageToS3(
filename: string,
file: Express.Multer.File
): Promise<void> {
// If S3 is not configured, return early
if (!s3Client || !isS3Configured()) {
console.warn('S3 is not configured. Skipping upload.');
return;
}

try {
const optimizedImage = await optimizeImage(file.buffer);
const params: PutObjectCommandInput = {
Key: filename,
Body: optimizedImage,
ContentType: file.mimetype,
Bucket: config.s3.bucketName,
};
const command = new PutObjectCommand(params);
await s3Client.send(command);
} catch (error) {
console.error('Error uploading to S3:', error);
if (error instanceof S3ServiceException) {
throw new Error(`Failed to upload image to S3: ${error.message}`);
}
throw new Error('Failed to upload image to S3');
}
}

export function getS3SignedUrl(filename: string): Promise<string> {
const params: GetObjectCommandInput = {
Key: filename,
Bucket: config.s3.bucketName,
};
const command = new GetObjectCommand(params);
return getSignedUrl(s3Client, command, { expiresIn: 3600 });
export async function getS3SignedUrl(filename: string): Promise<string | null> {
// If S3 is not configured, return null
if (!s3Client || !isS3Configured()) {
console.warn('S3 is not configured. Cannot generate signed URL.');
return null;
}

try {
const params: GetObjectCommandInput = {
Key: filename,
Bucket: config.s3.bucketName,
};
const command = new GetObjectCommand(params);
return await getSignedUrl(s3Client, command, { expiresIn: 3600 });
} catch (error) {
console.error('Error generating signed URL:', error);
if (error instanceof S3ServiceException) {
throw new Error(`Failed to generate signed URL: ${error.message}`);
}
throw new Error('Failed to generate signed URL');
}
}

export async function getS3SignedUrlIfExisted(filename?: string | null): Promise<string | null> {
export async function getS3SignedUrlIfExisted(
filename?: string | null
): Promise<string | null> {
if (!filename) return null;
return getS3SignedUrl(filename);
}

0 comments on commit 9fb0ac4

Please sign in to comment.