Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | 11x 129x 129x 64x 4x 60x 60x 65x 29x 85x 85x 85x 85x 129x | /**
* Generic table-rendering helpers driven by Sentry Events API
* `meta.fields` / `meta.units` metadata.
*
* Used by `sentry explore` (and any future command rendering dynamic
* Discover/Events results) to format cell values according to the
* field's declared type and unit, and to build right-aligned columns
* for numeric fields.
*/
import { escapeMarkdownCell } from "./markdown.js";
import { appendUnitSuffix, formatNumber } from "./numbers.js";
import type { Column } from "./table.js";
/** Sentry field types that render as right-aligned numeric columns. */
export const NUMERIC_FIELD_TYPES = new Set([
"integer",
"number",
"duration",
"percentage",
"size",
]);
/**
* Format a single cell value according to its `meta.fields` type.
*
* - `null` / `undefined` → `"—"`
* - `duration` / `size` → `formatNumber` + unit suffix (`"1,234ms"`, `"5MB"`)
* - `percentage` → multiplied by 100 and suffixed with `%`
* - other numbers → `formatNumber` (locale grouping, K/M/B above 1M)
* - non-numeric → `String(value)` with markdown-cell escaping
*/
export function formatCellValue(
value: unknown,
fieldType?: string,
unit?: string | null
): string {
Iif (value === null || value === undefined) {
return "—";
}
if (typeof value === "number") {
if (fieldType === "duration" || fieldType === "size") {
return appendUnitSuffix(formatNumber(value), unit);
}
Iif (fieldType === "percentage") {
return `${formatNumber(value * 100)}%`;
}
return formatNumber(value);
}
return escapeMarkdownCell(String(value));
}
/**
* Build dynamic table columns from API response field metadata.
*
* Each field name becomes a column. Numeric fields (per
* {@link NUMERIC_FIELD_TYPES}) are right-aligned and not truncated.
*
* Cell values are extracted from `row[name]` and formatted via
* {@link formatCellValue}.
*
* @param fieldNames - Column order (typically the user's `--field` order)
* @param fieldTypes - Optional `meta.fields` map: field name → Sentry type
* @param fieldUnits - Optional `meta.units` map: field name → unit string
*/
export function buildMetaColumns(
fieldNames: string[],
fieldTypes?: Record<string, string>,
fieldUnits?: Record<string, string | null>
): Column<Record<string, unknown>>[] {
return fieldNames.map((name) => {
const fieldType = fieldTypes?.[name];
const unit = fieldUnits?.[name];
const isNumeric = fieldType ? NUMERIC_FIELD_TYPES.has(fieldType) : false;
return {
header: name.toUpperCase(),
value: (row) => formatCellValue(row[name], fieldType, unit),
align: isNumeric ? ("right" as const) : ("left" as const),
truncate: !isNumeric,
};
});
}
|