import { Command } from 'commander'; import path from 'path'; import fs from 'fs'; import { parse, stringify } from 'yaml'; import { v4 } from 'uuid'; import { normalizeName, searchTask, } from '../../../../helpers/profileGeneratorHelper'; import { transformationTypesTemplate, transformationYaml, } from '../../../../components/transformationTemplate'; import inquirer from 'inquirer'; import { paddingList } from '../../../../helpers/paddingList'; import { getProjectPath } from '../../../../helpers/cluserHelper'; import { mergeVariables, readVariableValue, } from '../../../../helpers/variablesHelper'; import { findEntityByIdOrName } from '../../../../helpers/entityHelper'; export function GenerateTransformationCommand(): Command { const cmd = new Command('generate') .alias('g') .description('Generates a HexaSync Transformation') .option( '-t, --task-name ', 'Search for name of the task, e.g.: product', ) .option( '-c, --category ', "Define the category of the transformation, e.g.: product, 'sales order'", ) .option( '-n, --transformation-name ', "Define the name of the transformation, e.g.: product, 'calculate product price'", ) .action(async ({ taskName, category, transformationName }) => { const taskYml = await findEntityByIdOrName('', taskName, 'task'); if (!taskYml) { console.error( `There is no such task ${taskName}, generating a dummy transformation`, ); } const normalizedCategoryName = normalizeName(category); const componentPath = getProjectPath(); const categoryPath = path.join( componentPath, 'transformations', normalizedCategoryName.dashedSlug, ); if (!fs.existsSync(categoryPath)) { fs.mkdirSync(categoryPath, { recursive: true }); } const realTaskName = taskYml?.entityName ? readVariableValue(taskYml?.entityName) : ''; const taskHeader = typeof realTaskName === 'string' ? realTaskName.replace(/\[([^\]]+)\]/g, '$1') : ''; const normalizedTaskHeader = taskYml?.entityName ? normalizeName(taskHeader) : null; const normalizedTransformationName = normalizeName(transformationName); const variableKey = normalizedTaskHeader ? `${normalizedTaskHeader.camelCaseName}_${normalizedTransformationName.camelCaseName}_Transformation` : `${normalizedTransformationName.camelCaseName}_Transformation`; const transformationTypes = transformationTypesTemplate(); const transformationTypeChoices = transformationTypes.map((t) => t.type); const answer = await inquirer.prompt<{ type: string; index: string }>([ { type: 'list', name: 'type', message: 'Please choose one type of transformation:', choices: transformationTypeChoices, }, { type: 'input', name: 'index', message: 'Please enter transformation index:', default: '0', validate: (input: string) => { if (/^\d+$/.test(input)) { return true; } return 'Index must be a valid integer. Please enter again.'; }, }, ]); const index = Number(answer.index) || 0; var variables = [ { field: 'id', key: `**${variableKey}_Id**`, value: v4(), }, { field: 'index', key: `**${variableKey}_Index**`, value: index, }, { field: 'name', key: `**${variableKey}_Name**`, value: normalizedTaskHeader ? `[${normalizedTaskHeader.displayName}] ${normalizedTransformationName.displayName} Transformation` : `${normalizedTransformationName.displayName} Transformation`, }, ]; let yml = transformationYaml(); for (var i = 0; i < variables.length; i++) { var variable = variables[i]; yml = yml.replaceAll( `||VARIABLE_KEY_${variable.field}||`, variable.key, ); } const transformationType = transformationTypes.find( (t) => t.type === answer.type, ); const metadata = transformationType?.metadataSample as any; switch (transformationType?.type) { case 'SQL': case 'Nested_SQL': metadata.sql = taskYml?.content?.valueTableName ? metadata.sql.replaceAll( '__hss_the_current_task_table', taskYml.content.valueTableName, ) : metadata.sql.replaceAll( '__hss_the_current_task_table', '', ); break; default: break; } const config = parse(yml); config.metadata = metadata; config.type = transformationType?.type; const filePath = path.join(categoryPath, `${variableKey}.yaml`); fs.writeFileSync( filePath, stringify( { transformations: { ...{ [taskYml?.content?.id || taskYml?.entityId || '']: [config], }, }, }, { keepSourceTokens: true, lineWidth: 0 }, ), ); mergeVariables(variables); }); return cmd; }