Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 29 additions & 4 deletions apps/spfx-cli/src/cli/actions/ListTemplatesAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// See LICENSE in the project root for license information.

import type { Terminal } from '@rushstack/terminal';
import { type SPFxTemplateCollection, SPFxTemplateRepositoryManager } from '@microsoft/spfx-template-api';
import { SPFxTemplateCollection, SPFxTemplateRepositoryManager } from '@microsoft/spfx-template-api';

import { SPFxActionBase } from './SPFxActionBase';

Expand All @@ -14,7 +14,8 @@ export class ListTemplatesAction extends SPFxActionBase {
summary: 'Lists available SPFx templates from configured sources',
documentation:
'This command lists all available templates from the default GitHub source ' +
'and any additional sources specified with --local-source or --remote-source.'
'and any additional sources specified with --local-source or --remote-source. ' +
'Use --spfx-version to filter templates by version (e.g., "--spfx-version 1.22").'
Comment on lines 16 to +18
},
terminal
);
Expand All @@ -37,8 +38,32 @@ export class ListTemplatesAction extends SPFxActionBase {

const templates: SPFxTemplateCollection = await this._fetchTemplatesAsync(manager);

const formattedTable: string = await templates.toFormattedStringAsync();
terminal.writeLine(formattedTable);
// Apply --spfx-version filter if provided (user expects filter, not just branch selection)
const spfxVersion: string | undefined = this._spfxVersionParameter.value?.trim();
// Normalize version prefix: "version/1.22" -> "1.22", "1.22-rc.0" -> "1.22"
Comment on lines 39 to +43
const normalizedVersion: string | undefined = spfxVersion
? spfxVersion.replace(/^version\//, '').replace(/-.*$/, '')
: undefined;
Comment on lines +41 to +46
if (normalizedVersion) {
// Split into parts and compare major.minor so "1.2" doesn't match "1.20.0"
const versionParts: string[] = normalizedVersion.split('.');
Comment on lines +48 to +49
const filteredTemplates = [...templates.values()].filter(
(t) => t.spfxVersion && t.spfxVersion.split('.').slice(0, versionParts.length).join('.') === normalizedVersion
);
if (filteredTemplates.length === 0) {
terminal.writeLine(
`No templates found for SPFx version "${spfxVersion}". ` +
`Use "spfx list-templates" (without --spfx-version) to see all available versions.`
);
return;
Comment on lines +41 to +58
Comment on lines +41 to +58
}
const displayCollection: SPFxTemplateCollection = new SPFxTemplateCollection(filteredTemplates);
const formattedTable: string = await displayCollection.toFormattedStringAsync();
terminal.writeLine(formattedTable);
Comment on lines +47 to +62
} else {
const formattedTable: string = await templates.toFormattedStringAsync();
terminal.writeLine(formattedTable);
}
} catch (error: unknown) {
const message: string = error instanceof Error ? error.message : String(error);
terminal.writeErrorLine(`Error listing templates: ${message}`);
Expand Down
2 changes: 1 addition & 1 deletion apps/spfx-cli/src/cli/actions/SPFxActionBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export abstract class SPFxActionBase extends CommandLineAction {
parameterLongName: '--spfx-version',
argumentName: 'VERSION',
description:
'The SPFx version to use (e.g., "1.22", "1.23-rc.0"). Resolves to the "version/<VERSION>" branch ' +
'The SPFx version to filter by (e.g., "1.22"). Also selects a corresponding "version/<VERSION>" branch ' +
'in the template repository. Defaults to the "version/latest" branch.'
Comment on lines +55 to 56
});

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@microsoft/spfx-cli",
"comment": "",
"type": "none"
}
],
"packageName": "@microsoft/spfx-cli"
}