Adds JSON output mode for the spfx list-templates command. Closes #235#253
Adds JSON output mode for the spfx list-templates command. Closes #235#253Adam-it wants to merge 1 commit into
spfx list-templates command. Closes #235#253Conversation
There was a problem hiding this comment.
Pull request overview
Adds a JSON output mode (now the default) for spfx list-templates, and refactors command output so structured results go to stdout while informational output is routed to stderr.
Changes:
- Added
--output/-o {json,text}tolist-templates, defaulting tojson - Implemented JSON serialization for template collections (
toJsonString()) and updated CLI action to write JSON to stdout - Introduced
StderrTerminalProviderand added/updated unit tests + docs/snapshots accordingly
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| common/changes/@microsoft/spfx-cli/json-output-mode_2026-04-25.json | Adds a change record for the CLI package. |
| apps/spfx-cli/src/utilities/StderrTerminalProvider.ts | New terminal provider intended to route CLI messages to stderr for JSON output scenarios. |
| apps/spfx-cli/src/utilities/tests/StderrTerminalProvider.test.ts | Unit tests validating stderr routing behavior. |
| apps/spfx-cli/src/cli/actions/ListTemplatesAction.ts | Adds --output option; writes JSON to stdout by default and table output for text mode. |
| apps/spfx-cli/src/cli/actions/SPFxActionBase.ts | Makes _terminal mutable so actions can temporarily swap terminal behavior. |
| apps/spfx-cli/src/cli/actions/tests/ListTemplatesAction.test.ts | Updates existing tests to force text output; adds JSON-output tests using stdout spying. |
| apps/spfx-cli/src/cli/test/snapshots/CommandLineHelp.test.ts.snap | Updates help snapshot to include the new --output parameter and its description. |
| apps/spfx-cli/README.md | Documents --output and provides examples for JSON (default) and text. |
| api/spfx-template-api/src/repositories/SPFxTemplateCollection.ts | Adds toJsonString() for structured template list serialization. |
| api/spfx-template-api/src/repositories/test/SPFxTemplateCollection.test.ts | Adds unit tests for toJsonString(). |
| api/spfx-template-api/src/repositories/test/snapshots/SPFxTemplateCollection.test.ts.snap | Snapshot for JSON serialization formatting. |
| api/spfx-template-api/etc/spfx-template-api.api.md | API report update to include toJsonString(). |
| api/spfx-template-api/README.md | Updates docs to mention JSON/table output helpers. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
26860dd to
65b297d
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 16 out of 16 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
apps/spfx-cli/README.md:81
- The
spfx list-templatesdocs list the new--outputoption, but the command also now supports--verbose(and help output advertises it). The README’s optional flags table should include--verboseand clarify that verbose/info messages are written to stderr (especially important with JSON output).
### Optional flags
| Flag | Default | Description |
|------|---------|-------------|
| `-o`, `--output {json,text}` | `json` | Output format. `json` writes machine-readable JSON to stdout (informational messages go to stderr). `text` writes a human-readable table |
| `--spfx-version VERSION` | `version/latest` branch | Branch/tag in the default template repo to use (e.g. `1.22`, `1.23-rc.0`) |
| `--template-url URL` | `https://github.com/SharePoint/spfx` | Custom GitHub template repository (default source) |
| `--local-source PATH` | — | Path to a local template folder to include (repeatable) |
| `--remote-source URL` | — | Additional public GitHub repo to include as a template source (repeatable) |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
9e88690 to
77d8b1c
Compare
| // @public | ||
| export interface ITemplateJsonOutputEntry { | ||
| // (undocumented) | ||
| category: string; |
| // (undocumented) | ||
| category: string; | ||
| // (undocumented) | ||
| description: string | null; |
There was a problem hiding this comment.
We generally use undefined for nullish things, not null.
| // `null` (not `undefined`) is intentional: JSON.stringify drops `undefined` fields | ||
| // but preserves `null`, ensuring the field is always present in the output. | ||
| // eslint-disable-next-line @rushstack/no-new-null |
There was a problem hiding this comment.
We could also just make this required.
| * {@link SPFxTemplateCollection.toJsonString}. | ||
| */ | ||
| export interface ITemplateJsonOutputEntry { | ||
| name: string; |
There was a problem hiding this comment.
Add doc comments for these things. It's not obvious what version is supposed to be, for example.
| Array [ | ||
| "[ log] Using GitHub template source: https://github.com/SharePoint/spfx[n]", | ||
| "[ log] Adding local template source: /path/to/templates[n]", | ||
| "[verbose] Using GitHub template source: https://github.com/SharePoint/spfx[n]", |
| expect(parsed).toEqual([ | ||
| { | ||
| name: 'webpart-minimal', | ||
| category: 'webpart', | ||
| description: 'A minimal web part template (no framework) for SPFx', | ||
| version: '0.0.1', | ||
| spfxVersion: '1.22.2', | ||
| fileCount: 23 | ||
| } | ||
| ]); | ||
| }); |
There was a problem hiding this comment.
Just make this a snapshot?
| it('does not write table output to the terminal', async () => { | ||
| const { terminalChunks } = await runListJsonAsync(); | ||
| const hasTableOutput: boolean = terminalChunks.some( | ||
| (chunk: string) => chunk.includes('┌') || chunk.includes('Found') | ||
| ); | ||
| expect(hasTableOutput).toBe(false); | ||
| }); |
There was a problem hiding this comment.
This is redundant with the parsing test.
| "changes": [ | ||
| { | ||
| "packageName": "@microsoft/spfx-cli", | ||
| "comment": "Adds JSON output mode for the `spfx list-templates` command (default `--output json`, with `--output text` for the human-readable table). Also adds a global `--verbose` flag to all actions and demotes source-registration messages (`Using GitHub template source`, `Adding local template source`, `Adding remote template source`) to verbose-level output.", |
There was a problem hiding this comment.
Stick the note about --verbose in a separate changelog message.
| 'Output format. "json" writes machine-readable JSON to stdout (informational ' + | ||
| 'messages go to stderr). "text" writes a human-readable table.', |
There was a problem hiding this comment.
Generally avoid printing non-erroneous data to stderr. In JSON mode, why not just not output anything that can't be JSON-parsed?
| terminal | ||
| ); | ||
|
|
||
| this._outputParameter = this.defineChoiceParameter({ |
There was a problem hiding this comment.
Consider making this a --json flag instead.
Description
The aim is to:
list-templatescommand that supports JSON (which will be the default mode) and TEXT.--verboseflag and moved some of the information command outputs to be part of the verbose, so that they are not part of stdout but instead are present in stderrHow was this tested?
Result
Help now also has new
--outputand--verboseflagThe default output mode of the
list-templatescommand is now JSON, or you may use the--output jsonas welltext works as before but
--output textneeds to be usedCommand output is part of stdout, and all other messages go to stderr
To see additional info the
--verboseoption needs to be usedType of change
spfx list-templatescommand #235