chore: refine stage 7 json validation
This commit is contained in:
+66
@@ -0,0 +1,66 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { chat } from './llm.js';
|
||||
|
||||
function stripCodeFence(text) {
|
||||
return String(text)
|
||||
.trim()
|
||||
.replace(/^```[a-zA-Z0-9_-]*\n?/, '')
|
||||
.replace(/```$/, '')
|
||||
.trim();
|
||||
}
|
||||
|
||||
async function repairJSONArrayWithAI(fullPath, label, rawText) {
|
||||
const systemPrompt = `你是 JSON 修復器。請修正使用者提供的內容,使其成為可直接 JSON.parse 的 JSON 陣列。
|
||||
只回傳修正後的 JSON 陣列內容,不要使用 markdown code fence,不要加任何解釋。
|
||||
如果原內容不是陣列,也請盡量修成合理的 JSON 陣列;若無法判斷,回傳 []。`;
|
||||
const userContent = `檔案: ${label}\n原始內容:\n${rawText}`;
|
||||
const repaired = await chat(systemPrompt, userContent);
|
||||
return stripCodeFence(repaired);
|
||||
}
|
||||
|
||||
/**
|
||||
* 驗證 JSON 陣列檔案是否存在且格式正確。
|
||||
* 若格式錯誤,直接嘗試透過 AI 修復,修復後再次檢查;
|
||||
* 第二次檢查仍失敗才丟出例外。
|
||||
* 若檔案不存在,回傳 exists=false,交由呼叫端決定是否補檔。
|
||||
*/
|
||||
export async function validateJSONArrayFile(fullPath, label, repairer = repairJSONArrayWithAI) {
|
||||
fs.mkdirSync(path.dirname(fullPath), { recursive: true });
|
||||
|
||||
if (!fs.existsSync(fullPath)) {
|
||||
console.log(` ⚠️ ${label} 不存在,將於驗證後補建`);
|
||||
return { exists: false, valid: false, repaired: false };
|
||||
}
|
||||
|
||||
try {
|
||||
JSON.parse(fs.readFileSync(fullPath, 'utf8'));
|
||||
console.log(` ✅ ${label} JSON 格式正確`);
|
||||
return { exists: true, valid: true, repaired: false };
|
||||
} catch (e) {
|
||||
console.error(` ❌ ${label} JSON 格式錯誤: ${e.message},嘗試透過 AI 修正...`);
|
||||
try {
|
||||
const original = fs.readFileSync(fullPath, 'utf8');
|
||||
const repaired = await repairer(fullPath, label, original);
|
||||
fs.writeFileSync(fullPath, repaired.endsWith('\n') ? repaired : `${repaired}\n`, 'utf8');
|
||||
JSON.parse(fs.readFileSync(fullPath, 'utf8'));
|
||||
console.log(` ✅ ${label} 已由 AI 修正並通過再次驗證`);
|
||||
return { exists: true, valid: true, repaired: true };
|
||||
} catch (repairErr) {
|
||||
console.error(` ❌ ${label} 修正失敗: ${repairErr.message}`);
|
||||
throw repairErr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 若檔案不存在則建立空陣列。
|
||||
*/
|
||||
export function ensureJSONArrayFileExists(fullPath, label) {
|
||||
fs.mkdirSync(path.dirname(fullPath), { recursive: true });
|
||||
if (fs.existsSync(fullPath)) return false;
|
||||
|
||||
fs.writeFileSync(fullPath, '[]\n', 'utf8');
|
||||
console.log(` ⚠️ ${label} 不存在,已建立空陣列`);
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user