export type AuditRow = Record & { id: string | number }; export interface AuditApiResponse { total?: number; limit?: number; page?: number; data?: unknown; items?: unknown[]; audits?: unknown[]; logs?: unknown[]; results?: unknown[]; records?: unknown[]; meta?: { total?: number }; pagination?: { total?: number }; } export interface AuditQueryResult { rows: AuditRow[]; total: number; payload: AuditApiResponse; pageIndex: number; } export const DEFAULT_PAGE_SIZE = 25; const CANDIDATE_ARRAY_KEYS: (keyof AuditApiResponse)[] = [ "items", "audits", "logs", "results", "records", ]; export const normalizeValue = (value: unknown): string | number => { if (value === null || value === undefined) { return ""; } if (typeof value === "string" || typeof value === "number") { return value; } if (typeof value === "boolean") { return value ? "true" : "false"; } return JSON.stringify(value); }; export const extractArray = (payload: AuditApiResponse): unknown[] => { if (Array.isArray(payload)) { return payload; } for (const key of CANDIDATE_ARRAY_KEYS) { const candidate = payload[key]; if (Array.isArray(candidate)) { return candidate; } } const dataRecord = payload.data && typeof payload.data === "object" && !Array.isArray(payload.data) ? (payload.data as Record) : null; if (dataRecord) { for (const key of CANDIDATE_ARRAY_KEYS) { const candidate = dataRecord[key]; if (Array.isArray(candidate)) { return candidate; } } } if (Array.isArray(payload.data)) { return payload.data; } return []; }; export const resolveTotal = ( payload: AuditApiResponse, fallback: number ): number => { const fromPayload = payload.total; const fromMeta = payload.meta?.total; const fromPagination = payload.pagination?.total; const fromData = payload.data && typeof payload.data === "object" && !Array.isArray(payload.data) ? (payload.data as { total?: number }).total : undefined; return ( (typeof fromPayload === "number" && fromPayload) || (typeof fromMeta === "number" && fromMeta) || (typeof fromPagination === "number" && fromPagination) || (typeof fromData === "number" && fromData) || fallback ); }; export const normalizeRows = ( entries: unknown[], pageIndex: number ): AuditRow[] => entries.map((entry, index) => { if (!entry || typeof entry !== "object" || Array.isArray(entry)) { return { id: `${pageIndex}-${index}`, value: normalizeValue(entry), }; } const record = entry as Record; const normalized: Record = {}; Object.entries(record).forEach(([key, value]) => { normalized[key] = normalizeValue(value); }); const identifier = record.id ?? record.audit_id ?? record.log_id ?? record._id ?? `${pageIndex}-${index}`; return { id: (identifier as string | number) ?? `${pageIndex}-${index}`, ...normalized, }; });