dt-common-device
Version: 
A secure and robust device management library for IoT applications
134 lines (133 loc) • 5.1 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateServiceUrl = validateServiceUrl;
exports.createAxiosInstance = createAxiosInstance;
exports.getDeviceServiceAxiosInstance = getDeviceServiceAxiosInstance;
exports.getAdminServiceAxiosInstance = getAdminServiceAxiosInstance;
exports.getMonitoringServiceAxiosInstance = getMonitoringServiceAxiosInstance;
exports.retryRequest = retryRequest;
const config_1 = require("../config/config");
const axios_1 = __importDefault(require("axios"));
/**
 * Validates if a URL is properly formatted and accessible
 */
function validateServiceUrl(url) {
    try {
        const parsedUrl = new URL(url);
        return parsedUrl.protocol === "http:" || parsedUrl.protocol === "https:";
    }
    catch (error) {
        (0, config_1.getConfig)().LOGGER.error(`Invalid service URL: ${url}`, error);
        return false;
    }
}
/**
 * Creates a properly configured axios instance with error handling
 */
function createAxiosInstance(baseURL) {
    const instance = axios_1.default.create({
        baseURL,
        timeout: 60000, // 60 seconds timeout
        maxRedirects: 5,
        validateStatus: (status) => status < 400, // Only treat 2xx and 3xx as successful
        headers: {
            "Content-Type": "application/json",
            "User-Agent": `dt-common-device/${require("../../package.json").version}`,
            "x-api-key": (0, config_1.getDTApiKey)(),
        },
    });
    // Add request interceptor for logging
    instance.interceptors.request.use((config) => {
        const logger = (0, config_1.getConfig)().LOGGER;
        logger.info(`Making request to: ${config.method?.toUpperCase()} ${config.url}`, {
            baseURL: config.baseURL,
            timeout: config.timeout,
        });
        return config;
    }, (error) => {
        (0, config_1.getConfig)().LOGGER.error("Request interceptor error:", error);
        return Promise.reject(error instanceof Error ? error : new Error(String(error)));
    });
    // Add response interceptor for error handling
    instance.interceptors.response.use((response) => {
        return response;
    }, (error) => {
        const logger = (0, config_1.getConfig)().LOGGER;
        const errorInfo = {
            url: error.config?.url,
            method: error.config?.method,
            status: error.response?.status,
            statusText: error.response?.statusText,
            message: error.message,
            code: error.code,
            baseURL: error.config?.baseURL,
        };
        logger.error("HTTP request failed:", errorInfo);
        // Log additional details for network errors
        if (error.code === "ECONNREFUSED" || error.code === "ENOTFOUND") {
            logger.error("Network connectivity issue detected. Please check:", {
                serviceUrl: error.config?.baseURL,
                errorCode: error.code,
                errorMessage: error.message,
            });
        }
        return Promise.reject(error instanceof Error ? error : new Error(String(error)));
    });
    return instance;
}
/**
 * Centralized axios instance for device service
 */
let deviceServiceAxiosInstance = null;
function getDeviceServiceAxiosInstance() {
    if (!deviceServiceAxiosInstance) {
        deviceServiceAxiosInstance = createAxiosInstance((0, config_1.getDeviceServiceUrl)());
    }
    return deviceServiceAxiosInstance;
}
/**
 * Centralized axios instance for cloud service (smart-cloud)
 */
let cloudServiceAxiosInstance = null;
function getAdminServiceAxiosInstance() {
    if (!cloudServiceAxiosInstance) {
        cloudServiceAxiosInstance = createAxiosInstance((0, config_1.getAdminServiceUrl)());
    }
    return cloudServiceAxiosInstance;
}
let deviceMonitoringServiceAxiosInstance = null;
function getMonitoringServiceAxiosInstance() {
    if (!deviceMonitoringServiceAxiosInstance) {
        deviceMonitoringServiceAxiosInstance = createAxiosInstance((0, config_1.getMonitoringServiceUrl)());
    }
    return deviceMonitoringServiceAxiosInstance;
}
/**
 * Retry function for failed HTTP requests
 */
async function retryRequest(requestFn, maxRetries = 3, delay = 1000) {
    let lastError;
    for (let attempt = 1; attempt <= maxRetries; attempt++) {
        try {
            return await requestFn();
        }
        catch (error) {
            lastError = error;
            if (attempt === maxRetries) {
                (0, config_1.getConfig)().LOGGER.error(`Request failed after ${maxRetries} attempts:`, error);
                throw error;
            }
            (0, config_1.getConfig)().LOGGER.warn(`Request attempt ${attempt} failed, retrying in ${delay}ms:`, {
                error: error.message,
                attempt,
                maxRetries,
            });
            await new Promise((resolve) => setTimeout(resolve, delay));
            delay *= 2; // Exponential backoff
        }
    }
    throw lastError;
}