@absolutejs/voice 0.0.22-beta.433 → 0.0.22-beta.434
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/incidentTimeline.d.ts +1 -0
- package/dist/index.js +6 -2
- package/package.json +1 -1
|
@@ -104,6 +104,7 @@ export declare const renderVoiceIncidentTimelineMarkdown: (report: VoiceIncident
|
|
|
104
104
|
title?: string;
|
|
105
105
|
}) => string;
|
|
106
106
|
export declare const renderVoiceIncidentTimelineHTML: (report: VoiceIncidentTimelineReport, options?: {
|
|
107
|
+
actionPath?: string;
|
|
107
108
|
title?: string;
|
|
108
109
|
}) => string;
|
|
109
110
|
export declare const createVoiceIncidentTimelineRoutes: (options: VoiceIncidentTimelineRoutesOptions) => Elysia<"", {
|
package/dist/index.js
CHANGED
|
@@ -30406,6 +30406,7 @@ ${report.actions.map((action) => `- ${action.method ?? "GET"} ${action.id}: ${ac
|
|
|
30406
30406
|
};
|
|
30407
30407
|
var renderVoiceIncidentTimelineHTML = (report, options = {}) => {
|
|
30408
30408
|
const title = options.title ?? "AbsoluteJS Voice Incident Timeline";
|
|
30409
|
+
const actionPath = options.actionPath ?? "/api/voice/incident-timeline/actions";
|
|
30409
30410
|
const events = report.events.map((event) => `<article class="${escapeHtml43(event.severity)}">
|
|
30410
30411
|
<span>${escapeHtml43(event.severity.toUpperCase())} / ${escapeHtml43(event.category)}</span>
|
|
30411
30412
|
<h2>${escapeHtml43(event.label)}</h2>
|
|
@@ -30421,7 +30422,7 @@ var renderVoiceIncidentTimelineHTML = (report, options = {}) => {
|
|
|
30421
30422
|
const control = action.method === "POST" ? `<button type="button" data-voice-incident-action="${escapeHtml43(action.id)}" ${action.disabled ? "disabled" : ""}>${label}</button>` : href;
|
|
30422
30423
|
return `<article class="action"><span>${escapeHtml43(action.method ?? "GET")}</span><h2>${label}</h2>${detail}<div>${control}${href && action.method === "POST" ? href : ""}</div></article>`;
|
|
30423
30424
|
}).join("");
|
|
30424
|
-
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml43(title)}</title><style>body{background:#11110d;color:#faf4df;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1100px;padding:32px}.hero{background:linear-gradient(135deg,rgba(248,113,113,.2),rgba(245,158,11,.13),rgba(34,197,94,.12));border:1px solid #39301d;border-radius:30px;margin-bottom:18px;padding:28px}.eyebrow{color:#fcd34d;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}.status{border:1px solid #575030;border-radius:999px;display:inline-flex;font-weight:900;padding:8px 12px}.status.pass{border-color:rgba(34,197,94,.65)}.status.warn{border-color:rgba(245,158,11,.75)}.status.fail{border-color:rgba(239,68,68,.85)}.grid{display:grid;gap:14px}.actions{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));margin:0 0 18px}.summary{display:flex;flex-wrap:wrap;gap:10px}.summary span{background:#181711;border:1px solid #39301d;border-radius:999px;padding:8px 12px}article{background:#181711;border:1px solid #39301d;border-radius:22px;padding:18px}article.critical{border-color:rgba(239,68,68,.85)}article.warn{border-color:rgba(245,158,11,.75)}article.info{border-color:rgba(34,197,94,.55)}article.action{border-color:#5b4a22}article span{color:#fcd34d;font-size:.78rem;font-weight:900;letter-spacing:.08em}article h2{margin:.35rem 0}.muted,article p{color:#cfc5a8}article strong{display:block;font-size:1.3rem;margin:.5rem 0}a{color:#fde68a;margin-right:12px}button{background:#fcd34d;border:0;border-radius:999px;color:#171307;cursor:pointer;font-weight:900;padding:10px 14px}button:disabled{cursor:not-allowed;opacity:.55}</style></head><body><main><section class="hero"><p class="eyebrow">Operational triage</p><h1>${escapeHtml43(title)}</h1><p class="status ${escapeHtml43(report.status)}">Overall: ${escapeHtml43(report.status.toUpperCase())}</p><p class="muted">Generated ${escapeHtml43(new Date(report.generatedAt).toLocaleString())}</p><div class="summary"><span>${String(report.summary.critical)} critical</span><span>${String(report.summary.warn)} warn</span><span>${String(report.summary.info)} info</span><span>${String(report.summary.total)} total</span></div></section><h2>Recovery actions</h2><section class="actions">${actions || '<article class="action"><span>NONE</span><h2>No recovery actions</h2><p>No executable actions are available for this report.</p></article>'}</section><h2>Timeline</h2><section class="grid">${events || '<article class="info"><span>INFO</span><h2>No incident events</h2><p>No non-pass operational events were found in this window.</p></article>'}</section></main><script>document.querySelectorAll("[data-voice-incident-action]").forEach((button)=>{button.addEventListener("click",async()=>{const id=button.getAttribute("data-voice-incident-action");if(!id)return;button.disabled=true;const original=button.textContent;button.textContent="Running...";try{const response=await fetch("/
|
|
30425
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>${escapeHtml43(title)}</title><style>body{background:#11110d;color:#faf4df;font-family:ui-sans-serif,system-ui,sans-serif;margin:0}main{margin:auto;max-width:1100px;padding:32px}.hero{background:linear-gradient(135deg,rgba(248,113,113,.2),rgba(245,158,11,.13),rgba(34,197,94,.12));border:1px solid #39301d;border-radius:30px;margin-bottom:18px;padding:28px}.eyebrow{color:#fcd34d;font-weight:900;letter-spacing:.12em;text-transform:uppercase}h1{font-size:clamp(2.4rem,6vw,5rem);letter-spacing:-.06em;line-height:.9;margin:.2rem 0 1rem}.status{border:1px solid #575030;border-radius:999px;display:inline-flex;font-weight:900;padding:8px 12px}.status.pass{border-color:rgba(34,197,94,.65)}.status.warn{border-color:rgba(245,158,11,.75)}.status.fail{border-color:rgba(239,68,68,.85)}.grid{display:grid;gap:14px}.actions{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));margin:0 0 18px}.summary{display:flex;flex-wrap:wrap;gap:10px}.summary span{background:#181711;border:1px solid #39301d;border-radius:999px;padding:8px 12px}article{background:#181711;border:1px solid #39301d;border-radius:22px;padding:18px}article.critical{border-color:rgba(239,68,68,.85)}article.warn{border-color:rgba(245,158,11,.75)}article.info{border-color:rgba(34,197,94,.55)}article.action{border-color:#5b4a22}article span{color:#fcd34d;font-size:.78rem;font-weight:900;letter-spacing:.08em}article h2{margin:.35rem 0}.muted,article p{color:#cfc5a8}article strong{display:block;font-size:1.3rem;margin:.5rem 0}a{color:#fde68a;margin-right:12px}button{background:#fcd34d;border:0;border-radius:999px;color:#171307;cursor:pointer;font-weight:900;padding:10px 14px}button:disabled{cursor:not-allowed;opacity:.55}</style></head><body><main><section class="hero"><p class="eyebrow">Operational triage</p><h1>${escapeHtml43(title)}</h1><p class="status ${escapeHtml43(report.status)}">Overall: ${escapeHtml43(report.status.toUpperCase())}</p><p class="muted">Generated ${escapeHtml43(new Date(report.generatedAt).toLocaleString())}</p><div class="summary"><span>${String(report.summary.critical)} critical</span><span>${String(report.summary.warn)} warn</span><span>${String(report.summary.info)} info</span><span>${String(report.summary.total)} total</span></div></section><h2>Recovery actions</h2><section class="actions">${actions || '<article class="action"><span>NONE</span><h2>No recovery actions</h2><p>No executable actions are available for this report.</p></article>'}</section><h2>Timeline</h2><section class="grid">${events || '<article class="info"><span>INFO</span><h2>No incident events</h2><p>No non-pass operational events were found in this window.</p></article>'}</section></main><script>const voiceIncidentActionPath=${JSON.stringify(actionPath)};document.querySelectorAll("[data-voice-incident-action]").forEach((button)=>{button.addEventListener("click",async()=>{const id=button.getAttribute("data-voice-incident-action");if(!id)return;button.disabled=true;const original=button.textContent;button.textContent="Running...";try{const response=await fetch(voiceIncidentActionPath+"/"+encodeURIComponent(id),{method:"POST"});button.textContent=response.ok?"Done":"Failed";if(response.ok)setTimeout(()=>location.reload(),700)}catch{button.textContent="Failed"}finally{setTimeout(()=>{button.disabled=false;button.textContent=original},1600)}})});</script></body></html>`;
|
|
30425
30426
|
};
|
|
30426
30427
|
var createVoiceIncidentTimelineRoutes = (options) => {
|
|
30427
30428
|
const path = options.path ?? "/api/voice/incident-timeline";
|
|
@@ -30443,7 +30444,10 @@ var createVoiceIncidentTimelineRoutes = (options) => {
|
|
|
30443
30444
|
if (htmlPath !== false) {
|
|
30444
30445
|
routes.get(htmlPath, async () => {
|
|
30445
30446
|
const report = await buildVoiceIncidentTimelineReport(options);
|
|
30446
|
-
const body = await (options.render ?? ((input) => renderVoiceIncidentTimelineHTML(input, {
|
|
30447
|
+
const body = await (options.render ?? ((input) => renderVoiceIncidentTimelineHTML(input, {
|
|
30448
|
+
actionPath: actionPath === false ? undefined : actionPath,
|
|
30449
|
+
title: options.title
|
|
30450
|
+
})))(report);
|
|
30447
30451
|
return new Response(body, {
|
|
30448
30452
|
headers: {
|
|
30449
30453
|
"Content-Type": "text/html; charset=utf-8",
|