( plugin: QuickAdd, params: CliData, )
| 525 | } |
| 526 | |
| 527 | async function runTemplateHandler( |
| 528 | plugin: QuickAdd, |
| 529 | params: CliData, |
| 530 | ): Promise<string> { |
| 531 | const command = CLI_COMMANDS.runTemplate; |
| 532 | |
| 533 | // Wrapped so malformed input (e.g. invalid vars= JSON parsed by the up-front |
| 534 | // name check) returns the standard {ok:false,error} envelope instead of |
| 535 | // rejecting the handler — matching quickadd:run and run-template's ui path. |
| 536 | try { |
| 537 | const path = typeof params.path === "string" ? params.path.trim() : ""; |
| 538 | if (!path) { |
| 539 | return serialize({ |
| 540 | ok: false, |
| 541 | command, |
| 542 | error: "Missing template path. Provide path=<vault-path>.", |
| 543 | }); |
| 544 | } |
| 545 | |
| 546 | // Honest envelope: confirm the template file exists up front rather than |
| 547 | // letting the engine swallow a missing-file error and report ok:true. Use |
| 548 | // the engine's own resolver (getTemplateFile) so the CLI accepts exactly the |
| 549 | // paths the engine does — leading slash stripped, ".md" appended — instead of |
| 550 | // a stricter raw lookup that rejects "Templates/Daily" or "/Templates/Daily.md". |
| 551 | const file = getTemplateFile(plugin.app, path); |
| 552 | if (!file) { |
| 553 | return serialize({ |
| 554 | ok: false, |
| 555 | command, |
| 556 | error: `No template file found at '${path}'.`, |
| 557 | }); |
| 558 | } |
| 559 | |
| 560 | // Build from the resolved path so the note-name prompt header (basename) and |
| 561 | // the content read agree with what the engine will open. |
| 562 | const choice = createFolderTemplateChoice(file.path); |
| 563 | |
| 564 | // Honest envelope for the note name. The name is {{value}}; when it's provided |
| 565 | // but blank, the requirement collector consumes it (so the standard guard sees |
| 566 | // nothing missing) and the engine then throws "File name is empty" and swallows |
| 567 | // it — reporting a false ok:true with no note created. Reject a blank name up |
| 568 | // front for non-interactive runs (ui mode can still prompt). Headless runs have |
| 569 | // no editor selection, so {{value}} comes solely from this variable. |
| 570 | if (!isTruthy(params.ui)) { |
| 571 | const variables = extractVariables(params, RESERVED_RUN_TEMPLATE_PARAMS); |
| 572 | const name = variables.value; |
| 573 | if (name == null || String(name).trim().length === 0) { |
| 574 | return serialize({ |
| 575 | ok: false, |
| 576 | command, |
| 577 | error: "Missing required inputs for non-interactive CLI run.", |
| 578 | choice: describeChoice(choice), |
| 579 | missing: [ |
| 580 | { |
| 581 | id: "value", |
| 582 | label: "New note name", |
| 583 | type: "text", |
| 584 | source: "collected", |
no test coverage detected