/** * json 结点:将 JSON 字符串解析为数组(如 img-url-json -> img-url-arr) * 对应 process:type: "json", method: "json-to-arr", inVars: ["{img-url-json}"], outVars: ["{img-url-arr}"] * 或统一写法:type: "fun", method: "json-to-arr", inVars / outVars 可省略 */ /** * 将 JSON 字符串解析为数组并返回,供后续 for 等使用。 * @param {{ jsonString: string }} input - jsonString 为变量取值后的 JSON 字符串 * @returns {{ success: boolean, result?: any[], error?: string }} */ function normalizeAiJsonText(raw) { let s = typeof raw === 'string' ? raw.trim() : String(raw).trim() if (!s) return '' // 去掉行首行尾 markdown 围栏(含仅开头 ```json 的情况) s = s.replace(/^```(?:json)?\s*\r?\n?/i, '') s = s.replace(/\r?\n?```\s*$/i, '') s = s.trim() // 再取第一个 ```...``` 内层(模型有时前后还有说明文字) const inner = s.match(/```(?:json)?\s*([\s\S]*?)```/i) if (inner) s = inner[1].trim() // 弯引号、直角引号 → 标准双引号(避免 Unterminated string) s = s.replace(/[\u201c\u201d\u201e\u201f\u2033\u2036\u00ab\u00bb]/g, '"') s = s.replace(/[「」『』]/g, '"') // 截取从首个 [ 到最后一个 ],忽略模型输出的前后废话 const lb = s.indexOf('[') const rb = s.lastIndexOf(']') if (lb !== -1 && rb > lb) s = s.slice(lb, rb + 1) return s.trim() } async function executeJsonToArr({ jsonString }) { if (jsonString == null) return { success: false, error: 'json-to-arr 缺少输入(如 inVars[0])' } let str = normalizeAiJsonText(jsonString) if (!str) return { success: false, error: 'json-to-arr 输入为空' } let parsed let lastErr try { parsed = JSON.parse(str) } catch (e) { lastErr = e // AI 可能截断:尝试补全后再解析 if (str.startsWith('[')) { if (/^\[\s*"[^"]*$/.test(str)) { try { parsed = JSON.parse(str + '"]') } catch (_) {} } if (parsed == null && str.endsWith('"')) { try { parsed = JSON.parse(str + ']') } catch (_) {} } // 常见:只输出了一个带引号的串和逗号,第二个串未闭合 if (parsed == null && /^\[\s*"[^"]*",\s*"[^"]*$/.test(str)) { try { parsed = JSON.parse(str + '"]') } catch (_) {} } } if (parsed == null) { return { success: false, error: `JSON 解析失败: ${lastErr && lastErr.message ? lastErr.message : String(lastErr)}(原始前 120 字: ${String(jsonString).slice(0, 120).replace(/\s+/g, ' ')})`, } } } const arr = Array.isArray(parsed) ? parsed : (parsed != null ? [parsed] : []) return { success: true, result: arr } } module.exports = { executeJsonToArr }