Merge commit 'd803bfe2b1fe7f5e219e50ac20d6801a0a58ac75' as 'vendor/ruvector'

This commit is contained in:
ruv
2026-02-28 14:39:40 -05:00
7854 changed files with 3522914 additions and 0 deletions

View File

@@ -0,0 +1,78 @@
/**
* API Client for external service integration
*/
export class APIClient {
constructor(options = {}) {
this.baseUrl = options.baseUrl || 'https://api.example.com';
this.apiKey = options.apiKey || '';
this.timeout = options.timeout || 5000;
this.retries = options.retries || 3;
}
/**
* Make API request
* @param {string} endpoint - API endpoint
* @param {Object} options - Request options
*/
async request(endpoint, options = {}) {
const url = `${this.baseUrl}${endpoint}`;
const headers = {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.apiKey}`,
...options.headers
};
let lastError;
for (let i = 0; i < this.retries; i++) {
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
const response = await fetch(url, {
...options,
headers,
signal: controller.signal
});
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error(`API error: ${response.status} ${response.statusText}`);
}
return await response.json();
} catch (error) {
lastError = error;
if (i < this.retries - 1) {
await this._delay(1000 * Math.pow(2, i));
}
}
}
throw lastError;
}
/**
* GET request
*/
async get(endpoint, params = {}) {
const queryString = new URLSearchParams(params).toString();
const url = queryString ? `${endpoint}?${queryString}` : endpoint;
return this.request(url, { method: 'GET' });
}
/**
* POST request
*/
async post(endpoint, data) {
return this.request(endpoint, {
method: 'POST',
body: JSON.stringify(data)
});
}
_delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}