better-auth/packages/storage/provider/s3/index.ts
 Илья Шалонин 8538ab969a first
2025-10-29 13:43:43 +05:00

89 lines
1.8 KiB
TypeScript

import {
GetObjectCommand,
PutObjectCommand,
S3Client,
} from "@aws-sdk/client-s3";
import { getSignedUrl as getS3SignedUrl } from "@aws-sdk/s3-request-presigner";
import { logger } from "@repo/logs";
import type {
GetSignedUploadUrlHandler,
GetSignedUrlHander,
} from "../../types";
let s3Client: S3Client | null = null;
const getS3Client = () => {
if (s3Client) {
return s3Client;
}
const s3Endpoint = process.env.S3_ENDPOINT as string;
if (!s3Endpoint) {
throw new Error("Missing env variable S3_ENDPOINT");
}
const s3Region = (process.env.S3_REGION as string) || "auto";
const s3AccessKeyId = process.env.S3_ACCESS_KEY_ID as string;
if (!s3AccessKeyId) {
throw new Error("Missing env variable S3_ACCESS_KEY_ID");
}
const s3SecretAccessKey = process.env.S3_SECRET_ACCESS_KEY as string;
if (!s3SecretAccessKey) {
throw new Error("Missing env variable S3_SECRET_ACCESS_KEY");
}
s3Client = new S3Client({
region: s3Region,
endpoint: s3Endpoint,
forcePathStyle: true,
credentials: {
accessKeyId: s3AccessKeyId,
secretAccessKey: s3SecretAccessKey,
},
});
return s3Client;
};
export const getSignedUploadUrl: GetSignedUploadUrlHandler = async (
path,
{ bucket },
) => {
const s3Client = getS3Client();
try {
return await getS3SignedUrl(
s3Client,
new PutObjectCommand({
Bucket: bucket,
Key: path,
ContentType: "image/jpeg",
}),
{
expiresIn: 60,
},
);
} catch (e) {
logger.error(e);
throw new Error("Could not get signed upload url");
}
};
export const getSignedUrl: GetSignedUrlHander = async (
path,
{ bucket, expiresIn },
) => {
const s3Client = getS3Client();
try {
return getS3SignedUrl(
s3Client,
new GetObjectCommand({ Bucket: bucket, Key: path }),
{ expiresIn },
);
} catch (e) {
logger.error(e);
throw new Error("Could not get signed url");
}
};