const axios = require("axios"); const { createObjectCsvWriter } = require("csv-writer"); const moment = require("moment"); const fs = require("fs"); const https = require("https"); const CONFIG = { API_URL: "https://dropship.ecomzone.eu/api/catalog", API_KEY: "klRyAdrXaxL0s6PEUp7LDlH6T8aPSCtBY8NiEHsHiWpc6646K2TZPi5KMxUg", MAX_RETRIES: 3, RETRY_DELAY: 10000, OUTPUT_DIR: "./output", LOG_DIR: "./logs", }; function ensureDirectories() { if (!fs.existsSync(CONFIG.OUTPUT_DIR)) { fs.mkdirSync(CONFIG.OUTPUT_DIR); } if (!fs.existsSync(CONFIG.LOG_DIR)) { fs.mkdirSync(CONFIG.LOG_DIR); } } function getCsvWriter() { const timestamp = moment().format("YYYY-MM-DD-HH-mm-ss"); return createObjectCsvWriter({ path: `${CONFIG.OUTPUT_DIR}/products_${timestamp}.csv`, header: [ { id: "sku", title: "SKU" }, { id: "products_id", title: "Product IDs" }, { id: "has_variations", title: "Has Variations" }, { id: "image", title: "Image URL" }, { id: "description", title: "Description" }, { id: "long_description", title: "Long Description" }, { id: "product_name", title: "Product Name" }, { id: "product_price", title: "Price" }, { id: "currency", title: "Currency" }, { id: "stock", title: "Stock" }, { id: "updated_at", title: "Updated At" }, ], }); } function transformData(data) { return data.map((item) => ({ ...item, products_id: Array.isArray(item.products_id) ? item.products_id.join(", ") : item.products_id, has_variations: item.has_variations ? "Yes" : "No", long_description: item.long_description?.replace(/\n/g, " ").trim() || "", description: item.description?.replace(/\n/g, " ").trim() || "", })); } const axiosInstance = axios.create({ timeout: 30000, // 30 seconds timeout httpsAgent: new https.Agent({ rejectUnauthorized: false, // Only use this in development keepAlive: true, keepAliveMsecs: 1000, maxSockets: 10, }), maxContentLength: Infinity, maxBodyLength: Infinity, }); async function saveToCSV(data) { try { const csvWriter = getCsvWriter(); await csvWriter.writeRecords(data); logger.log("Data successfully written to CSV"); } catch (error) { logger.error(`Error writing to CSV: ${error.message}`); throw error; } } async function fetchDataFromAPI() { let retries = 0; while (retries < CONFIG.MAX_RETRIES) { try { logger.log(`Attempting API call (${retries + 1}/${CONFIG.MAX_RETRIES})`); const response = await axiosInstance({ method: "get", url: CONFIG.API_URL, headers: { Accept: "application/json", "Content-Type": "application/json", Authorization: `Bearer ${CONFIG.API_KEY}`, }, params: { perpage: 1000, }, }); if (response.data && response.data.data) { logger.log("Data successfully retrieved from API"); return response.data.data; } throw new Error("Invalid data structure received from API"); } catch (error) { logger.error( `API call failed (attempt ${retries + 1}): ${error.message}`, ); if (error.response) { logger.error(`Status: ${error.response.status}`); logger.error(`Response data: ${JSON.stringify(error.response.data)}`); } retries++; if (retries < CONFIG.MAX_RETRIES) { logger.log( `Waiting ${CONFIG.RETRY_DELAY / 1000} seconds before retry...`, ); await delay(CONFIG.RETRY_DELAY); } } } throw new Error("Max retries exceeded"); } const logger = { log: (message) => { const timestamp = moment().format("YYYY-MM-DD HH:mm:ss"); const logMessage = `${timestamp} - ${message}\n`; console.log(message); fs.appendFileSync(`${CONFIG.LOG_DIR}/app.log`, logMessage); }, error: (message) => { const timestamp = moment().format("YYYY-MM-DD HH:mm:ss"); const logMessage = `${timestamp} - ERROR: ${message}\n`; console.error(message); fs.appendFileSync(`${CONFIG.LOG_DIR}/error.log`, logMessage); }, }; // Add data validation function function validateData(data) { if (!Array.isArray(data)) { return []; } return data.filter((item) => { return ( item && typeof item.sku === "string" && item.products_id && typeof item.product_name === "string" && typeof item.product_price !== "undefined" && typeof item.stock !== "undefined" ); }); } async function main() { try { ensureDirectories(); logger.log("Starting data extraction process"); const rawData = await fetchDataFromAPI(); if (rawData) { const validatedData = validateData(rawData); logger.log(`Found ${validatedData.length} valid records`); if (validatedData.length > 0) { const transformedData = transformData(validatedData); await saveToCSV(transformedData); logger.log( `Successfully saved ${transformedData.length} records to CSV`, ); logger.log("Process completed successfully"); } else { logger.log("No valid data to save"); } } else { logger.log("No data received from API"); } } catch (error) { logger.error(`Process failed: ${error.message}`); process.exit(1); } } // Fix the delay function name (it was "dalay") const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); // Fix the loggerConfig function function loggerConfig() { const logFile = `${CONFIG.LOG_DIR}/log-${moment().format("YYYY-MM-DD")}.log`; const logStream = fs.createWriteStream(logFile, { flags: "a" }); console.log = (message) => { logStream.write(`[${moment().format("YYYY-MM-DD HH:mm:ss")}] ${message}\n`); }; } main();