fix: wrap shell operators in sh -c for sprites-exec v0.1.5

Commands containing shell operators (&&, ||, |, ;, >, etc.) were being
parsed incorrectly, causing errors like "The update command takes no
arguments". Now detects shell operators and wraps the entire command
in `sh -c "..."` for proper execution.
This commit is contained in:
Ajax Davis 2026-01-15 03:57:40 +10:00
parent a548edc0db
commit e6857e245e
2 changed files with 47 additions and 1 deletions

View file

@ -1,6 +1,6 @@
{
"name": "@tpmjs/tools-sprites-exec",
"version": "0.1.4",
"version": "0.1.5",
"description": "Execute a command inside a sprite and return the output with exit code",
"type": "module",
"keywords": [

View file

@ -40,11 +40,57 @@ function getSpritesToken(): string {
return token;
}
/**
* Shell operators that require wrapping the command in sh -c
*/
const SHELL_OPERATORS = ['&&', '||', '|', ';', '>', '>>', '<', '<<', '2>', '2>>', '&>', '$(', '`'];
/**
* Check if a command string contains shell operators that need sh -c wrapping
*/
function needsShellWrapper(cmdString: string): boolean {
// Check for shell operators outside of quotes
let inSingleQuote = false;
let inDoubleQuote = false;
for (let i = 0; i < cmdString.length; i++) {
const char = cmdString[i];
if (char === "'" && !inDoubleQuote) {
inSingleQuote = !inSingleQuote;
continue;
}
if (char === '"' && !inSingleQuote) {
inDoubleQuote = !inDoubleQuote;
continue;
}
// Only check for operators when not inside quotes
if (!inSingleQuote && !inDoubleQuote) {
for (const op of SHELL_OPERATORS) {
if (cmdString.slice(i, i + op.length) === op) {
return true;
}
}
}
}
return false;
}
/**
* Parse a command string into command and arguments.
* Handles quoted strings and escapes.
* If the command contains shell operators (&&, ||, |, ;, etc.),
* wraps it in sh -c to execute properly.
*/
function parseCommand(cmdString: string): string[] {
// If command contains shell operators, wrap in sh -c
if (needsShellWrapper(cmdString)) {
return ['sh', '-c', cmdString];
}
const args: string[] = [];
let current = '';
let inSingleQuote = false;