181 lines
4.9 KiB
JavaScript
181 lines
4.9 KiB
JavaScript
const readline = require('readline');
|
|
|
|
const rl = readline.createInterface({
|
|
input: process.stdin,
|
|
output: process.stdout
|
|
});
|
|
|
|
const question = (query) => new Promise((resolve) => rl.question(query, resolve));
|
|
|
|
async function loadScript(name) {
|
|
try {
|
|
return await require(name);
|
|
} catch (error) {
|
|
console.error(`Failed to load script ${name}:`, error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
async function runWithTimeout(fn) {
|
|
return new Promise((resolve, reject) => {
|
|
// Create a child process for the script
|
|
const child = require('child_process').fork(fn.toString(), [], {
|
|
stdio: 'inherit'
|
|
});
|
|
|
|
child.on('exit', (code) => {
|
|
if (code === 0) {
|
|
resolve();
|
|
} else {
|
|
reject(new Error(`Script exited with code ${code}`));
|
|
}
|
|
});
|
|
|
|
child.on('error', (err) => {
|
|
reject(err);
|
|
});
|
|
});
|
|
}
|
|
|
|
function clearScreen() {
|
|
process.stdout.write('\x1Bc');
|
|
}
|
|
|
|
const scripts = {
|
|
'Import Scripts': {
|
|
'1': { name: 'Full Import From Production', path: './import-from-prod' },
|
|
'2': { name: 'Individual Import Scripts ▸', submenu: {
|
|
'1': { name: 'Import Orders', path: './import/orders', key: 'importOrders' },
|
|
'2': { name: 'Import Products', path: './import/products', key: 'importProducts' },
|
|
'3': { name: 'Import Purchase Orders', path: './import/purchase-orders' },
|
|
'4': { name: 'Import Categories', path: './import/categories' },
|
|
'b': { name: 'Back to Main Menu' }
|
|
}}
|
|
},
|
|
'Metrics': {
|
|
'3': { name: 'Calculate All Metrics', path: './calculate-metrics' },
|
|
'4': { name: 'Individual Metric Scripts ▸', submenu: {
|
|
'1': { name: 'Brand Metrics', path: './metrics/brand-metrics' },
|
|
'2': { name: 'Category Metrics', path: './metrics/category-metrics' },
|
|
'3': { name: 'Financial Metrics', path: './metrics/financial-metrics' },
|
|
'4': { name: 'Product Metrics', path: './metrics/product-metrics' },
|
|
'5': { name: 'Sales Forecasts', path: './metrics/sales-forecasts' },
|
|
'6': { name: 'Time Aggregates', path: './metrics/time-aggregates' },
|
|
'7': { name: 'Vendor Metrics', path: './metrics/vendor-metrics' },
|
|
'b': { name: 'Back to Main Menu' }
|
|
}}
|
|
},
|
|
'Database Management': {
|
|
'5': { name: 'Test Production Connection', path: './test-prod-connection' }
|
|
},
|
|
'Reset Scripts': {
|
|
'6': { name: 'Reset Database', path: './reset-db' },
|
|
'7': { name: 'Reset Metrics', path: './reset-metrics' }
|
|
}
|
|
};
|
|
|
|
let lastRun = null;
|
|
|
|
async function displayMenu(menuItems, title = 'Inventory Management Script Runner') {
|
|
clearScreen();
|
|
console.log(`\n${title}\n`);
|
|
|
|
for (const [category, items] of Object.entries(menuItems)) {
|
|
console.log(`\n${category}:`);
|
|
Object.entries(items).forEach(([key, script]) => {
|
|
console.log(`${key}. ${script.name}`);
|
|
});
|
|
}
|
|
|
|
if (lastRun) {
|
|
console.log('\nQuick Access:');
|
|
console.log(`r. Repeat Last Script (${lastRun.name})`);
|
|
}
|
|
|
|
console.log('\nq. Quit\n');
|
|
}
|
|
|
|
async function handleSubmenu(submenu, title) {
|
|
while (true) {
|
|
await displayMenu({"Individual Scripts": submenu}, title);
|
|
const choice = await question('Select an option (or b to go back): ');
|
|
|
|
if (choice.toLowerCase() === 'b') {
|
|
return null;
|
|
}
|
|
|
|
if (submenu[choice]) {
|
|
return submenu[choice];
|
|
}
|
|
|
|
console.log('Invalid selection. Please try again.');
|
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
}
|
|
}
|
|
|
|
async function runScript(script) {
|
|
console.log(`\nRunning: ${script.name}`);
|
|
try {
|
|
const scriptPath = require.resolve(script.path);
|
|
await runWithTimeout(scriptPath);
|
|
console.log('\nScript completed successfully');
|
|
lastRun = script;
|
|
} catch (error) {
|
|
console.error('\nError running script:', error);
|
|
}
|
|
await question('\nPress Enter to continue...');
|
|
}
|
|
|
|
async function main() {
|
|
while (true) {
|
|
await displayMenu(scripts);
|
|
|
|
const choice = await question('Select an option: ');
|
|
|
|
if (choice.toLowerCase() === 'q') {
|
|
break;
|
|
}
|
|
|
|
if (choice.toLowerCase() === 'r' && lastRun) {
|
|
await runScript(lastRun);
|
|
continue;
|
|
}
|
|
|
|
let selectedScript = null;
|
|
for (const category of Object.values(scripts)) {
|
|
if (category[choice]) {
|
|
selectedScript = category[choice];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!selectedScript) {
|
|
console.log('Invalid selection. Please try again.');
|
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
continue;
|
|
}
|
|
|
|
if (selectedScript.submenu) {
|
|
const submenuChoice = await handleSubmenu(
|
|
selectedScript.submenu,
|
|
selectedScript.name
|
|
);
|
|
if (submenuChoice && submenuChoice.path) {
|
|
await runScript(submenuChoice);
|
|
}
|
|
} else if (selectedScript.path) {
|
|
await runScript(selectedScript);
|
|
}
|
|
}
|
|
|
|
rl.close();
|
|
process.exit(0);
|
|
}
|
|
|
|
if (require.main === module) {
|
|
main().catch(error => {
|
|
console.error('Fatal error:', error);
|
|
process.exit(1);
|
|
});
|
|
}
|