UNPKG

redai-automation-web-sdk

Version:

TypeScript SDK for RedAI Automation Web API - Zalo Personal automation, messaging, advanced sticker search, and bulk operations. 100% compatible with automation-web backend. v1.8.0: Added SessionProxyService for managing proxy assignments to sessions with

332 lines 9.98 kB
"use strict"; /** * HTTP utility functions for making API requests */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.HttpUtils = exports.HttpClient = exports.HttpError = void 0; const axios_1 = __importDefault(require("axios")); /** * Custom error class for HTTP requests */ class HttpError extends Error { constructor(message, status, code, response) { super(message); this.status = status; this.code = code; this.response = response; this.name = 'HttpError'; } } exports.HttpError = HttpError; /** * HTTP client class for making requests to automation-web API */ class HttpClient { constructor(config) { this.config = config; this.axiosInstance = this.createAxiosInstance(); } /** * Create axios instance with default configuration */ createAxiosInstance() { const instance = axios_1.default.create({ baseURL: this.config.baseUrl, timeout: this.config.timeout || 30000, headers: { 'Content-Type': 'application/json', 'User-Agent': this.config.userAgent || '@redai/automation-web-sdk/1.0.0', ...(this.config.apiKey && { Authorization: `Bearer ${this.config.apiKey}` }), }, }); // Request interceptor instance.interceptors.request.use((config) => { if (this.config.logging) { console.log(`[HTTP] ${config.method?.toUpperCase()} ${config.url}`, { params: config.params, data: config.data, }); } return config; }, (error) => { if (this.config.logging) { console.error('[HTTP] Request error:', error); } return Promise.reject(error); }); // Response interceptor instance.interceptors.response.use((response) => { if (this.config.logging) { console.log(`[HTTP] ${response.status} ${response.config.url}`, { data: response.data, }); } return response; }, (error) => { if (this.config.logging) { console.error('[HTTP] Response error:', error.response?.data || error.message); } return Promise.reject(this.handleError(error)); }); return instance; } /** * Handle axios errors and convert to HttpError */ handleError(error) { if (error.response) { // Server responded with error status const response = error.response.data; return new HttpError(response.error || response.message || 'Request failed', error.response.status, response.code?.toString(), response); } else if (error.request) { // Request was made but no response received return new HttpError('Network error - no response received', 0, 'NETWORK_ERROR'); } else { // Something else happened return new HttpError(error.message || 'Unknown error occurred', 0, 'UNKNOWN_ERROR'); } } /** * Make HTTP request with retry logic */ async makeRequestWithRetry(requestConfig, retryCount = 0) { try { return await this.axiosInstance.request(requestConfig); } catch (error) { const maxRetries = this.config.retryCount || 3; const retryDelay = this.config.retryDelay || 1000; if (retryCount < maxRetries && this.shouldRetry(error)) { if (this.config.logging) { console.log(`[HTTP] Retrying request (${retryCount + 1}/${maxRetries}) after ${retryDelay}ms`); } await this.delay(retryDelay * Math.pow(2, retryCount)); // Exponential backoff return this.makeRequestWithRetry(requestConfig, retryCount + 1); } throw error; } } /** * Determine if request should be retried */ shouldRetry(error) { // Retry on network errors or 5xx server errors return (error.code === 'NETWORK_ERROR' || (error.status !== undefined && error.status >= 500) || error.status === 429 // Rate limit ); } /** * Delay utility for retry logic */ delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } /** * Generic request method */ async request(options) { const requestConfig = { method: options.method, url: options.url, data: options.data, params: options.params, headers: options.headers, timeout: options.timeout || this.config.timeout, }; const response = await this.makeRequestWithRetry(requestConfig); // Handle automation-web response format const responseData = response.data; // Check for error in response if (responseData.error) { throw new HttpError(responseData.error, responseData.code || response.status, responseData.code?.toString(), responseData); } // Return the whole AutomationWebResponse structure // Let the service methods handle extracting result if needed return responseData; } /** * GET request */ async get(url, params, headers) { return this.request({ method: 'GET', url, params, headers, }); } /** * POST request */ async post(url, data, headers) { return this.request({ method: 'POST', url, data, headers, }); } /** * PUT request */ async put(url, data, headers) { return this.request({ method: 'PUT', url, data, headers, }); } /** * DELETE request */ async delete(url, params, headers) { return this.request({ method: 'DELETE', url, params, headers, }); } /** * PATCH request */ async patch(url, data, headers) { return this.request({ method: 'PATCH', url, data, headers, }); } /** * Update configuration */ updateConfig(newConfig) { this.config = { ...this.config, ...newConfig }; this.axiosInstance = this.createAxiosInstance(); } /** * Get current configuration */ getConfig() { return { ...this.config }; } } exports.HttpClient = HttpClient; /** * Utility functions for HTTP operations */ class HttpUtils { /** * Build query string from parameters */ static buildQueryString(params) { const searchParams = new URLSearchParams(); Object.entries(params).forEach(([key, value]) => { if (value !== undefined && value !== null) { if (Array.isArray(value)) { value.forEach(item => searchParams.append(key, String(item))); } else { searchParams.append(key, String(value)); } } }); return searchParams.toString(); } /** * Parse response headers */ static parseHeaders(headers) { const parsed = {}; Object.entries(headers).forEach(([key, value]) => { parsed[key.toLowerCase()] = value; }); return parsed; } /** * Check if URL is absolute */ static isAbsoluteUrl(url) { return /^https?:\/\//.test(url); } /** * Join URL paths */ static joinPaths(...paths) { return paths .map(path => path.replace(/^\/+|\/+$/g, '')) .filter(path => path.length > 0) .join('/'); } /** * Validate URL format */ static isValidUrl(url) { try { new URL(url); return true; } catch { return false; } } /** * Extract domain from URL */ static extractDomain(url) { try { const urlObj = new URL(url); return urlObj.hostname; } catch { return null; } } /** * Format file size in human readable format */ static formatFileSize(bytes) { const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; if (bytes === 0) return '0 Bytes'; const i = Math.floor(Math.log(bytes) / Math.log(1024)); return Math.round((bytes / Math.pow(1024, i)) * 100) / 100 + ' ' + sizes[i]; } /** * Get MIME type from file extension */ static getMimeType(filename) { const ext = filename.split('.').pop()?.toLowerCase(); const mimeTypes = { jpg: 'image/jpeg', jpeg: 'image/jpeg', png: 'image/png', gif: 'image/gif', webp: 'image/webp', mp4: 'video/mp4', avi: 'video/avi', mov: 'video/quicktime', mp3: 'audio/mpeg', wav: 'audio/wav', pdf: 'application/pdf', doc: 'application/msword', docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', txt: 'text/plain', json: 'application/json', xml: 'application/xml', zip: 'application/zip', rar: 'application/x-rar-compressed', }; return mimeTypes[ext || ''] || 'application/octet-stream'; } } exports.HttpUtils = HttpUtils; //# sourceMappingURL=http.utils.js.map