mirror of
https://github.com/Infisical/infisical.git
synced 2026-01-10 07:58:15 -05:00
rewrite aggregateTerminalEvents to work properly with timestamps
This commit is contained in:
@@ -22,51 +22,78 @@ export const aggregateTerminalEvents = (events: TTerminalEvent[]): AggregatedTer
|
||||
|
||||
if (outputEvents.length === 0) return [];
|
||||
|
||||
// First, combine all events into one string to process
|
||||
const allText = outputEvents
|
||||
.map((e) => {
|
||||
try {
|
||||
return stripAnsiCodes(atob(e.data));
|
||||
} catch {
|
||||
return "";
|
||||
}
|
||||
})
|
||||
.join("");
|
||||
// Decode each event and track character positions to map back to original events
|
||||
const decodedEvents: { text: string; event: TTerminalEvent }[] = outputEvents.map((e) => {
|
||||
try {
|
||||
return { text: stripAnsiCodes(atob(e.data)), event: e };
|
||||
} catch {
|
||||
return { text: "", event: e };
|
||||
}
|
||||
});
|
||||
|
||||
// Build a character-to-event index mapping
|
||||
// This tracks which original event each character came from
|
||||
const charToEventIndex: number[] = [];
|
||||
decodedEvents.forEach((decoded, eventIndex) => {
|
||||
for (let i = 0; i < decoded.text.length; i += 1) {
|
||||
charToEventIndex.push(eventIndex);
|
||||
}
|
||||
});
|
||||
|
||||
const allText = decodedEvents.map((d) => d.text).join("");
|
||||
|
||||
// Split on lines that contain shell prompts
|
||||
// Pattern matches: user@hostname:path# or user@hostname:path$
|
||||
const promptPattern = /^[\w-]+@[\w-]+[^\s]*[:#$]\s+/;
|
||||
|
||||
const lines = allText.split("\n");
|
||||
const segments: string[] = [];
|
||||
let currentSegment: string[] = [];
|
||||
const segments: { text: string; startCharIndex: number }[] = [];
|
||||
let currentSegmentLines: string[] = [];
|
||||
let currentSegmentStartChar = 0;
|
||||
let currentCharIndex = 0;
|
||||
|
||||
lines.forEach((line) => {
|
||||
lines.forEach((line, lineIndex) => {
|
||||
const hasPrompt = promptPattern.test(line);
|
||||
|
||||
if (hasPrompt && currentSegment.length > 0) {
|
||||
if (hasPrompt && currentSegmentLines.length > 0) {
|
||||
// Found a new prompt, save current segment and start new one
|
||||
segments.push(currentSegment.join("\n"));
|
||||
currentSegment = [line];
|
||||
segments.push({
|
||||
text: currentSegmentLines.join("\n"),
|
||||
startCharIndex: currentSegmentStartChar
|
||||
});
|
||||
currentSegmentLines = [line];
|
||||
currentSegmentStartChar = currentCharIndex;
|
||||
} else {
|
||||
// Add line to current segment
|
||||
currentSegment.push(line);
|
||||
currentSegmentLines.push(line);
|
||||
}
|
||||
|
||||
// Account for line length + newline character (except for last line)
|
||||
currentCharIndex += line.length + (lineIndex < lines.length - 1 ? 1 : 0);
|
||||
});
|
||||
|
||||
// Add the last segment
|
||||
if (currentSegment.length > 0) {
|
||||
segments.push(currentSegment.join("\n"));
|
||||
if (currentSegmentLines.length > 0) {
|
||||
segments.push({
|
||||
text: currentSegmentLines.join("\n"),
|
||||
startCharIndex: currentSegmentStartChar
|
||||
});
|
||||
}
|
||||
|
||||
// Filter out empty segments and convert to aggregated events
|
||||
const validSegments = segments.filter((seg) => seg.trim().length > 0);
|
||||
const validSegments = segments.filter((seg) => seg.text.trim().length > 0);
|
||||
|
||||
return validSegments.map((segment) => ({
|
||||
timestamp: outputEvents[0].timestamp,
|
||||
eventType: "output",
|
||||
data: segment,
|
||||
elapsedTime: outputEvents[0].elapsedTime,
|
||||
eventCount: Math.ceil(outputEvents.length / validSegments.length)
|
||||
}));
|
||||
return validSegments.map((segment) => {
|
||||
// Find the original event that corresponds to the start of this segment
|
||||
const eventIndex = charToEventIndex[segment.startCharIndex] ?? 0;
|
||||
const originalEvent = decodedEvents[eventIndex]?.event ?? outputEvents[0];
|
||||
|
||||
return {
|
||||
timestamp: originalEvent.timestamp,
|
||||
eventType: "output",
|
||||
data: segment.text,
|
||||
elapsedTime: originalEvent.elapsedTime,
|
||||
eventCount: 1
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user