UNPKG

nhb-toolbox

Version:

A versatile collection of smart, efficient, and reusable utility functions, classes and types for everyday development needs.

257 lines (256 loc) 10.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createControlledFormData = void 0; const guards_1 = require("../date/guards"); const non_primitives_1 = require("../guards/non-primitives"); const primitives_1 = require("../guards/primitives"); const basics_1 = require("../string/basics"); const guards_2 = require("./guards"); const createControlledFormData = (data, configs) => { if (typeof FormData === 'undefined') { throw new Error('FormData is not available! Please make sure your environment supports FormData.'); } const formData = new FormData(); const { stringifyNested = '*', ignoreKeys = [], breakArray, lowerCaseKeys, dotNotateNested, lowerCaseValues, requiredKeys, } = configs || {}; const _compareKeyPaths = (key, paths) => { return paths.some((path) => key === path || key.startsWith(`${path}.`)); }; const _shouldLowercaseKeys = (key) => { return Array.isArray(lowerCaseKeys) ? _compareKeyPaths(key, lowerCaseKeys) : lowerCaseKeys === '*'; }; const _shouldLowercaseValue = (key) => { return Array.isArray(lowerCaseValues) ? _compareKeyPaths(key, lowerCaseValues) : lowerCaseValues === '*'; }; const _transformKey = (key) => { return (_shouldLowercaseKeys(key) ? key.toLowerCase() : key); }; const _parseDateLike = (value) => { return String(JSON.parse(JSON.stringify(value))); }; const _isRequiredKey = (key) => { const transformedKey = _transformKey(key); return Array.isArray(requiredKeys) ? _compareKeyPaths(transformedKey, requiredKeys) : requiredKeys === '*'; }; const _shouldDotNotate = (key) => { const transformedKey = _transformKey(key); return Array.isArray(dotNotateNested) ? _compareKeyPaths(transformedKey, dotNotateNested) : dotNotateNested === '*'; }; const _shouldStringify = (key) => { const transformedKey = _transformKey(key); return Array.isArray(stringifyNested) ? _compareKeyPaths(transformedKey, stringifyNested) : stringifyNested === '*'; }; const _shouldBreakArray = (key) => { const transformedKey = _transformKey(key); return Array.isArray(breakArray) ? _compareKeyPaths(transformedKey, breakArray) : breakArray === '*'; }; const _cleanObject = (obj, parentKey = '') => { return Object.entries(obj).reduce((acc, [key, value]) => { const transformedKey = _transformKey(key); const fullKey = parentKey ? `${parentKey}.${transformedKey}` : transformedKey; if (_compareKeyPaths(fullKey, ignoreKeys)) { return acc; } const shouldKeep = (value != null && value !== '') || _isRequiredKey(fullKey) || (0, primitives_1.isNonEmptyString)(value) || (0, non_primitives_1.isValidArray)(value) || (0, non_primitives_1.isNotEmptyObject)(value); if (shouldKeep) { if ((0, guards_1.isDateLike)(value)) { acc[transformedKey] = value; } else if ((0, non_primitives_1.isNotEmptyObject)(value)) { if ((0, guards_1.isDateLike)(value)) { acc[transformedKey] = value; } else { const cleaned = _cleanObject(value, fullKey); if (_isRequiredKey(fullKey) || (0, non_primitives_1.isNotEmptyObject)(cleaned)) { acc[transformedKey] = cleaned; } } } else { if ((0, primitives_1.isString)(value)) { if ((0, primitives_1.isNonEmptyString)(value)) { let cleanString = value; if (configs?.trimStrings) { cleanString = (0, basics_1.trimString)(cleanString); } if (_shouldLowercaseValue(fullKey)) { cleanString = cleanString?.toLowerCase(); } acc[transformedKey] = cleanString; } else { acc[transformedKey] = value; } } else if (Array.isArray(value)) { if (_isRequiredKey(fullKey) || (0, non_primitives_1.isValidArray)(value)) { acc[transformedKey] = value; } } else if ((0, non_primitives_1.isEmptyObject)(value)) { if (_isRequiredKey(fullKey)) { acc[transformedKey] = value; } } else { acc[transformedKey] = value; } } } return acc; }, {}); }; const _addToFormData = (key, value) => { const transformedKey = _transformKey(key); if (_compareKeyPaths(transformedKey, ignoreKeys)) { return; } if ((0, guards_2.isCustomFileArray)(value)) { for (const file of value) { formData.append(transformedKey, file?.originFileObj); } } else if ((0, guards_2.isFileUpload)(value)) { if (value?.fileList) { for (const file of value.fileList) { formData.append(transformedKey, file?.originFileObj); } } else if (value?.file) { if ((0, guards_2.isCustomFile)(value?.file)) { formData.append(transformedKey, value?.file?.originFileObj); } else { formData.append(transformedKey, value?.file); } } } else if ((0, guards_2.isFileOrBlob)(value)) { formData.append(transformedKey, value); } else if ((0, guards_2.isFileList)(value)) { for (let i = 0; i < value?.length; i++) { formData.append(transformedKey, value.item(i)); } } else if (Array.isArray(value)) { if ((0, guards_2.isFileArray)(value)) { if (_shouldBreakArray(key)) { value?.forEach((item, index) => { _addToFormData(`${transformedKey}[${index}]`, item); }); } else { value?.forEach((item) => { formData.append(transformedKey, item); }); } } else if ((0, non_primitives_1.isValidArray)(value)) { if (_shouldBreakArray(key)) { value?.forEach((item, index) => { _addToFormData(`${transformedKey}[${index}]`, item); }); } else { formData.append(transformedKey, JSON.stringify(value)); } } else if (_isRequiredKey(key)) { formData.append(transformedKey, JSON.stringify(value)); } } else if ((0, guards_1.isDateLike)(value)) { formData.append(transformedKey, _parseDateLike(value)); } else if ((0, non_primitives_1.isNotEmptyObject)(value)) { if (_shouldStringify(key) && !_shouldDotNotate(key)) { const cleanedValue = _cleanObject(value, key); if ((0, non_primitives_1.isNotEmptyObject)(cleanedValue) || _isRequiredKey(key)) { formData.append(transformedKey, JSON.stringify(cleanedValue)); } } else { Object.entries(value).forEach(([nestedKey, nestedValue]) => { _addToFormData(`${key}.${nestedKey}`, nestedValue); }); } } else { const isNotNullish = value != null && value !== ''; if (isNotNullish || _isRequiredKey(key)) { if ((0, primitives_1.isString)(value)) { let processedValue = value; if (configs?.trimStrings) { processedValue = (0, basics_1.trimString)(processedValue); } if (_shouldLowercaseValue(key)) { processedValue = processedValue.toLowerCase(); } formData.append(transformedKey, processedValue); } else { formData.append(transformedKey, value); } } } }; const _processObject = (obj, parentKey = '') => { Object.entries(obj).forEach(([key, value]) => { const transformedKey = _transformKey(key); const fullKey = parentKey ? `${parentKey}.${transformedKey}` : transformedKey; if (_compareKeyPaths(fullKey, ignoreKeys)) { return; } if (configs?.trimStrings && (0, primitives_1.isNonEmptyString)(value)) { value = (0, basics_1.trimString)(value); } if (_shouldDotNotate(fullKey)) { _addToFormData(fullKey, value); } else if ((0, non_primitives_1.isNotEmptyObject)(value) && !_shouldStringify(fullKey)) { if ((0, guards_1.isDateLike)(value)) { _addToFormData(key, _parseDateLike(value)); } else { _processObject(value, key); } } else if ((0, guards_2.isFileOrBlob)(value)) { _addToFormData(key, value); } else if ((0, guards_1.isDateLike)(value)) { _addToFormData(key, _parseDateLike(value)); } else if ((0, non_primitives_1.isEmptyObject)(value)) { if (_isRequiredKey(fullKey)) { _addToFormData(key, JSON.stringify(value)); } } else { _addToFormData(key, value); } }); }; if ((0, non_primitives_1.isNotEmptyObject)(data)) { _processObject(data); } return formData; }; exports.createControlledFormData = createControlledFormData;