Skip to main content
Glama
storage-upload.ts4.36 kB
import type { PutObjectCommandInput } from '@aws-sdk/client-s3'; import { ListBucketsCommand, PutObjectCommand, S3Client, } from '@aws-sdk/client-s3'; import { NodeHttpHandler } from '@aws-sdk/node-http-handler'; import { env } from '../../env'; import { getImageBufferFromUrl, readFileToBuffer } from '../utils/image'; import { getUploadFileOriginEndpointUrl, getUploadFilePublicUrl, guessMimeTypeByBuffer, } from './helper'; import type { CloudStorageProvider, StorageUploadOptions } from './types'; import type { ICloudStorage } from './types'; export function getCurrentStorage(): ICloudStorage { if ( !env.CLOUDFLARE_CDN_ACCESS_KEY || !env.CLOUDFLARE_CDN_SECRET_KEY || !env.CLOUDFLARE_CDN_BUCKET_NAME || !env.CLOUDFLARE_CDN_ENDPOINT_URL || !env.CLOUDFLARE_CDN_BASE_URL || !env.CLOUDFLARE_CDN_PROJECT_NAME ) { throw new Error( 'Cloudflare CDN access key or secret key is not defined', ); } return { provider: 'cloudflare', region: 'auto', bucket: env.CLOUDFLARE_CDN_BUCKET_NAME, accessKey: env.CLOUDFLARE_CDN_ACCESS_KEY, secretKey: env.CLOUDFLARE_CDN_SECRET_KEY, endpoint: env.CLOUDFLARE_CDN_ENDPOINT_URL, baseUrl: env.CLOUDFLARE_CDN_BASE_URL, basePath: `/${env.CLOUDFLARE_CDN_PROJECT_NAME}`, }; } export async function initStorage(storage: ICloudStorage) { const s3 = new S3Client({ region: storage.region, endpoint: storage.endpoint || `https://${storage.accessKey}.r2.cloudflarestorage.com`, credentials: { accessKeyId: storage.accessKey, secretAccessKey: storage.secretKey, }, forcePathStyle: true, retryMode: 'standard', maxAttempts: 5, requestHandler: new NodeHttpHandler({ connectionTimeout: 10000, socketTimeout: 10000, }), }); return s3; } export async function listBuckets(storage: ICloudStorage) { const s3 = await initStorage(storage); const response = await s3.send(new ListBucketsCommand({})); return response.Buckets; } export async function uploadFileBuffer( buffer: Buffer, destFileName: string, options?: StorageUploadOptions, ): Promise<{ path: string; storageUrl: string; publicUrl: string; provider: CloudStorageProvider; }> { const { storage = getCurrentStorage() } = options || {}; if (!storage) throw new Error('Storage is not defined'); if (destFileName.startsWith('/')) destFileName = destFileName.slice(1); const path = destFileName.replace(/[^a-zA-Z0-9-_.]/g, ''); if (options?.debug) console.log('uploadFileBuffer :>>', { storage }); const s3 = await initStorage(storage); const mimeType = guessMimeTypeByBuffer(buffer) || 'application/octet-stream'; if (options?.debug) console.log('uploadFileBuffer :>>', { mimeType }); if (options?.debug) console.log('uploadFileBuffer :>>', { path }); const uploadParams: PutObjectCommandInput = { Bucket: storage.bucket, Key: `${env.CLOUDFLARE_CDN_PROJECT_NAME}/${path}`, Body: buffer, ContentType: mimeType, CacheControl: 'max-age=31536000, s-maxage=31536000', }; if (options?.debug) console.log('uploadFileBuffer :>>', { uploadParams }); try { const data = await s3.send(new PutObjectCommand(uploadParams)); if (options?.debug) console.log('uploadFileBuffer :>>', { data }); const response = { provider: storage.provider, path, storageUrl: getUploadFileOriginEndpointUrl(storage, destFileName), publicUrl: getUploadFilePublicUrl(storage, destFileName), }; if (options?.debug) console.log('uploadFileBuffer :>>', { response }); return response; } catch (error) { if (error instanceof Error) { console.error('Upload error:', error.message); if ('code' in error) { console.error('Error code:', (error as any).code); } } throw error; } } export async function uploadFileURL( url: string, destFileName: string, options?: StorageUploadOptions, ) { const buffer = await getImageBufferFromUrl(url); if (options?.debug) console.log('uploadFileURL :>>', { buffer }); if (!buffer) throw new Error(`Unable to get image buffer from "${url}"`); return uploadFileBuffer(buffer, destFileName, options); } export async function uploadFilePath( filePath: string, destFileName: string, options?: StorageUploadOptions, ) { const buffer = readFileToBuffer(filePath); if (!buffer) throw new Error(`Unable to get image buffer from "${filePath}"`); return uploadFileBuffer(buffer, destFileName, options); }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mrgoonie/reviewwebsite-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server