You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

62 lines
1.6 KiB

import {
DEFAULT_MASK_FIELD_KEYWORDS,
NEVER_EXPORT_FIELD_EXACT_NAMES,
type ExportMaskPolicy,
} from "../constants/export";
function hitKeyword(field: string, keywords: readonly string[]): boolean {
const name = field.toLowerCase();
return keywords.some((k) => name.includes(k.toLowerCase()));
}
function normalizeFieldName(field: string): string {
return field.toLowerCase().replace(/[_-]/g, "");
}
function shouldNeverExportField(field: string): boolean {
const normalizedField = normalizeFieldName(field);
return NEVER_EXPORT_FIELD_EXACT_NAMES.includes(
normalizedField as (typeof NEVER_EXPORT_FIELD_EXACT_NAMES)[number],
);
}
function shouldMaskField(field: string): boolean {
return hitKeyword(field, DEFAULT_MASK_FIELD_KEYWORDS);
}
function maskValue(value: unknown): unknown {
if (value === null || value === undefined) {
return value;
}
if (typeof value === "string") {
return "***";
}
if (typeof value === "number") {
return 0;
}
if (typeof value === "boolean") {
return false;
}
return "[masked]";
}
export function sanitizeUserForExport(
row: Record<string, unknown>,
maskPolicy: ExportMaskPolicy,
): Record<string, unknown> {
const out: Record<string, unknown> = {};
for (const [field, value] of Object.entries(row)) {
if (shouldNeverExportField(field)) {
continue;
}
if (maskPolicy === "masked" && shouldMaskField(field)) {
out[field] = maskValue(value);
continue;
}
out[field] = value;
}
return out;
}
// Backward-compatible alias used by current tests/callers.
export const applyExportMask = sanitizeUserForExport;