/** * Sleep helper function * @param {number} ms * @returns {Promise} */ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); /** * Parses product name to extract amount and unit from parentheses at the end of the name. * Handles patterns like (75 g), (1200 ml), (6x 200 ml), (5 x 75 g), (90 Yaprak), etc. * * @param {string} fullName * @returns {{cleanName: string, amountRaw: string|null, amount: number|null, unit: string|null}} */ function parseName(fullName) { if (!fullName) { return { cleanName: '', amountRaw: null, amount: null, unit: null }; } // Look for text inside parentheses at the end of the name const match = fullName.match(/\(([^)]+)\)\s*$/); if (!match) { return { cleanName: fullName.trim(), amountRaw: null, amount: null, unit: null }; } const parenContent = match[1].trim(); // e.g., "75 g" or "6x 200 ml" or "90 Yaprak" const cleanName = fullName.replace(/\(([^)]+)\)\s*$/, '').trim(); // Regex to capture numeric part + multiplier expressions (digits, spaces, x, *, ,, ., -) // followed by the alphabetic unit part (e.g. g, ml, L, adet, Yaprak) const amountUnitMatch = parenContent.match(/^([\d\s.x*X,-]+)\s*([a-zA-ZçıöşğüÇİÖŞĞÜ]+.*)$/); if (amountUnitMatch) { const amountRaw = amountUnitMatch[1].trim(); const unit = amountUnitMatch[2].trim(); let amount = null; try { // Clean up multiplier characters (convert x, X to *, replace Turkish decimal comma with dot) const evalString = amountRaw.toLowerCase().replace(/x/g, '*').replace(/,/g, '.'); // Ensure only numbers, math operations, and spaces exist in the evaluation string to prevent arbitrary code execution if (/^[0-9\s.*+-]+$/.test(evalString)) { // Safe evaluation amount = Function(`"use strict"; return (${evalString})`)(); } else { amount = parseFloat(amountRaw.replace(/,/g, '.')); } } catch (e) { // Fallback amount = parseFloat(amountRaw.replace(/,/g, '.')); } return { cleanName, amountRaw, amount: (amount && !isNaN(amount)) ? amount : null, unit }; } // Fallback if structure is different return { cleanName, amountRaw: parenContent, amount: null, unit: null }; } module.exports = { sleep, parseName };