mirror of
https://gitbruv.vercel.app/api/git/bruv/gitbruv.git
synced 2025-12-20 23:24:09 +01:00
98 lines
2.5 KiB
TypeScript
98 lines
2.5 KiB
TypeScript
import { S3Client, GetObjectCommand, PutObjectCommand, DeleteObjectCommand, ListObjectsV2Command, HeadObjectCommand } from "@aws-sdk/client-s3";
|
|
|
|
const R2_ACCOUNT_ID = process.env.R2_ACCOUNT_ID!;
|
|
const R2_ACCESS_KEY_ID = process.env.R2_ACCESS_KEY_ID!;
|
|
const R2_SECRET_ACCESS_KEY = process.env.R2_SECRET_ACCESS_KEY!;
|
|
export const R2_BUCKET_NAME = process.env.R2_BUCKET_NAME || "gitbruv-repos";
|
|
|
|
export const r2Client = new S3Client({
|
|
region: "auto",
|
|
endpoint: `https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com`,
|
|
credentials: {
|
|
accessKeyId: R2_ACCESS_KEY_ID,
|
|
secretAccessKey: R2_SECRET_ACCESS_KEY,
|
|
},
|
|
});
|
|
|
|
export async function r2Get(key: string): Promise<Buffer | null> {
|
|
try {
|
|
const response = await r2Client.send(
|
|
new GetObjectCommand({
|
|
Bucket: R2_BUCKET_NAME,
|
|
Key: key,
|
|
})
|
|
);
|
|
if (!response.Body) return null;
|
|
const bytes = await response.Body.transformToByteArray();
|
|
return Buffer.from(bytes);
|
|
} catch (err: unknown) {
|
|
if ((err as { name?: string })?.name === "NoSuchKey") return null;
|
|
throw err;
|
|
}
|
|
}
|
|
|
|
export async function r2Put(key: string, data: Buffer | Uint8Array | string): Promise<void> {
|
|
await r2Client.send(
|
|
new PutObjectCommand({
|
|
Bucket: R2_BUCKET_NAME,
|
|
Key: key,
|
|
Body: data instanceof Buffer ? data : Buffer.from(data),
|
|
})
|
|
);
|
|
}
|
|
|
|
export async function r2Delete(key: string): Promise<void> {
|
|
await r2Client.send(
|
|
new DeleteObjectCommand({
|
|
Bucket: R2_BUCKET_NAME,
|
|
Key: key,
|
|
})
|
|
);
|
|
}
|
|
|
|
export async function r2Exists(key: string): Promise<boolean> {
|
|
try {
|
|
await r2Client.send(
|
|
new HeadObjectCommand({
|
|
Bucket: R2_BUCKET_NAME,
|
|
Key: key,
|
|
})
|
|
);
|
|
return true;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
export async function r2List(prefix: string): Promise<string[]> {
|
|
const keys: string[] = [];
|
|
let continuationToken: string | undefined;
|
|
|
|
do {
|
|
const response = await r2Client.send(
|
|
new ListObjectsV2Command({
|
|
Bucket: R2_BUCKET_NAME,
|
|
Prefix: prefix,
|
|
ContinuationToken: continuationToken,
|
|
})
|
|
);
|
|
|
|
if (response.Contents) {
|
|
for (const obj of response.Contents) {
|
|
if (obj.Key) keys.push(obj.Key);
|
|
}
|
|
}
|
|
|
|
continuationToken = response.NextContinuationToken;
|
|
} while (continuationToken);
|
|
|
|
return keys;
|
|
}
|
|
|
|
export async function r2DeletePrefix(prefix: string): Promise<void> {
|
|
const keys = await r2List(prefix);
|
|
for (const key of keys) {
|
|
await r2Delete(key);
|
|
}
|
|
}
|
|
|