|
|
@@ -113,9 +113,67 @@ function resolveActionInputs(action, variableContext) {
|
|
|
return resolved
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * 从字符串或数组中提取所有变量引用名({var}、{{var}}、{arr}[{idx}] 中的 var/arr/idx)
|
|
|
+ * @returns {string[]} 变量名列表(可能重复)
|
|
|
+ */
|
|
|
+function extractVarNamesFromValue(val) {
|
|
|
+ const names = []
|
|
|
+ function collect(str) {
|
|
|
+ if (typeof str !== 'string') return
|
|
|
+ const doubleBrace = /\{\{([\w-]+)\}\}/g
|
|
|
+ const singleBrace = /\{([\w-]+)\}/g
|
|
|
+ let m
|
|
|
+ while ((m = doubleBrace.exec(str)) !== null) names.push(m[1])
|
|
|
+ while ((m = singleBrace.exec(str)) !== null) names.push(m[1])
|
|
|
+ }
|
|
|
+ if (typeof val === 'string') {
|
|
|
+ collect(val)
|
|
|
+ return names
|
|
|
+ }
|
|
|
+ if (Array.isArray(val)) {
|
|
|
+ val.forEach((v) => names.push(...extractVarNamesFromValue(v)))
|
|
|
+ return names
|
|
|
+ }
|
|
|
+ if (typeof val === 'object' && val !== null) {
|
|
|
+ Object.keys(val).forEach((k) => names.push(...extractVarNamesFromValue(val[k])))
|
|
|
+ return names
|
|
|
+ }
|
|
|
+ return names
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 校验 action 的 inVars/outVars 中引用的变量是否均在 declaredVariableNames 中声明
|
|
|
+ * @param {object} action - 当前 action(含 inVars、outVars)
|
|
|
+ * @param {Set|string[]} declaredVariableNames - 在 workflow.variables 中声明的变量名集合
|
|
|
+ * @returns {{ valid: boolean, undeclared: string[] }}
|
|
|
+ */
|
|
|
+function validateInOutVars(action, declaredVariableNames) {
|
|
|
+ const declared = declaredVariableNames instanceof Set ? declaredVariableNames : new Set(declaredVariableNames || [])
|
|
|
+ const undeclared = []
|
|
|
+ function check(names) {
|
|
|
+ names.forEach((n) => {
|
|
|
+ if (n && typeof n === 'string' && !declared.has(n)) undeclared.push(n)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ if (action.inVars && Array.isArray(action.inVars)) {
|
|
|
+ action.inVars.forEach((v) => check(extractVarNamesFromValue(v)))
|
|
|
+ }
|
|
|
+ if (action.outVars && Array.isArray(action.outVars)) {
|
|
|
+ action.outVars.forEach((v) => {
|
|
|
+ const name = typeof v === 'string' ? extractVarName(v) : v
|
|
|
+ if (name) check([name])
|
|
|
+ })
|
|
|
+ }
|
|
|
+ const unique = [...new Set(undeclared)]
|
|
|
+ return { valid: unique.length === 0, undeclared: unique }
|
|
|
+}
|
|
|
+
|
|
|
module.exports = {
|
|
|
resolveActionInputs,
|
|
|
resolveInputValue,
|
|
|
replaceArrayIndexInString,
|
|
|
extractVarName,
|
|
|
+ extractVarNamesFromValue,
|
|
|
+ validateInOutVars,
|
|
|
}
|