96 lines
2.3 KiB
TypeScript

import { execa } from "execa";
import PQueue from "p-queue";
// Configure the queue with a concurrency limit
const scriptQueue = new PQueue({ concurrency: 5 });
export type ScriptParams = {
scriptPath: string;
args?: string[];
onProgress?: (data: string) => void;
};
export type ScriptResult = {
success: boolean;
stdout: string;
stderr: string;
error?: string;
};
/**
* Executes a bash script with queue management
*/
export async function executeScript(
params: ScriptParams,
): Promise<ScriptResult> {
// Add the script execution to the queue
// hardcoded the allowed script path for security reasons
var allowedScriptPaths = [
"/tmp/api_scripts/hello_test.sh",
"/tmp/api_scripts/video_add_watermark.sh",
];
if (!allowedScriptPaths.includes(params.scriptPath)) {
return {
success: false,
stdout: "",
stderr: "",
error: "Script path is not allowed",
};
}
const result = await scriptQueue.add(async () => {
try {
// Execute the bash script
const { stdout, stderr } = await execa(
"bash",
[params.scriptPath, ...(params.args || [])],
{
buffer: true, // Changed to true to ensure we get the complete output
},
);
// If onProgress is provided, we can use it to stream script output
if (params.onProgress && stdout) {
params.onProgress(stdout.toString());
}
return {
success: true,
stdout: stdout ? stdout.toString() : "",
stderr: stderr ? stderr.toString() : "",
};
} catch (error: any) {
// Handle script execution errors
return {
success: false,
stdout: error.stdout ? error.stdout.toString() : "",
stderr: error.stderr ? error.stderr.toString() : "",
error: error.message || "Failed to execute script",
};
}
});
return result as ScriptResult;
}
// Get current queue size and pending tasks
export function getQueueStats() {
return {
size: scriptQueue.size,
pending: scriptQueue.pending,
isPaused: scriptQueue.isPaused,
};
}
// Pause the queue (no further tasks will be executed until resumed)
export function pauseQueue() {
scriptQueue.pause();
}
// Resume the queue
export function resumeQueue() {
scriptQueue.start();
}