Update variables v2 state handling
This commit is contained in:
@@ -21,6 +21,7 @@ import {
|
||||
const MODULE_ID = 'varCommands';
|
||||
const TAG_RE_XBGETVAR = /\{\{xbgetvar::([^}]+)\}\}/gi;
|
||||
const TAG_RE_XBGETVAR_YAML = /\{\{xbgetvar_yaml::([^}]+)\}\}/gi;
|
||||
const TAG_RE_XBGETVAR_YAML_IDX = /\{\{xbgetvar_yaml_idx::([^}]+)\}\}/gi;
|
||||
|
||||
let events = null;
|
||||
let initialized = false;
|
||||
@@ -183,6 +184,121 @@ export function replaceXbGetVarYamlInString(s) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 {{xbgetvar_yaml_idx::路径}} 替换为带索引注释的 YAML
|
||||
*/
|
||||
export function replaceXbGetVarYamlIdxInString(s) {
|
||||
s = String(s ?? '');
|
||||
if (!s || s.indexOf('{{xbgetvar_yaml_idx::') === -1) return s;
|
||||
|
||||
TAG_RE_XBGETVAR_YAML_IDX.lastIndex = 0;
|
||||
return s.replace(TAG_RE_XBGETVAR_YAML_IDX, (_, p) => {
|
||||
const value = lwbResolveVarPath(p);
|
||||
if (!value) return '';
|
||||
|
||||
try {
|
||||
const parsed = JSON.parse(value);
|
||||
if (typeof parsed === 'object' && parsed !== null) {
|
||||
return formatYamlWithIndex(parsed, 0).trim();
|
||||
}
|
||||
return value;
|
||||
} catch {
|
||||
return value;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function formatYamlWithIndex(obj, indent) {
|
||||
const pad = ' '.repeat(indent);
|
||||
|
||||
if (Array.isArray(obj)) {
|
||||
if (obj.length === 0) return `${pad}[]`;
|
||||
|
||||
const lines = [];
|
||||
obj.forEach((item, idx) => {
|
||||
if (item && typeof item === 'object' && !Array.isArray(item)) {
|
||||
const keys = Object.keys(item);
|
||||
if (keys.length === 0) {
|
||||
lines.push(`${pad}- {} # [${idx}]`);
|
||||
} else {
|
||||
const firstKey = keys[0];
|
||||
const firstVal = item[firstKey];
|
||||
const firstFormatted = formatValue(firstVal, indent + 2);
|
||||
|
||||
if (typeof firstVal === 'object' && firstVal !== null) {
|
||||
lines.push(`${pad}- ${firstKey}: # [${idx}]`);
|
||||
lines.push(firstFormatted);
|
||||
} else {
|
||||
lines.push(`${pad}- ${firstKey}: ${firstFormatted} # [${idx}]`);
|
||||
}
|
||||
|
||||
for (let i = 1; i < keys.length; i++) {
|
||||
const k = keys[i];
|
||||
const v = item[k];
|
||||
const vFormatted = formatValue(v, indent + 2);
|
||||
if (typeof v === 'object' && v !== null) {
|
||||
lines.push(`${pad} ${k}:`);
|
||||
lines.push(vFormatted);
|
||||
} else {
|
||||
lines.push(`${pad} ${k}: ${vFormatted}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (Array.isArray(item)) {
|
||||
lines.push(`${pad}- # [${idx}]`);
|
||||
lines.push(formatYamlWithIndex(item, indent + 1));
|
||||
} else {
|
||||
lines.push(`${pad}- ${formatScalar(item)} # [${idx}]`);
|
||||
}
|
||||
});
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
if (obj && typeof obj === 'object') {
|
||||
if (Object.keys(obj).length === 0) return `${pad}{}`;
|
||||
|
||||
const lines = [];
|
||||
for (const [key, val] of Object.entries(obj)) {
|
||||
const vFormatted = formatValue(val, indent + 1);
|
||||
if (typeof val === 'object' && val !== null) {
|
||||
lines.push(`${pad}${key}:`);
|
||||
lines.push(vFormatted);
|
||||
} else {
|
||||
lines.push(`${pad}${key}: ${vFormatted}`);
|
||||
}
|
||||
}
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
return `${pad}${formatScalar(obj)}`;
|
||||
}
|
||||
|
||||
function formatValue(val, indent) {
|
||||
if (Array.isArray(val)) return formatYamlWithIndex(val, indent);
|
||||
if (val && typeof val === 'object') return formatYamlWithIndex(val, indent);
|
||||
return formatScalar(val);
|
||||
}
|
||||
|
||||
function formatScalar(v) {
|
||||
if (v === null) return 'null';
|
||||
if (v === undefined) return '';
|
||||
if (typeof v === 'boolean') return String(v);
|
||||
if (typeof v === 'number') return String(v);
|
||||
if (typeof v === 'string') {
|
||||
const needsQuote =
|
||||
v === '' ||
|
||||
/^\s|\s$/.test(v) || // 首尾空格
|
||||
/[:[]\]{}&*!|>'"%@`#,]/.test(v) || // YAML 易歧义字符
|
||||
/^(?:true|false|null)$/i.test(v) || // YAML 关键字
|
||||
/^-?(?:\d+(?:\.\d+)?|\.\d+)$/.test(v); // 纯数字字符串
|
||||
if (needsQuote) {
|
||||
return `"${v.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
return String(v);
|
||||
}
|
||||
|
||||
export function replaceXbGetVarInChat(chat) {
|
||||
if (!Array.isArray(chat)) return;
|
||||
|
||||
@@ -194,10 +310,12 @@ export function replaceXbGetVarInChat(chat) {
|
||||
const old = String(msg[key] ?? '');
|
||||
const hasJson = old.indexOf('{{xbgetvar::') !== -1;
|
||||
const hasYaml = old.indexOf('{{xbgetvar_yaml::') !== -1;
|
||||
if (!hasJson && !hasYaml) continue;
|
||||
const hasYamlIdx = old.indexOf('{{xbgetvar_yaml_idx::') !== -1;
|
||||
if (!hasJson && !hasYaml && !hasYamlIdx) continue;
|
||||
|
||||
let result = hasJson ? replaceXbGetVarInString(old) : old;
|
||||
result = hasYaml ? replaceXbGetVarYamlInString(result) : result;
|
||||
result = hasYamlIdx ? replaceXbGetVarYamlIdxInString(result) : result;
|
||||
msg[key] = result;
|
||||
} catch {}
|
||||
}
|
||||
@@ -215,10 +333,12 @@ export function applyXbGetVarForMessage(messageId, writeback = true) {
|
||||
const old = String(msg[key] ?? '');
|
||||
const hasJson = old.indexOf('{{xbgetvar::') !== -1;
|
||||
const hasYaml = old.indexOf('{{xbgetvar_yaml::') !== -1;
|
||||
if (!hasJson && !hasYaml) return;
|
||||
const hasYamlIdx = old.indexOf('{{xbgetvar_yaml_idx::') !== -1;
|
||||
if (!hasJson && !hasYaml && !hasYamlIdx) return;
|
||||
|
||||
let out = hasJson ? replaceXbGetVarInString(old) : old;
|
||||
out = hasYaml ? replaceXbGetVarYamlInString(out) : out;
|
||||
out = hasYamlIdx ? replaceXbGetVarYamlIdxInString(out) : out;
|
||||
if (writeback && out !== old) {
|
||||
msg[key] = out;
|
||||
}
|
||||
@@ -1111,7 +1231,9 @@ export function cleanupVarCommands() {
|
||||
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按值从数组中删除元素(2.0 pop 操作)
|
||||
*/
|
||||
export {
|
||||
MODULE_ID,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user