/** * Utility functions for formatting data */ /** * Format a date to a human-readable string * @param date - The date to format (Date object or ISO string) * @param options - Formatting options * @returns Formatted date string */ export declare function formatDate(date: Date | string, options?: Intl.DateTimeFormatOptions): string; /** * Format a number with thousands separators * @param num - The number to format * @returns Formatted number string */ export declare function formatNumber(num: number): string; /** * Format a price with currency symbol * @param price - The price to format * @param currency - The currency code * @returns Formatted price string */ export declare function formatPrice(price: number, currency?: string): string; /** * Format bytes to a human-readable string (KB, MB, GB, etc.) * @param bytes - The number of bytes * @param decimals - Number of decimal places * @returns Formatted bytes string */ export declare function formatBytes(bytes: number, decimals?: number): string; /** * Compact bytes formatter using the single-letter unit `'B'` (not * `'Bytes'`). Used by upload-progress UIs where horizontal space is * tight and the longer "Bytes" string wraps. Tops out at `TB`. * @example formatBytesShort(0) → "0 B"; formatBytesShort(1536) → "1.5 KB" */ export declare function formatBytesShort(bytes: number): string; /** * File-size formatter (1 decimal place, `'B'` unit, caps at `GB`). * Hub historical semantics — distinct from `formatBytesShort` (2dp) and * `formatBytes` (2dp / `'Bytes'`). Lifted from the hub during the doc-viewer * unification so all upload UIs, publication cards, and data-room file-size * displays render the same way. * @example formatFileSize(0) → "0 B"; formatFileSize(1500) → "1.5 KB" */ export declare function formatFileSize(bytes: number): string; /** * Format large numbers to abbreviated form (K, M, B) with no decimal points * @param num - The number to format * @returns Formatted number string (e.g., "1K", "2M", "3B") */ export declare function formatLargeNumber(num: number): string; /** * Abbreviate large numbers for compact display. * 1 200 → 1.2K , 15 000 → 15K , 2 000 000 → 2M * @param n Number to format */ export declare function formatAbbreviatedNumber(n: number): string; /** * Two-letter uppercase initials from the FIRST + LAST word of a name. * Used by avatar-style fallbacks (SquareAvatar, EntityImage) where * "John Michael Doe" → "JD" reads better than "JM". * * Returns `''` for empty / whitespace-only input. Single-word names * return a single uppercase letter. Pure — same input always produces * the same output, no locale or timezone surface. */ export declare function getFirstLastInitials(name?: string | null): string; /** * Two-letter uppercase initials from the FIRST + SECOND word of a name. * Used as SquareAvatar / EntityImage / EntityAuthorCard fallback across * admin and public pages in both the lib and the hub. Handles empty * strings, all-whitespace input, and single-word names cleanly — always * returns at least one character so the fallback slot is never empty. * * Single source of truth: every "first-letter of each word, uppercase, * max 2 chars" computation across hub + lib MUST come through here. */ export declare function nameInitials(name: string | null | undefined, fallback?: string): string; /** * Format seconds to MM:SS or HH:MM:SS format * Used for media durations (podcasts, videos) * Returns: "MM:SS" or "HH:MM:SS" if hours > 0 */ export declare function formatDurationMMSS(seconds: number | null | undefined): string; /** * Format seconds to compact human-readable duration * Used for displaying duration in cards and headers (media cards, program * headers, meeting-duration chips). * Returns: "Xh Xm", "Xh" (whole hours), or "X min" * * Whole hours deliberately drop the zero-minutes tail (`3600 → "1h"`, not * `"1h 0m"`) — this matches the hub `formatMinutesOrDash` docblock that * already advertised `"2h"`. Distinct from `formatDuration` (long words, * seconds input), `formatDurationFromMs` (elapsed-time telemetry, `"30.0m"`), * `formatDurationMMSS` (clock style), `formatDurationFromRange` (two dates). */ export declare function formatDurationCompact(seconds: number | null | undefined): string; /** * Format a webinar/event start time as the wall-clock in its OWN timezone. * * `date` is an instant (UTC timestamp / ISO string). `timezone` is the event's * IANA zone (e.g. `'America/New_York'`). Rendering in that explicit zone makes * the server (Vercel = UTC) and the visitor's browser emit the SAME text — * fixing the React #418 hydration mismatch — AND shows the true event time * (4:00 PM EDT, not the 8:00 PM UTC a plain UTC pin would show, nor the * viewer-local time the old unpinned call produced). Falls back to UTC when no * zone is given, and tolerates a non-IANA label (legacy data) without throwing. * The zone LABEL is rendered separately by callers, so it is never appended here. * * Returns: "4:00 PM" */ export declare function formatTimeWithTimezone(date: Date | string | null | undefined, timezone?: string | null): string; /** * Calculate and format duration between two timestamps * Used for webinar durations * Returns: "1h 30m" or "45m" */ export declare function formatDurationFromRange(startAt: string | Date | null | undefined, endAt: string | Date | null | undefined): string; /** * UTC-anchored date formatter — distinct from the local-rendering * `formatDate` above. RAG mappers + audit-style consumers want UTC anchor * so date-only strings (`'2024-08-15'`) don't drift across timezones, AND * a `'N/A'` (or caller-supplied) fallback for missing values so the LLM * never sees a blank. * * Accepts: * - ISO date or timestamp string (`'2024-08-15'` or `'2024-08-15T10:30:00Z'`) * - Numeric epoch milliseconds * - Numeric string (treated as epoch ms — Slack and GitHub timestamps * sometimes arrive that way) * - `null` / `undefined` / empty / unparseable → returns `options.fallback` * * Date-only strings (no `'T'`) get `T00:00:00Z` appended so they anchor to * UTC midnight rather than midnight in the runtime's local timezone. */ export interface FormatDateUTCOptions { /** Returned for null/undefined/empty/unparseable input. Defaults to 'N/A'. */ fallback?: string; /** 'UTC' (default) or 'local' — switch off the UTC anchor when audit * stability matters less than local relevance (chat-card timestamps). */ timezone?: 'UTC' | 'local'; } export declare function formatDateUTC(value: string | number | null | undefined, options?: FormatDateUTCOptions): string; /** * Format a reporting-month value (`entry_month`) as "Mon YYYY" / "Month YYYY", * always anchored to UTC. THE single home for the "What I Shipped" month label — * both the lib card (`'short'`) and the hub detail page (`'long'`) call this, so * the React #418 UTC-pin convention lives in exactly one place. Returns `null` * for empty input (callers omit the label entirely). */ export declare function formatEntryMonthUTC(entryMonth: string | null | undefined, style?: 'short' | 'long'): string | null; /** * Format a date string as `MM/DD/YYYY` for legal-document display * (privacy policy, terms of service). Locale-stable: always en-US. */ export declare function formatLegalDate(dateInput: string): string; /** * Format a currency value as `$1,234`. Returns `'N/A'` for null/undefined. * USD-rounded (no cents). Used on KPI cards + investor pages. */ export declare function formatCurrency(value: number | null | undefined): string; /** * Format a percent value as `12.50%`. Returns `'N/A'` for null/undefined. */ export declare function formatPercent(value: number | null | undefined): string; /** * Whole-dollar price (no cents) — `$1,234`. Configurable currency code. */ export declare function formatWholeDollars(price: number, currency?: string): string; export type MetricFormat = 'number' | 'currency' | 'percentage' | 'months'; /** * Polarity determines whether an increase is good or bad. * - 'positive': higher is better (revenue, users, MRR) → up = green, down = red * - 'negative': higher is worse (burn rate, churn, CAC) → up = red, down = green * - 'neutral': no judgment (headcount, runway) → always gray */ export type TrendPolarity = 'positive' | 'negative' | 'neutral'; /** * Format a metric value with compact notation ($1.2M, 150K, 12 months). */ export declare function formatCompactMetric(value: number, format?: MetricFormat, options?: { prefix?: string; suffix?: string; }): string; /** * Get ODS trend colors based on direction AND polarity. Single source * of truth for trend coloring across hub + lib. */ export declare function getTrendColors(direction: 'up' | 'down' | 'neutral', polarity?: TrendPolarity): { textClass: string; badgeClass: string; }; /** * Format a date range as `Apr 20, 2026 — Jul 20, 2026`. Used on review * cycle list/detail rows and summary headers. * * Accepts either full ISO timestamps or bare `YYYY-MM-DD` dates. Bare * dates are interpreted in the viewer's LOCAL timezone — otherwise * `"2026-04-20"` renders as `"Apr 19"` west of UTC. DB values for cycle * period are stored as plain dates, so local-tz parsing is correct. */ export declare function formatDateRange(start: string | null | undefined, end: string | null | undefined): string; /** * Format an ISO date string as `"Jan 5, 2025 at 10:30 AM"`. Used by * admin podcast/webinar cards where the display needs both the short * date AND wall-clock time in a single readable phrase. * * Uses `new Date(...).toLocale*` (NOT the TZ-safe split) because the * source columns store full timestamps + the wall-clock half MUST * render in the viewer's local timezone (a podcast scheduled "10:30 AM * EST" should display "10:30 AM" for the Eastern admin, "7:30 AM" for * the Pacific admin — viewer-local is the right semantics here, unlike * date-only fields). */ export declare function formatDateTimeAt(dateString: string): string; /** * Format a duration measured in MILLISECONDS as a compact human-readable * string. Returns `"0ms"` for null/NaN/negative, then `Xms` → `X.Xs` → * `X.Xm` as the input grows. Used by job-runs / orchestrator dashboards * where elapsed milliseconds is the natural unit. * * Distinct from `formatDuration(seconds)` (verbose `"X hours Y minutes"`) * and `formatDurationMMSS(seconds)` (media timecode `MM:SS`). */ export declare function formatDurationFromMs(ms: number | null | undefined): string; /** * Format seconds to verbose human-readable duration: `"X seconds"`, * `"X minutes"`, `"X hours Y minutes"`. Use this for human-readable * spans; for media timecodes use `formatDurationMMSS`; for compact * media labels use `formatDurationCompact`; for elapsed milliseconds * use `formatDurationFromMs`. */ export declare function formatDuration(seconds: number): string; /** * Title-case a slug-like string: split on `separator`, capitalize each word. * `titleCaseFromSlug('customer-success')` → `"Customer Success"` * `titleCaseFromSlug('self_hosted', '_')` → `"Self Hosted"` * * The separator is EXPLICIT per call site on purpose: `formatUnderscoreText` * delegates with `'_'` (its output stays byte-identical — `'self-hosted'` * remains `"Self-hosted"` on the vendor classification/pricing labels), while * scheduling-purpose labels pass `'-'`. A combined `[-_]` splitter would have * silently changed shipped vendor-facing strings. */ export declare function titleCaseFromSlug(text: string, separator?: string): string; /** * Format underscore-separated text into proper case. * `"self_hosted"` → `"Self Hosted"` * `"open_source"` → `"Open Source"` * * Thin delegate over {@link titleCaseFromSlug} with an underscore separator. */ export declare function formatUnderscoreText(text: string): string; /** * Strip HTML tags and decode common HTML entities from a string. * Useful for cleaning API responses that contain HTML content. * * @example * stripHtml('
Hello World
') // "Hello World" * stripHtml('Test & Example') // "Test & Example" */ export declare function stripHtml(html: string): string; /** * Display label for the openmsp `vendors.classification` enum. * Falls back to proper-cased underscore split for values not in the * curated mapping. */ export declare function formatClassification(classification: string): string; /** * Display label for the openmsp `vendors.pricing_model` enum. * Falls back to proper-cased underscore split for values not in the * curated mapping. */ export declare function formatPricingModel(pricingModel: string): string; /** * Format a bio/about text from the profiles table for display. * Handles HTML content (e.g. `` tags from rich text editors), * plain text passthrough, and null/undefined values. */ export declare function formatBioText(aboutHtml: string | null | undefined, fallback?: string): string; //# sourceMappingURL=format.d.ts.map