sideshift-node-sdk
Version:
TypeScript Client for SideShift.ai API
168 lines (167 loc) • 6.12 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SideShiftHttpHandler = void 0;
const axios_1 = __importDefault(require("axios"));
class SideShiftHttpHandler {
constructor(config) {
this.rateMap = {
shift: { count: 0, windowStart: Date.now() },
quote: { count: 0, windowStart: Date.now() },
default: { count: 0, windowStart: Date.now() },
};
this.config = config;
this.axiosInstance = axios_1.default.create({
baseURL: config.baseUrl,
timeout: 10000,
headers: {
'Content-Type': 'application/json',
},
});
}
async execute(method, endpoint, params, options = {}) {
try {
this.checkRateLimit(options.category);
const headers = this.buildHeaders(options.auth, options.userIp);
if (options.affiliateId) {
if (!this.config.affiliateId) {
throw new Error('Affiliate ID is required but not provided in the configuration.');
}
if (!params) {
params = {};
}
params.affiliateId = this.config.affiliateId;
}
const requestConfig = { headers };
let response;
if (method === 'POST') {
const postData = options.data || {};
if (params && params.affiliateId) {
postData.affiliateId = params.affiliateId;
delete params.affiliateId;
}
requestConfig.params = params;
response = await this.axiosInstance.post(endpoint, postData, requestConfig);
}
else {
requestConfig.params = params;
response = await this.axiosInstance.get(endpoint, requestConfig);
}
if (this.config.verbose) {
console.log('=== [Debug] HTTP Response ===');
console.log(`${method} ${endpoint}:`, {
status: response.status,
data: response.data,
});
console.log('=========================');
}
return {
success: true,
data: response.data,
status: response.status,
};
}
catch (error) {
return this.handleError(error, method, endpoint);
}
}
handleError(error, method, endpoint) {
let status;
let message = `${method} ${endpoint} failed`;
if (axios_1.default.isAxiosError(error)) {
status = error.response?.status;
if (error.response) {
const statusText = error.response.statusText;
const code = error.response.status;
const data = error.response.data;
let details = '';
if (typeof data === 'string') {
details = data;
}
else if (data?.error?.message) {
details = data.error.message;
}
else {
try {
details = JSON.stringify(data);
}
catch {
details = String(data);
}
}
message = `${method} ${endpoint} failed: ${code} ${statusText} - ${details}`;
}
else if (error.request) {
message = `${method} ${endpoint} failed: No response received`;
}
else {
message = `${method} ${endpoint} failed: ${error.message}`;
}
}
else {
message = `${method} ${endpoint} failed: ${error?.message || 'Unknown error'}`;
}
if (this.config.verbose) {
console.log('=== [Debug] HTTP Error ===');
console.error('Error:', message);
console.log('==========================');
}
return {
success: false,
data: null,
error: message,
status,
};
}
buildHeaders(auth = false, userIp) {
const headers = {};
if (auth) {
headers['x-sideshift-secret'] = this.config.privateKey;
}
if (userIp) {
headers['x-user-ip'] = userIp;
}
if (this.config.verbose) {
console.log('=== [Debug] HTTP Headers ===');
console.log('Request headers:', headers);
console.log('=========================');
}
return headers;
}
checkRateLimit(category) {
if (!category) {
category = 'default';
}
const now = Date.now();
const limits = this.config.maxRequest;
if (!this.rateMap) {
this.rateMap = {
shift: { count: 0, windowStart: now },
quote: { count: 0, windowStart: now },
default: { count: 0, windowStart: now },
};
}
const state = this.rateMap[category];
const windowMs = 60 * 1000;
if (now - state.windowStart >= windowMs) {
state.count = 0;
state.windowStart = now;
}
if (this.config.verbose) {
console.log('=== [Debug] Rate Limit Check ===');
console.log(`Rate limit for ${category}:`, {
count: state.count,
windowStart: new Date(state.windowStart).toISOString(),
limits: limits[category],
});
console.log('=========================');
}
state.count += 1;
if (state.count > limits[category]) {
throw new Error(`Rate limit exceeded for ${category} (max ${limits[category]} per minute)`);
}
}
}
exports.SideShiftHttpHandler = SideShiftHttpHandler;