UNPKG

trigger.dev

Version:

A Command-Line Interface for Trigger.dev projects

330 lines 11.6 kB
const DEFAULT_MAX_TRACE_LINES = 500; export function formatRun(run) { const lines = []; // Header with basic info lines.push(`Run ${run.id}`); lines.push(`Task: ${run.taskIdentifier}`); lines.push(`Status: ${formatStatus(run.status)}`); // Timing information const timing = formatTiming(run); if (timing) { lines.push(`Timing: ${timing}`); } // Duration and cost if (run.durationMs > 0) { lines.push(`Duration: ${formatDuration(run.durationMs)}`); } if (run.costInCents > 0) { lines.push(`Cost: $${(run.costInCents / 100).toFixed(4)}`); } // Attempt count if (run.attemptCount > 1) { lines.push(`Attempts: ${run.attemptCount}`); } // Version and trigger info if (run.version) { lines.push(`Version: ${run.version}`); } // Tags if (run.tags && run.tags.length > 0) { lines.push(`Tags: ${run.tags.join(", ")}`); } // Error information if (run.error) { lines.push(`Error: ${run.error.name || "Error"}: ${run.error.message}`); if (run.error.stackTrace) { lines.push(`Stack: ${run.error.stackTrace.split("\n")[0]}`); // First line only } } // Related runs const relatedInfo = formatRelatedRuns(run.relatedRuns); if (relatedInfo) { lines.push(relatedInfo); } // Schedule info if (run.schedule) { lines.push(`Schedule: ${run.schedule.generator.expression} (${run.schedule.id})`); } // Batch info if (run.batchId) { lines.push(`Batch: ${run.batchId}`); } // Test flag if (run.isTest) { lines.push(`Test run`); } // TTL info if (run.ttl) { lines.push(`TTL: ${run.ttl}`); } // Payload and Output data if (run.payload) { lines.push(`Payload: ${JSON.stringify(run.payload, null, 2)}`); } else if (run.payloadPresignedUrl) { lines.push(`Payload: (large payload available via presigned URL: ${run.payloadPresignedUrl})`); } if (run.output) { lines.push(`Output: ${JSON.stringify(run.output, null, 2)}`); } else if (run.outputPresignedUrl) { lines.push(`Output: (large output available via presigned URL: ${run.outputPresignedUrl})`); } // Metadata if (run.metadata && Object.keys(run.metadata).length > 0) { lines.push(`Metadata: ${Object.keys(run.metadata).length} fields`); } return lines.join("\n"); } export function formatRunShape(run) { const lines = []; lines.push(`Run ${run.id}`); lines.push(`Task: ${run.taskIdentifier}`); lines.push(`Status: ${formatStatus(run.status)}`); if (run.output) { lines.push(`Output: ${JSON.stringify(run.output, null, 2)}`); } if (run.error) { lines.push(`Error: ${run.error.name || "Error"}: ${run.error.message}`); } if (run.metadata) { lines.push(`Metadata: ${JSON.stringify(run.metadata, null, 2)}`); } lines.push(`Created at: ${formatDateTime(run.createdAt)}`); if (run.finishedAt) { lines.push(`Finished at: ${formatDateTime(run.finishedAt)}`); } return lines.join("\n"); } function formatStatus(status) { return status.toLowerCase().replace(/_/g, " "); } function formatTiming(run) { const parts = []; parts.push(`created ${formatDateTime(run.createdAt)}`); if (run.startedAt) { parts.push(`started ${formatDateTime(run.startedAt)}`); } if (run.finishedAt) { parts.push(`finished ${formatDateTime(run.finishedAt)}`); } else if (run.delayedUntil) { parts.push(`delayed until ${formatDateTime(run.delayedUntil)}`); } return parts.length > 0 ? parts.join(", ") : null; } function formatDateTime(date) { if (!date) return "unknown"; try { return date .toISOString() .replace("T", " ") .replace(/\.\d{3}Z$/, " UTC"); } catch { return "unknown"; } } function formatDuration(durationMs) { if (durationMs < 1000) return `${durationMs}ms`; if (durationMs < 60000) return `${(durationMs / 1000).toFixed(1)}s`; if (durationMs < 3600000) return `${(durationMs / 60000).toFixed(1)}m`; return `${(durationMs / 3600000).toFixed(1)}h`; } function formatRelatedRuns(relatedRuns) { const parts = []; if (relatedRuns.parent) { parts.push(`parent: ${relatedRuns.parent.id} (${relatedRuns.parent.status.toLowerCase()})`); } if (relatedRuns.root && relatedRuns.root.id !== relatedRuns.parent?.id) { parts.push(`root: ${relatedRuns.root.id} (${relatedRuns.root.status.toLowerCase()})`); } if (relatedRuns.children && relatedRuns.children.length > 0) { const childStatuses = relatedRuns.children.reduce((acc, child) => { acc[child.status.toLowerCase()] = (acc[child.status.toLowerCase()] || 0) + 1; return acc; }, {}); const statusSummary = Object.entries(childStatuses) .map(([status, count]) => `${count} ${status}`) .join(", "); parts.push(`children: ${relatedRuns.children.length} runs (${statusSummary})`); } return parts.length > 0 ? `Related: ${parts.join("; ")}` : null; } export function formatRunTrace(trace, maxTraceLines = DEFAULT_MAX_TRACE_LINES) { const lines = []; lines.push(`Trace ID: ${trace.traceId}`); lines.push(""); // Format the root span and its children recursively const reachedMaxLines = formatSpan(trace.rootSpan, lines, 0, maxTraceLines); if (reachedMaxLines) { lines.push(`(truncated logs to ${maxTraceLines} lines)`); } return lines.join("\n"); } function formatSpan(span, lines, depth, maxLines) { if (lines.length >= maxLines) { return true; } const indent = " ".repeat(depth); const prefix = depth === 0 ? "└─" : "├─"; // Format span header const statusIndicator = getStatusIndicator(span.data); const duration = formatDuration(span.data.duration); const startTime = formatDateTime(span.data.startTime); lines.push(`${indent}${prefix} ${span.data.message} ${statusIndicator}`); lines.push(`${indent} Duration: ${duration}`); lines.push(`${indent} Started: ${startTime}`); if (span.data.taskSlug) { lines.push(`${indent} Task: ${span.data.taskSlug}`); } if (span.data.taskPath) { lines.push(`${indent} Path: ${span.data.taskPath}`); } if (span.data.queueName) { lines.push(`${indent} Queue: ${span.data.queueName}`); } if (span.data.machinePreset) { lines.push(`${indent} Machine: ${span.data.machinePreset}`); } if (span.data.workerVersion) { lines.push(`${indent} Worker: ${span.data.workerVersion}`); } // Show properties if they exist if (span.data.properties && Object.keys(span.data.properties).length > 0) { lines.push(`${indent} Properties: ${JSON.stringify(span.data.properties, null, 2).replace(/\n/g, "\n" + indent + " ")}`); } // Show output if it exists if (span.data.output) { lines.push(`${indent} Output: ${JSON.stringify(span.data.output, null, 2).replace(/\n/g, "\n" + indent + " ")}`); } // Show events if they exist and are meaningful if (span.data.events && span.data.events.length > 0) { lines.push(`${indent} Events: ${span.data.events.length} events`); // Optionally show first few events for context const maxEvents = 3; for (let i = 0; i < Math.min(span.data.events.length, maxEvents); i++) { const event = span.data.events[i]; if (typeof event === "object" && event !== null) { const eventStr = JSON.stringify(event, null, 2).replace(/\n/g, "\n" + indent + " "); lines.push(`${indent} [${i + 1}] ${eventStr}`); } } if (span.data.events.length > maxEvents) { lines.push(`${indent} ... and ${span.data.events.length - maxEvents} more events`); } } // Add spacing between spans if (span.children && span.children.length > 0) { lines.push(""); } // Recursively format children if (span.children) { const reachedMaxLines = span.children.some((child, index) => { const reachedMaxLines = formatSpan(child, lines, depth + 1, maxLines); // Add spacing between sibling spans (except for the last one) if (index < span.children.length - 1 && !reachedMaxLines) { lines.push(""); } return reachedMaxLines; }); return reachedMaxLines; } return false; } function getStatusIndicator(spanData) { if (spanData.isCancelled) return "[CANCELLED]"; if (spanData.isError) return "[ERROR]"; if (spanData.isPartial) return "[PARTIAL]"; return "[COMPLETED]"; } export function formatRunList(runsPage) { const lines = []; // Header with count info const totalRuns = runsPage.data.length; lines.push(`Found ${totalRuns} run${totalRuns === 1 ? "" : "s"}`); lines.push(""); if (totalRuns === 0) { lines.push("No runs found."); return lines.join("\n"); } // Format each run in a compact table-like format runsPage.data.forEach((run, index) => { lines.push(`${index + 1}. ${formatRunSummary(run)}`); }); // Pagination info lines.push(""); const paginationInfo = []; if (runsPage.pagination.previous) { paginationInfo.push("← Previous page available"); } if (runsPage.pagination.next) { paginationInfo.push("Next page available →"); } if (paginationInfo.length > 0) { lines.push(`Pagination: ${paginationInfo.join(" | ")}`); if (runsPage.pagination.next) { lines.push(`Next cursor: ${runsPage.pagination.next}`); } if (runsPage.pagination.previous) { lines.push(`Previous cursor: ${runsPage.pagination.previous}`); } } return lines.join("\n"); } function formatRunSummary(run) { const parts = []; // Basic info: ID, task, status parts.push(`${run.id}`); parts.push(`${run.taskIdentifier}`); parts.push(`${formatStatus(run.status)}`); // Environment parts.push(`env:${run.env.name}`); // Timing - show the most relevant time let timeInfo = ""; if (run.finishedAt) { timeInfo = `finished ${formatDateTime(run.finishedAt)}`; } else if (run.startedAt) { timeInfo = `started ${formatDateTime(run.startedAt)}`; } else if (run.delayedUntil) { timeInfo = `delayed until ${formatDateTime(run.delayedUntil)}`; } else { timeInfo = `created ${formatDateTime(run.createdAt)}`; } parts.push(timeInfo); // Duration if available if (run.durationMs > 0) { parts.push(`took ${formatDuration(run.durationMs)}`); } // Cost if significant if (run.costInCents > 0) { parts.push(`$${(run.costInCents / 100).toFixed(4)}`); } // Tags if present if (run.tags && run.tags.length > 0) { const tagStr = run.tags.length > 2 ? `${run.tags.slice(0, 2).join(", ")}+${run.tags.length - 2}` : run.tags.join(", "); parts.push(`tags:[${tagStr}]`); } // Test flag if (run.isTest) { parts.push("[TEST]"); } // Version if available if (run.version) { parts.push(`v${run.version}`); } return parts.join(" | "); } //# sourceMappingURL=formatters.js.map