138 lines
3.1 KiB
TypeScript
138 lines
3.1 KiB
TypeScript
export type AuditRow = Record<string, unknown> & { 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<string, unknown>)
|
|
: 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<string, unknown>;
|
|
|
|
const normalized: Record<string, unknown> = {};
|
|
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,
|
|
};
|
|
});
|