import { Command } from 'commander'; import { parse, stringify } from 'yaml'; import fs from 'fs'; import path from 'path'; import { v4 } from 'uuid'; import { getProjectPath } from '../../helpers/cluserHelper'; import { ID_POSTFIX, NAME_POSTFIX, normalizeName, PULLER_POSTFIX, searchConnection, TABLE_POSTFIX, } from '../../helpers/profileGeneratorHelper'; import { pullerYaml } from '../../components/pullerTemplate'; import { mergeVariables, readVariableValue, } from '../../helpers/variablesHelper'; function generatePullerConfig( connectionId: string, connectionName: string, pullerName: string, options: { useTimeBased: boolean; }, ): { fileName: string; config: any; variables: Array<{ key: string; value: any }>; } { const normalizedConnectionName = normalizeName(connectionName); const normalizedPullerName = normalizeName(pullerName); const keyPrefix = `${normalizedConnectionName.camelCaseName}_${normalizedPullerName.camelCaseName}`.replace( /[^a-zA-Z0-9]/g, '_', ); var variables = [ { field: 'id', key: `**${keyPrefix}_${PULLER_POSTFIX}_${ID_POSTFIX}**`, value: v4(), }, { field: 'name', key: `**${keyPrefix}_${PULLER_POSTFIX}_${NAME_POSTFIX}**`, value: `[${normalizedConnectionName.displayName}] ${normalizedPullerName.displayName} ${PULLER_POSTFIX}`, }, { field: 'useTimeBased', key: `**${keyPrefix}_UseTimeBased**`, value: options.useTimeBased ? 1 : 0, }, ]; // TODO: support SQL Puller as well let yml = pullerYaml(); for (var i = 0; i < variables.length; i++) { var variable = variables[i]; yml = yml.replaceAll(`||VARIABLE_KEY_${variable.field}||`, variable.key); } // Note: Puller Object/Task, and Table should have same Name with different postfix yml = yml.replaceAll( `||VARIABLE_KEY_objectTable||`, `**${keyPrefix}_${TABLE_POSTFIX}_${NAME_POSTFIX}**`, ); yml = yml.replaceAll( `||VARIABLE_KEY_connectorId||`, connectionId.replaceAll('"', ''), ); return { fileName: `${keyPrefix}_${PULLER_POSTFIX}`, variables, config: parse(yml), }; } export function GeneratePullerCommand(): Command { const cmd = new Command('generate') .alias('g') .description('Generates a HexaSync Puller') .option('-c, --connection-name ', 'Search connection by name') .option('-n, --name ', 'Name of the puller (also the mandator task)') .option( '-ts, --use-time-based ', 'Name of the puller (also the mandator task)', ) .action(async ({ connectionName, name, useTimeBased }) => { console.log('Generating a HexaSync Puller'); var projectComponentPath = getProjectPath(); if (!fs.existsSync(path.join(projectComponentPath, 'pullers'))) { fs.mkdirSync(path.join(projectComponentPath, 'pullers'), { recursive: true, }); } const connection = await searchConnection(connectionName); if (!connection) { console.error(`There is no such connection ${connectionName}`); return; } const connectionDisplayName = readVariableValue( connection.name, ) as string; const pullerConfig = generatePullerConfig( connection.id, connectionDisplayName, name, { useTimeBased: !!useTimeBased, }, ); const componentPath = getProjectPath(); const pullerPath = path.join(componentPath, 'pullers'); const pullerFilePath = path.join( pullerPath, `${pullerConfig.fileName}.yaml`, ); if (!fs.existsSync(pullerPath)) { fs.mkdirSync(pullerPath); } if (fs.existsSync(pullerFilePath)) { console.error(`A puller ${pullerConfig.fileName} is already exists.`); return; } mergeVariables(pullerConfig.variables); fs.writeFileSync( pullerFilePath, stringify(pullerConfig.config, { keepSourceTokens: true, lineWidth: 0, }), ); }); return cmd; }