/** * 持久化读取:从当前流程目录 save/config.json 按 key 读取(与 persist-save 成对,仅 string / number) */ const path = require('path') const fs = require('fs') /** 确保 save 目录存在;若无 config.json 则写入 {} */ function ensurePersistConfigFile (configPath) { const saveDir = path.dirname(configPath) try { if (!fs.existsSync(saveDir)) { fs.mkdirSync(saveDir, { recursive: true }) } if (!fs.existsSync(configPath)) { fs.writeFileSync(configPath, '{}\n', 'utf8') } } catch (e) { return { ok: false, error: `persist-read 无法创建 save/config: ${e.message || e}` } } return { ok: true } } function isAllowedPersistValue (val) { if (val === null || val === undefined) return { ok: false, error: 'persist-read 不支持 null / undefined' } if (typeof val === 'string' || typeof val === 'number') { if (typeof val === 'number' && !Number.isFinite(val)) { return { ok: false, error: 'persist-read 不支持 NaN / Infinity' } } return { ok: true } } if (typeof val === 'boolean') { return { ok: false, error: 'persist-read 仅支持读取 string 与 number,当前为 boolean' } } return { ok: false, error: 'persist-read 仅支持读取 string 与 number,不支持 object/array' } } async function executePersistRead ({ stateKey, folderPath }) { if (!folderPath || typeof folderPath !== 'string') { return { success: false, error: 'persist-read 缺少流程目录 folderPath' } } if (stateKey == null || String(stateKey).trim() === '') { return { success: false, error: 'persist-read 缺少 key(JSON 键名)' } } const key = String(stateKey).trim() const configPath = path.join(folderPath, 'save', 'config.json') const ensured = ensurePersistConfigFile(configPath) if (!ensured.ok) { return { success: false, error: ensured.error } } let data try { const raw = fs.readFileSync(configPath, 'utf8') data = JSON.parse(raw) } catch (e) { return { success: false, error: `persist-read 解析 config.json 失败: ${e.message || e}` } } if (!data || typeof data !== 'object' || Array.isArray(data)) { return { success: false, error: 'persist-read config.json 必须为 JSON 对象' } } if (!Object.prototype.hasOwnProperty.call(data, key)) { return { success: true, value: '', result: '' } } const val = data[key] const check = isAllowedPersistValue(val) if (!check.ok) { return { success: false, error: check.error } } return { success: true, value: val, result: val } } module.exports = { executePersistRead }