Initial commit

This commit is contained in:
2025-12-14 21:59:59 +00:00
commit 9c2a1a795a
126 changed files with 21728 additions and 0 deletions
+87
View File
@@ -0,0 +1,87 @@
/**
* Format a timestamp as relative time (e.g., "5m ago", "2h ago")
*/
export function formatRelativeTime(dateOrEpoch: string | number): string {
const timestamp = typeof dateOrEpoch === 'number' ? dateOrEpoch : new Date(dateOrEpoch).getTime()
const now = Date.now()
const diff = now - timestamp
const seconds = Math.floor(diff / 1000)
const minutes = Math.floor(seconds / 60)
const hours = Math.floor(minutes / 60)
const days = Math.floor(hours / 24)
if (seconds < 60) return 'just now'
if (minutes < 60) return `${minutes}m ago`
if (hours < 24) return `${hours}h ago`
if (days < 7) return `${days}d ago`
return new Date(timestamp).toLocaleDateString()
}
/**
* Format uptime duration string
*/
export function formatUptime(uptimeStr: string): string {
// Parse Go duration string (e.g., "1h30m45.123456789s")
const match = uptimeStr.match(/(?:(\d+)h)?(?:(\d+)m)?(?:(\d+(?:\.\d+)?)s)?/)
if (!match) return uptimeStr
const hours = parseInt(match[1] || '0', 10)
const minutes = parseInt(match[2] || '0', 10)
const seconds = Math.floor(parseFloat(match[3] || '0'))
if (hours > 0) {
return `${hours}h ${minutes}m`
}
if (minutes > 0) {
return `${minutes}m ${seconds}s`
}
return `${seconds}s`
}
/**
* Truncate text to a maximum length with ellipsis
*/
export function truncate(text: string, maxLength: number): string {
if (text.length <= maxLength) return text
return text.slice(0, maxLength - 3) + '...'
}
/**
* Escape HTML entities
*/
export function escapeHtml(text: string): string {
const map: Record<string, string> = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#039;'
}
return text.replace(/[&<>"']/g, m => map[m])
}
/**
* Parse JSON safely with fallback
*/
export function parseJsonSafe<T>(value: unknown, fallback: T): T {
if (Array.isArray(value)) return value as T
if (typeof value === 'string') {
try {
return JSON.parse(value) as T
} catch {
return fallback
}
}
return fallback
}
/**
* Get string value safely from potentially nullable fields
*/
export function getString(value: unknown): string {
if (typeof value === 'string') return value
if (value === null || value === undefined) return ''
return String(value)
}