/** * 语句:set 设置变量 + 变量与值解析(原 value-resolver:extractVarName、replaceVariablesInString、resolveValue、parseValue、时间/延迟) */ const types = ['set'] function extractVarName(varName) { if (typeof varName === 'string' && varName.startsWith('{') && varName.endsWith('}')) { return varName.slice(1, -1) } return varName } function replaceVariablesInString(str, context) { if (typeof str !== 'string') return str const doubleBracePattern = /\{\{([\w-]+)\}\}/g return str.replace(doubleBracePattern, (match, varName) => { const varValue = context[varName] if (varValue === undefined || varValue === null || varValue === '') return '' if (varValue === 'undefined' || varValue === 'null') return '' if (typeof varValue === 'string') { try { const parsed = JSON.parse(varValue) if (Array.isArray(parsed)) return parsed.length === 0 ? '' : varValue } catch (e) {} } if (Array.isArray(varValue) || (typeof varValue === 'object' && varValue !== null)) { try { return JSON.stringify(varValue) } catch (e) { return String(varValue) } } return String(varValue) }) } function resolveValue(value, context) { if (typeof value === 'string' && value.startsWith('{') && value.endsWith('}')) { const varName = value.slice(1, -1) return context[varName] !== undefined ? context[varName] : value } if (Array.isArray(value)) { return value.map(item => resolveValue(item, context)) } if (typeof value === 'object' && value !== null) { const resolved = {} for (const key in value) { resolved[key] = resolveValue(value[key], context) } return resolved } return value } function parseTimeString(timeStr) { if (!timeStr || typeof timeStr !== 'string' || timeStr.trim() === '') return null try { const parts = timeStr.trim().split(' ') if (parts.length !== 2) return null const datePart = parts[0].split('/') const timePart = parts[1].split(':') if (datePart.length !== 3 || timePart.length !== 2) return null const date = new Date( parseInt(datePart[0], 10), parseInt(datePart[1], 10) - 1, parseInt(datePart[2], 10), parseInt(timePart[0], 10), parseInt(timePart[1], 10), 0, 0 ) return isNaN(date.getTime()) ? null : date } catch (e) { return null } } function parseDelayString(delayStr) { if (!delayStr || typeof delayStr !== 'string' || delayStr.trim() === '') return 0 try { const trimmed = delayStr.trim() const unit = trimmed.slice(-1).toLowerCase() const value = parseInt(trimmed.slice(0, -1), 10) if (isNaN(value) || value < 0) return null switch (unit) { case 's': return value * 1000 case 'm': return value * 60 * 1000 case 'h': return value * 60 * 60 * 1000 default: return null } } catch (e) { return null } } function calculateWaitTime(data, delay) { return 0 } function parseValue(str) { if (typeof str !== 'string') return str str = str.trim() if (str === 'true') return true if (str === 'false') return false if ((str.startsWith('"') && str.endsWith('"')) || (str.startsWith("'") && str.endsWith("'"))) { return str.slice(1, -1).replace(/\\"/g, '"').replace(/\\'/g, "'") } if (/^-?\d+(\.\d+)?$/.test(str)) return parseFloat(str) if (str === 'undefined') return undefined return str } function parse(action, parseContext) { const variableContext = parseContext.variableContext || {} const parsed = { type: 'set', variable: action.variable, value: resolveValue(action.value, variableContext), } return Object.assign({}, action, parsed) } async function execute(action, ctx) { const { variableContext, evaluateExpression } = ctx if (!action.variable) return { success: true } const varName = extractVarName(action.variable) let finalValue = action.value if (typeof action.value === 'string' && /[+\-*/]/.test(action.value)) { finalValue = evaluateExpression(action.value, variableContext) } else if (typeof action.value === 'string') { const varPattern = /\{([\w-]+)\}/g let hasVariables = false finalValue = action.value.replace(varPattern, (match, vn) => { hasVariables = true const val = variableContext[vn] return val === undefined || val === null ? match : String(val) }) if (!hasVariables) finalValue = resolveValue(action.value, variableContext) } else { finalValue = resolveValue(action.value, variableContext) } variableContext[varName] = finalValue return { success: true } } module.exports = { types, parse, execute, extractVarName, replaceVariablesInString, resolveValue, parseTimeString, parseDelayString, calculateWaitTime, parseValue, }