@bramato/openrouter-mock-generator
Version:
AI-powered mock data generator using OpenRouter API with JSON mode support
164 lines • 6.63 kB
JavaScript
;
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