import chalk from 'chalk'; import { Command } from 'commander'; import { findEntityById, findEntityByIdOrName, toFriendlyName, getEntityIndexInfo, } from '../../helpers/entityHelper'; import { getAssociation } from '../../helpers/profileGeneratorHelper'; import { getVariables, readVariableKey, readVariableValue, } from '../../helpers/variablesHelper'; import { IEntitySearchResult } from '../../helpers/@types/IEntitySearchResult'; import path from 'path'; import { getGlobalConfig } from '../../helpers/cluserHelper'; import fs from 'fs'; import { parse } from 'yaml'; import { Dictionary } from 'tsyringe/dist/typings/types'; export async function showTaskFiles(id?: string, name?: string) { if (!id && !name) { console.error( `${chalk.red('✗')} Option ${chalk.green('id')} or ${chalk.green('name')} is ${chalk.red('required')}`, ); return; } var searchedTask = await findEntityByIdOrName(id!, name, 'task'); if (!searchedTask) { return; } var variables = getVariables(); var foundEntities: IEntitySearchResult[] = [searchedTask]; var associations = getAssociation(); var taskAssociation = associations.objectAssociations[readVariableKey(searchedTask.entityId)] || {}; var pullerId = taskAssociation?.puller?.id || searchedTask.content?.puller?.id; if (!!pullerId) { var searchedPuller = await findEntityById(pullerId, 'puller', false); if (!!searchedPuller) { foundEntities.push(searchedPuller); } } var pusherId = taskAssociation?.pusher?.id || searchedTask.content?.pusher?.id; if (!!pusherId) { var searchedPusher = await findEntityById(pusherId, 'pusher', false); if (!!searchedPusher) { foundEntities.push(searchedPusher); } } var tableId = taskAssociation?.table?.id; if (!!tableId) { var searchedTable = await findEntityById(tableId, 'table', false); if (!!searchedTable) { foundEntities.push(searchedTable); } } console.log('\n'); // Transformations is a dictionary // Validations is a dictionary // Dependencies is array of Dependency (objectId) // Print detailed information foundEntities.forEach((e, index) => { const entityType = e.entityType .replace(/[^a-zA-Z0-9 ]/g, ' ') .replace(/\b\w/g, (l) => l.toUpperCase()); const originalPath = path.resolve(e.filePath); // Split entityName into parts: [] and const entityName = !!e.entityName ? readVariableValue(e.entityName, '', variables)?.toString() || '' : readVariableValue(e.entityId, '', variables)?.toString() || ''; // Extract and format [] parts const formattedName = toFriendlyName(entityName); var formattedId = !!e.entityName ? readVariableValue(e.entityId, '', variables) : readVariableKey(e.entityId, '', variables); console.log( `${index + 1}. ${chalk.green(entityType.toUpperCase())}: ${formattedName} (${chalk.gray(formattedId)})`, ); console.log(` - Original Path: ${chalk.gray(originalPath)}`); if (!!e.override?.filePath) { const overridePath = path.resolve(e.override.filePath); console.log(` - Overrided Path: ${chalk.magenta(overridePath)}`); } if (e.entityType === 'task') { console.log( ` - ${'Table Name'}: ${chalk.green(readVariableValue(e.content?.valueTableName))} (${chalk.gray(readVariableKey(e.content?.valueTableName))})`, ); if (!!e.content?.puller?.mappings) { console.log(` - File Type: ${chalk.red('LEGACY')}`); if (!!e.content?.puller?.mappings) { { console.log(` - ${chalk.red('Has inline Puller Mappings')}`); } } if (!!e.content?.dependencies) { console.log(` - ${chalk.red('Has inline Dependencies')}`); } } } console.log('\r'); }); var cfg = getGlobalConfig(); var tasksRelations = parse(fs.readFileSync(cfg.taskRelationsCachesPath, 'utf8')) || {}; var taskRelations = tasksRelations[readVariableKey(searchedTask.entityId)] || []; // group taskRelations by entityType and console the result as a dictionary which key is an entityType var groupedTaskRelations: Dictionary = {}; for (const relation of taskRelations) { if (!groupedTaskRelations[relation.entityType]) { groupedTaskRelations[relation.entityType] = []; } groupedTaskRelations[relation.entityType].push(relation); } var startIndex = foundEntities.length + 1; for (const [entityType, relations] of Object.entries(groupedTaskRelations)) { console.log( `${startIndex++}. ${chalk.green(entityType.toUpperCase())}: ${chalk.gray(`${relations.length} ${entityType.toLowerCase()}`)}`, ); // Group relations by their entityId to handle overrides together const groupedByEntityId = relations.reduce( (acc, relation) => { const key = relation.entityId || relation.entityName || relation.filePath; // Updated to include entityName as fallback if (!acc[key]) acc[key] = []; acc[key].push(relation); return acc; }, {} as Record, ); for (const [entityId, groupedRelations] of Object.entries( groupedByEntityId, )) { const mainRelation = groupedRelations.find( (r) => !r.filePath.endsWith('.override.yaml'), ); const overrideRelations = groupedRelations.filter((r) => r.filePath.endsWith('.override.yaml'), ); if (mainRelation) { const entityName = !!mainRelation.entityName ? readVariableValue( mainRelation.entityName, '', variables, )?.toString() || '' : readVariableValue( mainRelation.entityId, '', variables, )?.toString() || ''; const formattedName = toFriendlyName(entityName); const formattedId = !!mainRelation.entityName ? readVariableValue(mainRelation.entityId, '', variables) : readVariableKey(mainRelation.entityId, '', variables); console.log(` - ${formattedName}: ${chalk.gray(formattedId)}`); console.log(` Path: ${chalk.gray(mainRelation.filePath)}`); const indexInfo = getEntityIndexInfo( mainRelation, entityType, variables, ); if (indexInfo !== null) { const location = indexInfo.lineNumber !== null ? `${indexInfo.definedAt}:${indexInfo.lineNumber}` : indexInfo.definedAt; console.log( ` Index: ${chalk.cyan(indexInfo.indexValue)} (Defined at: ${chalk.gray(location)})`, ); } } // Log override paths for (const override of overrideRelations) { console.log(` Override Path: ${chalk.magenta(override.filePath)}`); } } console.log('\r'); } } export function TaskFilesCommand(): Command { const cmd = new Command('files'); cmd .alias('f') .description('Find related files of a Task.') .option('-i, --id ', 'Search the task by id') .option('-n, --name ', 'Search the task by name') .action(async ({ id, name }: { id?: string; name?: string }) => { await showTaskFiles(id, name); }); return cmd; }