Execute all approved operations (mock: instant success unless configured otherwise).
(options?: ExecuteOptions)
| 256 | |
| 257 | /** Execute all approved operations (mock: instant success unless configured otherwise). */ |
| 258 | executeOperations(options?: ExecuteOptions): ExecuteResult { |
| 259 | const results: Array<{ id: string; result: OperationResult }> = [] |
| 260 | const approved = this.state.operations.filter(op => op.status === 'approved') |
| 261 | |
| 262 | // Sort by dependencies |
| 263 | const sorted = this.sortByDependencies(approved) |
| 264 | |
| 265 | for (const op of sorted) { |
| 266 | // Check if dependent operation completed successfully |
| 267 | if (op.dependsOn) { |
| 268 | const dep = this.state.operations.find(d => d.id === op.dependsOn) |
| 269 | if (!dep || dep.status !== 'completed') { |
| 270 | // Skip - dependency not met |
| 271 | continue |
| 272 | } |
| 273 | } |
| 274 | |
| 275 | op.status = 'running' |
| 276 | |
| 277 | // Check for configured result |
| 278 | const configuredResult = options?.results?.[op.id] |
| 279 | if (configuredResult) { |
| 280 | const result: OperationResult = { |
| 281 | stdout: configuredResult.stdout ?? '', |
| 282 | stderr: configuredResult.stderr ?? '', |
| 283 | exitCode: configuredResult.exitCode ?? 1, |
| 284 | requiresOtp: configuredResult.requiresOtp, |
| 285 | authFailure: configuredResult.authFailure, |
| 286 | urls: configuredResult.urls, |
| 287 | } |
| 288 | op.result = result |
| 289 | op.status = result.exitCode === 0 ? 'completed' : 'failed' |
| 290 | results.push({ id: op.id, result }) |
| 291 | |
| 292 | if (result.requiresOtp && !options?.otp) { |
| 293 | return { results, otpRequired: true } |
| 294 | } |
| 295 | } else { |
| 296 | // Default: success |
| 297 | const result: OperationResult = { |
| 298 | stdout: `Mock: ${op.command}`, |
| 299 | stderr: '', |
| 300 | exitCode: 0, |
| 301 | } |
| 302 | op.result = result |
| 303 | op.status = 'completed' |
| 304 | results.push({ id: op.id, result }) |
| 305 | |
| 306 | // Apply the operation's effects to mock state |
| 307 | this.applyOperationEffect(op) |
| 308 | } |
| 309 | } |
| 310 | |
| 311 | const authFailure = results.some(r => r.result.authFailure) |
| 312 | const allUrls = results.flatMap(r => r.result.urls ?? []) |
| 313 | const urls = [...new Set(allUrls)] |
| 314 | |
| 315 | return { |
no test coverage detected