| 362 | */ |
| 363 | // fallow-ignore-next-line complexity |
| 364 | export function parseBatchFile(path: string): Array<{ entry: BatchEntry; lineNumber: number }> { |
| 365 | const raw = readFileSync(path, "utf8"); |
| 366 | const lines = raw.split(/\r?\n/); |
| 367 | const out: Array<{ entry: BatchEntry; lineNumber: number }> = []; |
| 368 | for (let i = 0; i < lines.length; i++) { |
| 369 | const line = lines[i]!.trim(); |
| 370 | if (line === "") continue; |
| 371 | let parsed: unknown; |
| 372 | try { |
| 373 | parsed = JSON.parse(line); |
| 374 | } catch (err) { |
| 375 | errorBox(`Invalid JSON in batch file on line ${i + 1}`, normalizeErrorMessage(err)); |
| 376 | process.exit(1); |
| 377 | } |
| 378 | if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) { |
| 379 | errorBox( |
| 380 | `Invalid batch entry on line ${i + 1}`, |
| 381 | 'Each line must be a JSON object with at least { "outputKey": "..." }.', |
| 382 | ); |
| 383 | process.exit(1); |
| 384 | } |
| 385 | const obj = parsed as Record<string, unknown>; |
| 386 | const outputKey = obj.outputKey; |
| 387 | if (typeof outputKey !== "string" || outputKey.length === 0) { |
| 388 | errorBox( |
| 389 | `Missing outputKey on line ${i + 1}`, |
| 390 | 'Each batch entry needs a non-empty "outputKey" string (e.g. "renders/alice.mp4").', |
| 391 | ); |
| 392 | process.exit(1); |
| 393 | } |
| 394 | if (obj.variables !== undefined) { |
| 395 | if ( |
| 396 | obj.variables === null || |
| 397 | typeof obj.variables !== "object" || |
| 398 | Array.isArray(obj.variables) |
| 399 | ) { |
| 400 | errorBox( |
| 401 | `Invalid variables on line ${i + 1}`, |
| 402 | '"variables" must be a JSON object (or omitted).', |
| 403 | ); |
| 404 | process.exit(1); |
| 405 | } |
| 406 | } |
| 407 | if (obj.executionName !== undefined && typeof obj.executionName !== "string") { |
| 408 | errorBox( |
| 409 | `Invalid executionName on line ${i + 1}`, |
| 410 | '"executionName" must be a string (or omitted).', |
| 411 | ); |
| 412 | process.exit(1); |
| 413 | } |
| 414 | out.push({ |
| 415 | entry: { |
| 416 | outputKey, |
| 417 | variables: obj.variables as Record<string, unknown> | undefined, |
| 418 | executionName: obj.executionName as string | undefined, |
| 419 | }, |
| 420 | lineNumber: i + 1, |
| 421 | }); |