UNPKG

@kaspersky/dev-tools

Version:

Development tools and configs for Babel, ESLint and TypeScript

177 lines (176 loc) 7.61 kB
"use strict"; const { extractArgValue, isFormExcludet, isFromAlreadyMigrated, message, migrationList } = require('./helpers'); const predefinedIndentBeforeCssClasses = { 'indent-checkbox': 101, 'indent-toggle': 102, 'indent-label': 103 }; const indentCssClasses = [ 'indent-1', 'indent-2', 'indent-3', 'indent-top-1', 'indent-top-2', 'indent-top-3', 'indent-both-1', 'indent-both-2', 'indent-both-3', 'indent-bottom-1', 'indent-bottom-2', 'indent-bottom-3', 'indent-top-negative-1', 'indent-top-negative-2', 'indent-top-negative-3', 'indent-bottom-negative-1', 'indent-bottom-negative-2', 'indent-bottom-negative-3', ...Object.keys(predefinedIndentBeforeCssClasses) ]; const typesWithSubElements = [ ...['control-group', 20], ...['data-table', 31] ]; const filterIndentCSSClasses = (classesString) => { return typeof classesString === 'string' && classesString ? classesString .split(' ') .filter(className => !indentCssClasses.some(indent => indent === className)) .join(' ') : ''; }; const parseValueFromClassName = ({ customCssClasses, subString }) => { return customCssClasses ? parseInt((customCssClasses .split(' ') .map(cssClass => { return Object.keys(predefinedIndentBeforeCssClasses).some(key => key === cssClass) ? `indent-${predefinedIndentBeforeCssClasses[cssClass]}` : cssClass; }) .find(cssClass => cssClass.replace(/-\d+/, '') === subString) || '') .replace(/^\D+/g, '')) || 0 : 0; }; const createReplaceCssClassesWithOffsets = (customClassFunction) => { const resolveOffsets = ({ indent = 0, offsetBottom = 0, offsetTop = 0, offsetAfter = 0, customClass: customCssClasses }) => { const valuesFromClassName = customCssClasses ? { cssClassLeft: parseValueFromClassName({ customCssClasses, subString: 'indent' }), cssClassTop: parseValueFromClassName({ customCssClasses, subString: 'indent-top' }), cssClassTopNegative: parseValueFromClassName({ customCssClasses, subString: 'indent-top-negative' }), cssClassBottom: parseValueFromClassName({ customCssClasses, subString: 'indent-bottom' }), cssClassBottomNegative: parseValueFromClassName({ customCssClasses, subString: 'indent-bottom-negative' }), cssClassBoth: parseValueFromClassName({ customCssClasses, subString: 'indent-both' }) } : {}; return { indent: indent || valuesFromClassName.cssClassLeft || valuesFromClassName.cssClassBoth || 0, offsetBottom: offsetBottom || valuesFromClassName.cssClassBottom || (valuesFromClassName.cssClassBottomNegative ? -valuesFromClassName.cssClassBottomNegative : 0) || 0, offsetTop: offsetTop || valuesFromClassName.cssClassTop || (valuesFromClassName.cssClassTopNegative ? -valuesFromClassName.cssClassTopNegative : 0) || 0, offsetAfter: offsetAfter || valuesFromClassName.cssClassBoth || 0, customClass: customClassFunction(customCssClasses, filterIndentCSSClasses) }; }; const updateProductSectionElement = el => { return { ...el, style: el.style && { ...el.style, ...resolveOffsets(el.style) }, elements: Array.isArray(el.elements) && typesWithSubElements.includes(el.type) ? el.elements.map(updateProductSectionElement) : el.elements }; }; const updateBuilderSectionElement = el => { if (!el || !el.state) { return el; } const elements = el.state.elements; return { ...el, state: { ...el.state, style: el.state.style && { ...el.state.style, ...resolveOffsets(el.state.style) }, elements: Array.isArray(elements) && typesWithSubElements.includes(el.type) ? elements.map(updateBuilderSectionElement) : elements } }; }; const replaceCssClassesWithOffsetsFunc = async ({ fs, path }) => { const UI_FORMS_PATH = path.join('./client/ui/'); const FILE_EXT = '.json'; const specificFormArray = extractArgValue('--only') || []; const excludeArray = extractArgValue('--exclude'); return new Promise((resolve) => { const formNames = fs.readdirSync(UI_FORMS_PATH) .filter(file => path.extname(file) === FILE_EXT); const resolvedFormNames = specificFormArray.length ? formNames.filter(file => specificFormArray.includes(file.replace(FILE_EXT, ''))) : formNames; // eslint-disable-next-line no-console console.log(`${message.startingPatchOffsets} ${UI_FORMS_PATH} `); resolvedFormNames.forEach(file => { if (isFormExcludet({ file, excludeArray })) { // eslint-disable-next-line no-console console.log(`${message.skipped} ${file}`); return; } // eslint-disable-next-line no-console console.log(`${message.reading} ${file}`); const json = JSON.parse(fs.readFileSync(`${UI_FORMS_PATH}${file}`)); if (isFromAlreadyMigrated(json, migrationList.offsets)) { // eslint-disable-next-line no-console console.log(`${message.alreadyMigrated} ${file}`); return; } const currentMigrationInfo = json.state.migrationInfo || []; const migrationSet = new Set([...currentMigrationInfo, migrationList.offsets]); const updatedJSON = { ...json, state: { ...json.state, migrationInfo: [...migrationSet] }, elements: json.elements.map(updateBuilderSectionElement), json: { ...json.json, elements: json.json.elements.map(updateProductSectionElement) } }; if (Object.keys(updatedJSON).length) { fs.writeFileSync(`${UI_FORMS_PATH}${file}`, JSON.stringify(updatedJSON, null, 2), { encoding: 'utf-8' }); // eslint-disable-next-line no-console console.log(`${message.updated} ${file}`); } }); // eslint-disable-next-line no-console console.log(message.donePatchOffsets); resolve(); }); }; return replaceCssClassesWithOffsetsFunc; }; const replaceCssClassesWithOffsets = createReplaceCssClassesWithOffsets((customCssClasses, filterFunction) => customCssClasses && filterFunction(customCssClasses)); const replaceCssClassesWithOffsetsAndSaveCssClasses = createReplaceCssClassesWithOffsets((customCssClasses, filterFunction) => customCssClasses && customCssClasses); module.exports = { replaceCssClassesWithOffsets, replaceCssClassesWithOffsetsAndSaveCssClasses };