@llumiverse/drivers
Version:
LLM driver implementations. Currently supported are: openai, huggingface, bedrock, replicate.
109 lines (93 loc) • 3.54 kB
text/typescript
import { CreateBucketCommand, HeadBucketCommand, S3Client } from "@aws-sdk/client-s3";
import { Progress, Upload } from "@aws-sdk/lib-storage";
export async function doesBucketExist(s3: S3Client, bucketName: string): Promise<boolean> {
try {
await s3.send(new HeadBucketCommand({ Bucket: bucketName }));
return true;
} catch (err: any) {
if (err.name === 'NotFound') {
return false;
}
throw err;
}
}
export function createBucket(s3: S3Client, bucketName: string) {
return s3.send(new CreateBucketCommand({
Bucket: bucketName
}));
}
export async function tryCreateBucket(s3: S3Client, bucketName: string) {
const exists = await doesBucketExist(s3, bucketName);
if (!exists) {
return createBucket(s3, bucketName);
}
}
export async function uploadFile(s3: S3Client, source: ReadableStream, bucketName: string, file: string, onProgress?: (progress: Progress) => void) {
const upload = new Upload({
client: s3,
params: {
Bucket: bucketName,
Key: file,
Body: source,
}
});
onProgress && upload.on("httpUploadProgress", onProgress);
const result = await upload.done();
return result;
}
/**
* Create the bucket if not already exists and then upload the file.
* @param s3
* @param source
* @param bucketName
* @param file
* @param onProgress
* @returns
*/
export async function forceUploadFile(s3: S3Client, source: ReadableStream, bucketName: string, file: string, onProgress?: (progress: Progress) => void) {
// make sure the bucket exists
await tryCreateBucket(s3, bucketName);
return uploadFile(s3, source, bucketName, file, onProgress);
}
/**
* Parse an S3 HTTPS URL into an S3 URI format
* s3Url - The S3 HTTPS URL (e.g., https://bucket.s3.region.amazonaws.com/key)
* returns The S3 URI (e.g., s3://bucket/key)
*/
export function parseS3UrlToUri(s3Url: URL) {
try {
const url = new URL(s3Url);
// Extract the hostname which contains the bucket and S3 endpoint
const hostname = url.hostname;
// Parse the hostname to extract the bucket name
let bucketName;
if (hostname.endsWith('.amazonaws.com')) {
if (hostname.includes('.s3.')) {
// Format: bucket-name.s3.region.amazonaws.com
bucketName = hostname.split('.s3.')[0];
} else if (hostname.startsWith('s3.')) {
// Format: s3.region.amazonaws.com/bucket-name
// In this case, the bucket is actually in the first segment of the pathname
bucketName = url.pathname.split('/')[1];
// Adjust the pathname to remove the bucket name
const pathParts = url.pathname.split('/').slice(2);
url.pathname = '/' + pathParts.join('/');
} else {
throw new Error('Unable to determine bucket name from URL');
}
} else {
throw new Error('Unable to determine bucket name from URL');
}
// The key is the pathname without the leading slash
// If we had the bucket name in the path, it's already been removed above
let key = url.pathname;
if (key.startsWith('/')) {
key = key.substring(1);
}
// Construct the S3 URI
return `s3://${bucketName}/${key}`;
} catch (error) {
console.error('Error parsing S3 URL:', error);
throw error;
}
}