purify-objects
Version:
A powerful TypeScript library for cleaning objects by removing empty values, with support for YAML and CSV formats
97 lines (83 loc) • 3.01 kB
text/typescript
import { isNil, isObject, cloneDeep } from './utils';
import { CleanerOptions, AnyObject, FileFormat, ParserOptions } from './types';
import { parseYAML, parseCSV, stringifyYAML, stringifyCSV } from './parsers';
const INITIAL_OPTIONS: Required<Omit<CleanerOptions, 'customCleaner'>> & Pick<CleanerOptions, 'customCleaner'> = {
customCleaner: undefined,
keepFields: [],
recursive: true,
safe: true
};
const evaluateEmptiness = <T>(value: T): boolean => (
isNil(value) ||
value === '' ||
(Array.isArray(value) && !value.length) ||
(isObject(value) && !Object.keys(value as object).length)
);
function processNestedObject<T extends AnyObject>(
target: T,
customCleaner: CleanerOptions['customCleaner'],
preservedFields: string[],
config: Required<CleanerOptions>
): T {
const workingCopy = config.safe ? cloneDeep(target) : target;
for (const key in workingCopy) {
const value = workingCopy[key];
if (preservedFields.includes(key)) continue;
if (customCleaner?.(key, value)) {
delete workingCopy[key];
continue;
}
if (evaluateEmptiness(value)) {
delete workingCopy[key];
continue;
}
if (config.recursive && isObject(value) && !Array.isArray(value)) {
const processed = processNestedObject(
value as T[Extract<keyof T, string>] & AnyObject,
customCleaner,
preservedFields,
config
);
if (!Object.keys(processed).length) {
delete workingCopy[key];
} else {
workingCopy[key] = processed as T[Extract<keyof T, string>];
}
}
}
return workingCopy;
}
export function cleanObject<T extends AnyObject>(
obj: T,
customCleaner?: CleanerOptions['customCleaner'],
keepFields: string[] = [],
options: CleanerOptions = {}
): T {
const config = { ...INITIAL_OPTIONS, ...options } as Required<CleanerOptions>;
return processNestedObject(obj, customCleaner, keepFields, config);
}
export function parseContent(content: string, format: FileFormat, options: ParserOptions = {}): AnyObject | AnyObject[] {
switch (format) {
case 'yaml':
return parseYAML(content) as AnyObject;
case 'csv':
return parseCSV(content, { delimiter: options.delimiter || ',', headers: options.headers !== false }) as AnyObject[];
default:
return JSON.parse(content);
}
}
export function stringifyContent(data: AnyObject | AnyObject[], format: FileFormat, options: ParserOptions = {}): string {
switch (format) {
case 'yaml':
return stringifyYAML(data as AnyObject);
case 'csv':
return stringifyCSV(Array.isArray(data) ? data : [data], {
delimiter: options.delimiter || ',',
headers: options.headers !== false
});
default:
return JSON.stringify(data, null, 2);
}
}
export { parseYAML, parseCSV, stringifyYAML, stringifyCSV };
export default cleanObject;