1439 if (page.length < 500) break; 1440 } 1441 return rows; 1442} 1443 1444function unwrapInvocation(value) { 1445 let body = value; 1446 for (let index = 0; index < 6 && body != null; index += 1) { 1447 if (typeof body === "string") { try { body = JSON.parse(body); } catch { return body; } continue; } 1448 if (typeof body === "object" && body.response !== undefined) { body = body.response; continue; } 1449 if (typeof body === "object" && body.body !== undefined) { body = body.body; continue; } 1450 break; 1451 } 1452 return body; 1453} 1454 1455function requireCentre(args) { 1456 const centreId = clean(args?.centre_id); 1457 if (!centreId) throw new Error("centre_id est requis."); 1458 return centreId; 1459} 1460 1461function requireDate(value, label) { 1462 const text = clean(value); 1463 if (!/^\d{4}-\d{2}-\d{2}$/.test(text) || Number.isNaN(new Date(`${text}T00:00:00Z`).getTime())) { 1464 throw new Error(`${label} doit être une date AAAA-MM-JJ valide.`); 1465 } 1466 return text; 1467} 1468 1469function todayISO() { return new Date().toISOString().slice(0, 10); } 1470function dateOnly(value) { const text = clean(value); return /^\d{4}-\d{2}-\d{2}/.test(text) ? text.slice(0, 10) : ""; } 1471function effectiveToday(rule) { 1472 const today = todayISO(); 1473 const starts = dateOnly(rule.starts_at); 1474 const ends = dateOnly(rule.ends_at); 1475 return (!starts || starts <= today) && (!ends || ends >= today); 1476} 1477function activeRow(row) { return row?.active !== false && row?.active !== 0 && clean(row?.active).toLowerCase() !== "false" && clean(row?.active) !== "0"; } 1478function truthy(value) { return value === true || value === 1 || clean(value).toLowerCase() === "true" || clean(value) === "1"; } 1479function jsonObject(value) { 1480 let parsed = value; 1481 for (let index = 0; index < 2 && typeof parsed === "string"; index += 1) { try { parsed = JSON.parse(parsed); } catch { return {}; } } 1482 return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {}; 1483} 1484function values(input) { return Array.isArray(input) ? input.map(clean).filter(Boolean) : []; } 1485function jsonArray(value) { 1486 let parsed = value; 1487 for (let index = 0; index < 2 && typeof parsed === "string"; index += 1) { try { parsed = JSON.parse(parsed); } catch { return []; } } 1488 return Array.isArray(parsed) ? parsed.map(clean).filter(Boolean) : []; 1489} 1490function clean(value) { return String(value ?? "").trim(); } 1491function response(statusCode, body) { return { statusCode, headers: { "Content-Type": "application/json" }, body }; } 1492function rpcResult(id, result) { return { jsonrpc: "2.0", id, result }; } 1493function rpcError(id, code, message) { return { jsonrpc: "2.0", id, error: { code, message } }; } 1494function toolResult(payload) { return { content: [{ type: "text", text: JSON.stringify(payload) }] }; } 1495function toolError(message) { return { content: [{ type: "text", text: JSON.stringify({ error: message }) }], isError: true }; } 1496 1497export const __testHooks = { normalizeFormula, evaluateFormula, unwrapInvocation, effectiveToday, requireInvocationSuccess, slugify, requireLocalId, generatePassword, normalizeMembers, forwardableActor }; 1498