utilcn
libgenerate-presigned-upload-urlsource: ok · hit
Generate Presigned Upload URL
Generate a presigned upload URL for a file.
npx shadcn add "https://utilcn.dev/r/generate-presigned-upload-url.json"free
No selection tags yet — empty means no evidence, not lack of support.
Dependencies
Bundle weight · light@aws-sdk/client-s3@aws-sdk/s3-request-presigner
Files2 · source cached 10/14/2026, 2:55:30 PM
registry/default/storage/generate-presigned-upload-url.ts
import { PutObjectCommand } from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
import { getS3Client } from '@/registry/default/storage/s3-client';
const MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024; // 10MB
type PresignedUrlInput = {
fileName: string;
expiresIn?: number;
contentLength: number;
};
export async function generatePresignedUploadUrl({
fileName,
expiresIn = 3600,
contentLength,
}: PresignedUrlInput) {
if (contentLength > MAX_FILE_SIZE_BYTES) {
throw new Error('File size exceeds maximum allowed limit');
}
try {
const fileExt = fileName.split('.').pop()?.toLowerCase() ?? '';
const uniqueId = Date.now().toString();
const key = fileExt ? `${uniqueId}.${fileExt}` : uniqueId;
const contentType = getContentType(fileExt);
const command = new PutObjectCommand({
Bucket: process.env.S3_BUCKET_NAME,
Key: key,
ContentType: contentType,
ContentLength: contentLength,
});
const uploadUrl = await getSignedUrl(getS3Client(), command, { expiresIn });
const fileUrl = `${process.env.S3_PUBLIC_URL}/${key}`;
return { uploadUrl, key, fileUrl };
} catch (err) {
console.error({ err }, 'Failed to generate presigned upload URL');
throw new Error('Failed to generate upload URL');
}
}
function getContentType(extension: string): string {
switch (extension) {
// Images
case 'jpg':
case 'jpeg':
return 'image/jpeg';
case 'png':
return 'image/png';
case 'gif':
return 'image/gif';
case 'webp':
return 'image/webp';
case 'svg':
return 'image/svg+xml';
// Documents
case 'pdf':
return 'application/pdf';
case 'doc':
return 'application/msword';
case 'docx':
return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
// Other common types
case 'json':
return 'application/json';
case 'txt':
return 'text/plain';
default:
return 'application/octet-stream';
}
}
registry/default/storage/s3-client.ts
import { S3Client } from '@aws-sdk/client-s3';
let s3Client: S3Client | null = null;
export const getS3Client = (): S3Client => {
if (s3Client) {
return s3Client;
}
if (
!process.env.S3_REGION ||
!process.env.S3_ENDPOINT ||
!process.env.S3_ACCESS_KEY ||
!process.env.S3_SECRET_KEY
) {
throw new Error('Missing S3 environment variables');
}
s3Client = new S3Client({
region: process.env.S3_REGION,
endpoint: process.env.S3_ENDPOINT,
forcePathStyle: true, // Required for some S3-compatible services
credentials: {
accessKeyId: process.env.S3_ACCESS_KEY,
secretAccessKey: process.env.S3_SECRET_KEY,
},
});
return s3Client;
};