UNPKG

@bramato/openrouter-mock-generator

Version:

AI-powered mock data generator using OpenRouter API with JSON mode support

164 lines 6.63 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AWSS3Storage = void 0; const crypto_1 = require("crypto"); class AWSS3Storage { constructor(config) { this.config = config; } async uploadImage(imageData, filename, contentType = 'image/png') { const buffer = typeof imageData === 'string' ? Buffer.from(imageData, 'base64') : imageData; const key = this.generateImageKey(filename); try { const url = await this.uploadToS3(buffer, key, contentType); return { url, key, }; } catch (error) { console.error('Failed to upload image to S3:', error); throw new Error(`S3 upload failed: ${error}`); } } async uploadMultipleImages(images) { const results = []; for (const image of images) { try { const result = await this.uploadImage(image.data, image.filename, image.contentType); results.push(result); } catch (error) { console.error(`Failed to upload ${image.filename}:`, error); // Continue with other images even if one fails results.push({ url: '', key: '', etag: `ERROR: ${error}`, }); } } return results; } generateImageKey(filename) { const timestamp = new Date().toISOString().slice(0, 10); const hash = (0, crypto_1.createHash)('md5') .update(filename + Date.now()) .digest('hex') .slice(0, 8); const extension = filename.split('.').pop() || 'png'; return `generated-images/${timestamp}/${hash}.${extension}`; } async uploadToS3(buffer, key, contentType) { const endpoint = this.config.endpoint || `https://s3.${this.config.region}.amazonaws.com`; const url = `${endpoint}/${this.config.bucketName}/${key}`; const date = new Date().toISOString().slice(0, 10).replace(/-/g, ''); const timestamp = new Date().toISOString().replace(/[:-]|\.\d{3}/g, ''); const headers = { 'Content-Type': contentType, 'Content-Length': buffer.length.toString(), 'x-amz-acl': 'public-read', 'x-amz-content-sha256': this.sha256(buffer), 'x-amz-date': timestamp, Host: `${this.config.bucketName}.s3.${this.config.region}.amazonaws.com`, }; const authorization = this.generateAuthHeader('PUT', key, headers, timestamp, date); const response = await fetch(url, { method: 'PUT', headers: { ...headers, Authorization: authorization, }, body: buffer, }); if (!response.ok) { const errorText = await response.text(); throw new Error(`S3 upload failed: ${response.status} ${response.statusText}\n${errorText}`); } // Return public URL return `https://${this.config.bucketName}.s3.${this.config.region}.amazonaws.com/${key}`; } generateAuthHeader(method, key, headers, timestamp, date) { const region = this.config.region; const service = 's3'; // Create canonical request const canonicalHeaders = Object.entries(headers) .map(([k, v]) => `${k.toLowerCase()}:${v}`) .sort() .join('\n'); const signedHeaders = Object.keys(headers) .map(k => k.toLowerCase()) .sort() .join(';'); const canonicalRequest = [ method, `/${key}`, '', canonicalHeaders, '', signedHeaders, headers['x-amz-content-sha256'], ].join('\n'); // Create string to sign const credentialScope = `${date}/${region}/${service}/aws4_request`; const stringToSign = [ 'AWS4-HMAC-SHA256', timestamp, credentialScope, this.sha256(canonicalRequest), ].join('\n'); // Calculate signature const signature = this.calculateSignature(stringToSign, date, region, service); // Return authorization header return `AWS4-HMAC-SHA256 Credential=${this.config.accessKeyId}/${credentialScope}, SignedHeaders=${signedHeaders}, Signature=${signature}`; } calculateSignature(stringToSign, date, region, service) { const kDate = this.hmacSha256(`AWS4${this.config.secretAccessKey}`, date); const kRegion = this.hmacSha256(kDate, region); const kService = this.hmacSha256(kRegion, service); const kSigning = this.hmacSha256(kService, 'aws4_request'); return this.hmacSha256(kSigning, stringToSign).toString('hex'); } hmacSha256(key, data) { const crypto = require('crypto'); return crypto.createHmac('sha256', key).update(data).digest(); } sha256(data) { return (0, crypto_1.createHash)('sha256').update(data).digest('hex'); } async testConnection() { try { // Test with a small dummy upload const testBuffer = Buffer.from('test', 'utf8'); const testKey = `test-connection-${Date.now()}.txt`; await this.uploadToS3(testBuffer, testKey, 'text/plain'); // Cleanup test file (optional) await this.deleteObject(testKey); return true; } catch (error) { console.error('S3 connection test failed:', error); return false; } } async deleteObject(key) { const endpoint = this.config.endpoint || `https://s3.${this.config.region}.amazonaws.com`; const url = `${endpoint}/${this.config.bucketName}/${key}`; const timestamp = new Date().toISOString().replace(/[:-]|\.\d{3}/g, ''); const date = new Date().toISOString().slice(0, 10).replace(/-/g, ''); const headers = { 'x-amz-date': timestamp, Host: `${this.config.bucketName}.s3.${this.config.region}.amazonaws.com`, }; const authorization = this.generateAuthHeader('DELETE', key, { ...headers, 'x-amz-content-sha256': this.sha256('') }, timestamp, date); await fetch(url, { method: 'DELETE', headers: { ...headers, Authorization: authorization, }, }); } } exports.AWSS3Storage = AWSS3Storage; //# sourceMappingURL=aws-s3-storage.js.map