import { Command } from 'commander'; import path from 'path'; import fs from 'fs'; import { globSync } from 'glob'; import { includeTask } from './includeFiles/includeTask'; import { includeConnection } from './includeFiles/includeConnection'; import { includeReport } from './includeFiles/includeReport'; import { includeSchema } from './includeFiles/includeSchema'; import { includePusher } from './includeFiles/includePusher'; import { includeDependency } from './includeFiles/includeDependency'; import { includeTransformation } from './includeFiles/includeTransformation'; import { includeValidation } from './includeFiles/includeValidation'; import { importCommon } from './includeFiles/importCommonFiles'; import { getProjectPath } from '../../helpers/cluserHelper'; async function overrideEntities( folder: string, { type, name }: { type?: string; name?: string }, ) { folder = path.resolve(folder); if (!name || !name.trim()) { console.error(`Please provide a component name via -n/--name.`); return; } const variablePaths = globSync(path.join(folder, `**/variables.yaml`), { windowsPathsNoEscape: true, }) || []; if (!variablePaths.length) { console.error( `Please choose a folder path that contains the variables.yaml file, e.g.: ~/workspaces/shopify/partials`, ); return; } // SOURCE root = folder containing variables.yaml (same rule as include) const sourceRoot = path.dirname(variablePaths[0]); // TARGET root = current profile path const targetRoot = getProjectPath(); let components: { filePaths: string[]; associations: any | null; } | null = null; type = (type || '').trim().toLowerCase(); switch (type) { case 'task': components = await includeTask(sourceRoot, name); break; case 'connection': components = await includeConnection(sourceRoot, name); break; case 'pusher': components = await includePusher(sourceRoot, name); break; case 'dependency': components = await includeDependency(sourceRoot, name); break; case 'transformation': components = await includeTransformation(sourceRoot, name); break; case 'validation': components = await includeValidation(sourceRoot, name); break; case 'report': components = await includeReport(sourceRoot, name); break; case 'schema': components = await includeSchema(sourceRoot, name); break; default: components = await importCommon(sourceRoot, name); break; } if (!components?.filePaths?.length) return; for (const srcPath of components.filePaths) { // Keep relative structure identical between source and target const rel = path.relative(sourceRoot, srcPath); const ext = path.extname(rel) || '.yaml'; const base = path.basename(rel, ext); const relDir = path.dirname(rel); const dstDir = path.join(targetRoot, relDir); if (!fs.existsSync(dstDir)) fs.mkdirSync(dstDir, { recursive: true }); const dstPath = path.join(dstDir, `${base}.override${ext}`); if (fs.existsSync(dstPath)) { console.log(`Skip (already exists): ${dstPath}`); continue; } fs.copyFileSync(srcPath, dstPath); console.log(`Created: ${dstPath}`); } } export function OverrideCommand(): Command { const cmd = new Command('override') .alias('o') .description('Create .override.yaml files for selected profile components.') .argument('folder', 'Path to the source project/components') .option( '-t, --type ', 'Type of the entity to be overridden (same as include), e.g.: connection, task, puller, pusher, dependency, report, webhook, validation, transformation, mapping, ', ) .option( '-n, --name ', 'Search components by name, e.g.: product, sales order, customer', ) .action(overrideEntities); return cmd; }