core/selectors/record.selector.ts
core/selectors/record.selector.ts is a file in GovLab Quality. 44 lines of code and 15 definitions.
export const isRecord = (value: unknown): value is Record<string, unknown> =>
typeof value === "object" && value !== null && !Array.isArray(value);
export const recordAt = (record: Record<string, unknown>, key: string): Record<string, unknown> => {
const value = record[key];
return isRecord(value) ? value : {};
};
export const recordsAt = (record: Record<string, unknown>, key: string): Record<string, unknown>[] => {
const value = record[key];
return Array.isArray(value) ? value.filter(isRecord) : [];
};
export const firstRecord = (records: Record<string, unknown>[]): Record<string, unknown> => records[0] ?? {};
export const stringField = (record: Record<string, unknown>, key: string, fallback = ""): string => {
const value = record[key];
return typeof value === "string" ? value : fallback;
};
export const numberField = (record: Record<string, unknown>, key: string, fallback: number): number => {
const value = record[key];
return typeof value === "number" ? value : fallback;
};
export const boolField = (record: Record<string, unknown>, key: string): boolean => record[key] === true;
export const hasField = (record: Record<string, unknown>, key: string): boolean => (record[key] ?? null) !== null;
export const arrayField = (record: Record<string, unknown>, key: string): unknown[] => {
const value = record[key];
return Array.isArray(value) ? value : [];
};
export const stringArrayField = (record: Record<string, unknown>, key: string): string[] =>
arrayField(record, key).filter((entry): entry is string => typeof entry === "string");
export const stringArrayFieldOr = (
record: Record<string, unknown>,
key: string,
fallback: readonly string[],
): string[] => (Array.isArray(record[key]) ? stringArrayField(record, key) : [...fallback]);
export const numericField = (record: Record<string, unknown>, key: string, fallback: number): number => {
const value = record[key];
const parsed = typeof value === "string" || typeof value === "number" ? Number(value) : Number.NaN;
return parsed || fallback;
};
export const firstNumberField = (record: Record<string, unknown>, key: string, fallback: number): number => {
const value = record[key];
if (Array.isArray(value) && value.length > 0 && typeof value[0] === "number") {
return value[0];
}
return fallback;
};