( content: string, args: string | undefined, appendIfNoPlaceholder = true, argumentNames: string[] = [], )
| 92 | * @returns The content with placeholders substituted |
| 93 | */ |
| 94 | export function substituteArguments( |
| 95 | content: string, |
| 96 | args: string | undefined, |
| 97 | appendIfNoPlaceholder = true, |
| 98 | argumentNames: string[] = [], |
| 99 | ): string { |
| 100 | // undefined/null means no args provided - return content unchanged |
| 101 | // empty string is a valid input that should replace placeholders with empty |
| 102 | if (args === undefined || args === null) { |
| 103 | return content |
| 104 | } |
| 105 | |
| 106 | const parsedArgs = parseArguments(args) |
| 107 | const originalContent = content |
| 108 | |
| 109 | // Replace named arguments (e.g., $foo, $bar) with their values |
| 110 | // Named arguments map to positions: argumentNames[0] -> parsedArgs[0], etc. |
| 111 | for (let i = 0; i < argumentNames.length; i++) { |
| 112 | const name = argumentNames[i] |
| 113 | if (!name) continue |
| 114 | |
| 115 | // Match $name but not $name[...] or $nameXxx (word chars) |
| 116 | // Also ensure we match word boundaries to avoid partial matches |
| 117 | content = content.replace( |
| 118 | new RegExp(`\\$${name}(?![\\[\\w])`, 'g'), |
| 119 | parsedArgs[i] ?? '', |
| 120 | ) |
| 121 | } |
| 122 | |
| 123 | // Replace indexed arguments ($ARGUMENTS[0], $ARGUMENTS[1], etc.) |
| 124 | content = content.replace(/\$ARGUMENTS\[(\d+)\]/g, (_, indexStr: string) => { |
| 125 | const index = parseInt(indexStr, 10) |
| 126 | return parsedArgs[index] ?? '' |
| 127 | }) |
| 128 | |
| 129 | // Replace shorthand indexed arguments ($0, $1, etc.) |
| 130 | content = content.replace(/\$(\d+)(?!\w)/g, (_, indexStr: string) => { |
| 131 | const index = parseInt(indexStr, 10) |
| 132 | return parsedArgs[index] ?? '' |
| 133 | }) |
| 134 | |
| 135 | // Replace $ARGUMENTS with the full arguments string |
| 136 | content = content.replaceAll('$ARGUMENTS', args) |
| 137 | |
| 138 | // If no placeholders were found and appendIfNoPlaceholder is true, append |
| 139 | // But only if args is non-empty (empty string means command invoked with no args) |
| 140 | if (content === originalContent && appendIfNoPlaceholder && args) { |
| 141 | content = content + `\n\nARGUMENTS: ${args}` |
| 142 | } |
| 143 | |
| 144 | return content |
| 145 | } |
| 146 |
no test coverage detected