set-parser.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /**
  2. * 语句:set 设置变量 + 变量与值解析(原 value-resolver:extractVarName、replaceVariablesInString、resolveValue、parseValue、时间/延迟)
  3. */
  4. const types = ['set']
  5. function extractVarName(varName) {
  6. if (typeof varName === 'string' && varName.startsWith('{') && varName.endsWith('}')) {
  7. return varName.slice(1, -1)
  8. }
  9. return varName
  10. }
  11. function replaceVariablesInString(str, context) {
  12. if (typeof str !== 'string') return str
  13. const doubleBracePattern = /\{\{([\w-]+)\}\}/g
  14. return str.replace(doubleBracePattern, (match, varName) => {
  15. const varValue = context[varName]
  16. if (varValue === undefined || varValue === null || varValue === '') return ''
  17. if (varValue === 'undefined' || varValue === 'null') return ''
  18. if (typeof varValue === 'string') {
  19. try {
  20. const parsed = JSON.parse(varValue)
  21. if (Array.isArray(parsed)) return parsed.length === 0 ? '' : varValue
  22. } catch (e) {}
  23. }
  24. if (Array.isArray(varValue) || (typeof varValue === 'object' && varValue !== null)) {
  25. try {
  26. return JSON.stringify(varValue)
  27. } catch (e) {
  28. return String(varValue)
  29. }
  30. }
  31. return String(varValue)
  32. })
  33. }
  34. function resolveValue(value, context) {
  35. if (typeof value === 'string' && value.startsWith('{') && value.endsWith('}')) {
  36. const varName = value.slice(1, -1)
  37. return context[varName] !== undefined ? context[varName] : value
  38. }
  39. if (Array.isArray(value)) {
  40. return value.map(item => resolveValue(item, context))
  41. }
  42. if (typeof value === 'object' && value !== null) {
  43. const resolved = {}
  44. for (const key in value) {
  45. resolved[key] = resolveValue(value[key], context)
  46. }
  47. return resolved
  48. }
  49. return value
  50. }
  51. function parseTimeString(timeStr) {
  52. if (!timeStr || typeof timeStr !== 'string' || timeStr.trim() === '') return null
  53. try {
  54. const parts = timeStr.trim().split(' ')
  55. if (parts.length !== 2) return null
  56. const datePart = parts[0].split('/')
  57. const timePart = parts[1].split(':')
  58. if (datePart.length !== 3 || timePart.length !== 2) return null
  59. const date = new Date(
  60. parseInt(datePart[0], 10),
  61. parseInt(datePart[1], 10) - 1,
  62. parseInt(datePart[2], 10),
  63. parseInt(timePart[0], 10),
  64. parseInt(timePart[1], 10),
  65. 0, 0
  66. )
  67. return isNaN(date.getTime()) ? null : date
  68. } catch (e) {
  69. return null
  70. }
  71. }
  72. function parseDelayString(delayStr) {
  73. if (!delayStr || typeof delayStr !== 'string' || delayStr.trim() === '') return 0
  74. try {
  75. const trimmed = delayStr.trim()
  76. const unit = trimmed.slice(-1).toLowerCase()
  77. const value = parseInt(trimmed.slice(0, -1), 10)
  78. if (isNaN(value) || value < 0) return null
  79. switch (unit) {
  80. case 's': return value * 1000
  81. case 'm': return value * 60 * 1000
  82. case 'h': return value * 60 * 60 * 1000
  83. default: return null
  84. }
  85. } catch (e) {
  86. return null
  87. }
  88. }
  89. function calculateWaitTime(data, delay) {
  90. return 0
  91. }
  92. function parseValue(str) {
  93. if (typeof str !== 'string') return str
  94. str = str.trim()
  95. if (str === 'true') return true
  96. if (str === 'false') return false
  97. if ((str.startsWith('"') && str.endsWith('"')) || (str.startsWith("'") && str.endsWith("'"))) {
  98. return str.slice(1, -1).replace(/\\"/g, '"').replace(/\\'/g, "'")
  99. }
  100. if (/^-?\d+(\.\d+)?$/.test(str)) return parseFloat(str)
  101. if (str === 'undefined') return undefined
  102. return str
  103. }
  104. function parse(action, parseContext) {
  105. const variableContext = parseContext.variableContext || {}
  106. const parsed = {
  107. type: 'set',
  108. variable: action.variable,
  109. value: resolveValue(action.value, variableContext),
  110. }
  111. return Object.assign({}, action, parsed)
  112. }
  113. async function execute(action, ctx) {
  114. const { variableContext, evaluateExpression } = ctx
  115. if (!action.variable) return { success: true }
  116. const varName = extractVarName(action.variable)
  117. let finalValue = action.value
  118. if (typeof action.value === 'string' && /[+\-*/]/.test(action.value)) {
  119. finalValue = evaluateExpression(action.value, variableContext)
  120. } else if (typeof action.value === 'string') {
  121. const varPattern = /\{([\w-]+)\}/g
  122. let hasVariables = false
  123. finalValue = action.value.replace(varPattern, (match, vn) => {
  124. hasVariables = true
  125. const val = variableContext[vn]
  126. return val === undefined || val === null ? match : String(val)
  127. })
  128. if (!hasVariables) finalValue = resolveValue(action.value, variableContext)
  129. } else {
  130. finalValue = resolveValue(action.value, variableContext)
  131. }
  132. variableContext[varName] = finalValue
  133. return { success: true }
  134. }
  135. module.exports = {
  136. types,
  137. parse,
  138. execute,
  139. extractVarName,
  140. replaceVariablesInString,
  141. resolveValue,
  142. parseTimeString,
  143. parseDelayString,
  144. calculateWaitTime,
  145. parseValue,
  146. }