import { Command } from 'commander'; import path from 'path'; import fs from 'fs'; import { stringify } from 'yaml'; import { generateAssociation, normalizeName, PUSHER_POSTFIX, searchConnection, searchTask, setVariable, } from '../../helpers/profileGeneratorHelper'; import { pusherYaml } from '../../components/pusherTemplate'; import { v4 } from 'uuid'; import { getProjectPath } from '../../helpers/cluserHelper'; import inquirer from 'inquirer'; import { mergeVariables } from '../../helpers/variablesHelper'; export function GeneratePusherCommand(): Command { const cmd = new Command('generate') .alias('g') .description('Generates a HexaSync Pusher') .option( '-t, --task-name ', 'Search for name of the task, e.g.: product', ) .option( '-c, --connection-name ', 'Search for related connection, e.g.: shopify', ) .action(async ({ taskName, connectionName }) => { var projectComponentPath = getProjectPath(); if (!fs.existsSync(path.join(projectComponentPath, 'pushers'))) { fs.mkdirSync(path.join(projectComponentPath, 'pushers'), { recursive: true, }); } var taskYml = await searchTask(taskName); if (!taskYml) { console.error(`There is no such task ${taskName}`); return; } var connectionYml = (await searchConnection(connectionName)) as any; if (!connectionYml) { console.error(`There is no such connection ${connectionName}`); return; } const connectionNormalizedName = normalizeName(connectionYml.__real_name); const taskFullNameValue = taskYml.__real_name; const taskNameValue = taskFullNameValue .replace(/\s*\[([^\]]+)\]\s*/g, '') .replace(/\s*\(([^\)]+)\)\s*/g, '') .replaceAll(' Task', ''); const fromConnection = ( taskFullNameValue?.match(/\s*\[([^\]]+)\]\s*/g) || [] ) .map((e: string) => e.replace(/\s*\[([^\]]+)\]\s*/g, '$1'))[0] ?.split(/\s*\>\s*/)[0]; const taskNormalizedName = normalizeName(taskNameValue); const replacedTaskName = !!fromConnection ? `[${fromConnection} > ${connectionNormalizedName.displayName}] ${taskNormalizedName.displayName}` : `[HexaSync > ${connectionNormalizedName.displayName}] ${taskNormalizedName.displayName}`; console.log(`Would you like to name the pusher?`); const answer = await inquirer.prompt<{ value: string }>([ { type: 'input', name: 'value', message: `Answer (default ${taskNormalizedName.displayName}):`, }, ]); const pusherName = answer.value || taskNormalizedName.displayName; const pusherNormalizedName = normalizeName(pusherName); var variables = [ { field: 'id', key: `**${connectionNormalizedName.camelCaseName}_${pusherNormalizedName.camelCaseName}_${PUSHER_POSTFIX}_Id**`, value: v4(), }, { field: 'name', key: `**${connectionNormalizedName.camelCaseName}_${pusherNormalizedName.camelCaseName}_${PUSHER_POSTFIX}_Name**`, value: `[${connectionNormalizedName.displayName}] ${pusherNormalizedName.displayName} ${PUSHER_POSTFIX}`, }, ]; let yml = pusherYaml(); for (var i = 0; i < variables.length; i++) { var variable = variables[i]; yml = yml.replaceAll( `||VARIABLE_KEY_${variable.field}||`, variable.key, ); } yml = yml.replaceAll(`||VARIABLE_KEY_connectorId||`, connectionYml.id); const componentPath = getProjectPath(); const pusherFilePath = path.join( componentPath, 'pushers', `${connectionNormalizedName.camelCaseName}_${pusherNormalizedName.camelCaseName}_${PUSHER_POSTFIX}.yaml`, ); const association = generateAssociation(taskYml.id, null, null, { id: `**${connectionNormalizedName.camelCaseName}_${pusherNormalizedName.camelCaseName}_${PUSHER_POSTFIX}_Id**`, }); if (fs.existsSync(pusherFilePath)) { console.error(`There is a pusher already at ${pusherFilePath}`); return; } mergeVariables(variables); setVariable(taskYml.name, replacedTaskName); fs.writeFileSync( association.filePath, stringify(association.config, { keepSourceTokens: true, lineWidth: 0 }), ); fs.writeFileSync(pusherFilePath, yml); console.log(`Done. Remember to edit the pusher's steps to fit your business requirements`); }); return cmd; }