UNPKG

stepwright

Version:

A powerful web scraping library built with Playwright

156 lines 5.25 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.replaceIndexPlaceholders = replaceIndexPlaceholders; exports.replaceDataPlaceholders = replaceDataPlaceholders; exports.locatorFor = locatorFor; exports.cloneStepWithIndex = cloneStepWithIndex; exports.flattenNestedForeachResults = flattenNestedForeachResults; // ---------------------------- // Internal helpers // ---------------------------- /** * Replace index placeholders in a string. * * @param {string} text - The text to replace placeholders in. * @param {number} i - The index to replace placeholders with. * * @since v1.0.0 * @author Muhammad Umer Farooq <umer@lablnet.com> * * @returns {string} - The text with placeholders replaced. * @since v1.0.0 * @company Framework Island */ function replaceIndexPlaceholders(text, i, char = 'i') { if (!text) return text; const regex = new RegExp(`\\{\\{\\s*${char}\\s*\\}\\}`, 'g'); const plus1Regex = new RegExp(`\\{\\{\\s*${char}_plus1\\s*\\}\\}`, 'g'); return text.replace(regex, i.toString()).replace(plus1Regex, (i + 1).toString()); } /** * Replace data placeholders like {{key}} with values from collector. * * @param {string} text - The text to replace placeholders in. * @param {object} collector - The collector object. * * @since v1.0.0 * @author Muhammad Umer Farooq <umer@lablnet.com> * * @returns {string} - The text with placeholders replaced. * @since v1.0.0 * @company Framework Island */ function replaceDataPlaceholders(text, collector) { if (!text) return text; let result = text; // Replace any {{key}} placeholders with values from collector const placeholderRegex = /\{\{\s*([^}]+)\s*\}\}/g; result = result.replace(placeholderRegex, (match, key) => { const value = collector[key]; if (value !== undefined && value !== null) { // Clean the value for filename use (remove special chars, trim whitespace) return String(value).trim().replace(/[^a-zA-Z0-9\s\-_]/g, '').replace(/\s+/g, '_'); } return match; // Keep original if not found }); return result; } /** * Get the locator for the given selector. * * @param {object} page - The page object. * @param {string} type - The type of selector. * @param {string} selector - The selector. * * @since v1.0.0 * @author Muhammad Umer Farooq <umer@lablnet.com> * * @returns {object} - The locator. * @since v1.0.0 * @company Framework Island */ function locatorFor(page, type, selector) { if (!type) return page.locator(selector); switch (type) { case 'id': return page.locator(`#${selector}`); case 'class': return page.locator(`.${selector}`); case 'tag': return page.locator(selector); case 'xpath': return page.locator(`xpath=${selector}`); default: return page.locator(selector); } } /** * Clone a step and apply index placeholders recursively. * * @param {object} step - The step object. * @param {number} idx - The index to replace placeholders with. * * @since v1.0.0 * @author Muhammad Umer Farooq <umer@lablnet.com> * * @returns {object} - The cloned step. * @since v1.0.0 * @company Framework Island */ function cloneStepWithIndex(step, idx, char = 'i') { const cloned = { ...step }; cloned.object = replaceIndexPlaceholders(cloned.object, idx, char); cloned.value = replaceIndexPlaceholders(cloned.value, idx, char); cloned.key = replaceIndexPlaceholders(cloned.key, idx, char); if (cloned.subSteps && cloned.subSteps.length > 0) { cloned.subSteps = cloned.subSteps.map((sub) => cloneStepWithIndex(sub, idx, char)); } return cloned; } /** * Flatten nested foreach results into an array. * * @param {object} item - Dictionary that may contain nested item_* keys. * * @since v1.0.0 * @author Muhammad Umer Farooq <umer@lablnet.com> * * @returns {any} - Either a flattened array of items or the original item. * @since v1.0.0 * @company Framework Island */ function flattenNestedForeachResults(item) { // Extract context keys (keys NOT starting with item_) const context = {}; Object.keys(item).forEach(k => { if (!k.startsWith('item_')) { context[k] = item[k]; } }); // Check if item contains nested item_* keys (from nested foreach) const nestedItemKeys = Object.keys(item).filter(k => k.startsWith('item_')); if (nestedItemKeys.length > 0) { // Flatten nested items into an array const flattenedItems = []; const sortedKeys = nestedItemKeys.sort((a, b) => { const aIdx = parseInt(a.split('_')[1]); const bIdx = parseInt(b.split('_')[1]); return aIdx - bIdx; }); for (const k of sortedKeys) { if (item[k] && Object.keys(item[k]).length > 0) { // Merge context into the nested item flattenedItems.push({ ...context, ...item[k] }); } } return flattenedItems; } else { // No nested items, return item with context (already in item) return item; } } //# sourceMappingURL=utils.js.map