From 7ff35b7a380e84c03e9a9fd6dbac7b0547ad903e Mon Sep 17 00:00:00 2001 From: Tarushi Date: Mon, 6 Jul 2026 11:25:57 +0530 Subject: [PATCH] feat: add Angular options to sf project generate --template --- messages/project.md | 2 + .../template/generate/project/index.ts | 4 +- .../template/generate/project/index.nut.ts | 44 +++++++++++++++++++ 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/messages/project.md b/messages/project.md index 92baf59e..7a1208d6 100644 --- a/messages/project.md +++ b/messages/project.md @@ -64,6 +64,8 @@ The analytics template provides similar files and the force-app/main/default/wav The reactinternalapp and reactexternalapp templates provide React-based project scaffolding for internal and external UI bundle use cases. +The angularinternalapp and angularexternalapp templates provide Angular-based project scaffolding for internal and external UI bundle use cases. + The agent template provides project scaffolding for building Agentforce agents and includes a sample agent called Local Info Agent. # flags.namespace.summary diff --git a/src/commands/template/generate/project/index.ts b/src/commands/template/generate/project/index.ts index 7964a8c7..fc5aea35 100644 --- a/src/commands/template/generate/project/index.ts +++ b/src/commands/template/generate/project/index.ts @@ -33,7 +33,7 @@ export default class Project extends SfCommand { summary: messages.getMessage('flags.template.summary'), description: messages.getMessage('flags.template.description'), default: 'standard', - options: ['standard', 'empty', 'analytics', 'reactinternalapp', 'reactexternalapp', 'agent'] as const, + options: ['standard', 'empty', 'analytics', 'reactinternalapp', 'reactexternalapp', 'angularinternalapp', 'angularexternalapp', 'agent'] as const, })(), 'output-dir': outputDirFlag, namespace: Flags.string({ @@ -81,7 +81,7 @@ export default class Project extends SfCommand { outputdir: flags['output-dir'], manifest: flags.manifest, loginurl: flags['login-url'], - template: flags.template, + template: flags.template as ProjectOptions['template'], // namespace is a reserved keyword for the generator ns: flags.namespace, defaultpackagedir: flags['default-package-dir'], diff --git a/test/commands/template/generate/project/index.nut.ts b/test/commands/template/generate/project/index.nut.ts index 4910cea6..8c1e7ba6 100644 --- a/test/commands/template/generate/project/index.nut.ts +++ b/test/commands/template/generate/project/index.nut.ts @@ -287,6 +287,50 @@ describe('template generate project:', () => { assert.fileContent(uiBundleMetaPath, alphanumericName); }); + it('should create project with angularexternalapp template', () => { + const projectName = 'angular-externalapp-test'; + const alphanumericName = 'angularexternalapptest'; + execCmd(`template generate project --projectname ${projectName} --template angularexternalapp`, { + ensureExitCode: 0, + }); + const projectDir = path.join(session.project.dir, projectName); + assert.file([path.join(projectDir, 'sfdx-project.json')]); + assert.fileContent(path.join(projectDir, 'sfdx-project.json'), 'sourceApiVersion'); + const uiBundleMetaPath = path.join( + projectDir, + 'force-app', + 'main', + 'default', + 'uiBundles', + alphanumericName, + `${alphanumericName}.uibundle-meta.xml` + ); + assert.file([uiBundleMetaPath]); + assert.fileContent(uiBundleMetaPath, alphanumericName); + }); + + it('should create project with angularinternalapp template', () => { + const projectName = 'angular-internalapp-test'; + const alphanumericName = 'angularinternalapptest'; + execCmd(`template generate project --projectname ${projectName} --template angularinternalapp`, { + ensureExitCode: 0, + }); + const projectDir = path.join(session.project.dir, projectName); + assert.file([path.join(projectDir, 'sfdx-project.json')]); + assert.fileContent(path.join(projectDir, 'sfdx-project.json'), 'sourceApiVersion'); + const uiBundleMetaPath = path.join( + projectDir, + 'force-app', + 'main', + 'default', + 'uiBundles', + alphanumericName, + `${alphanumericName}.uibundle-meta.xml` + ); + assert.file([uiBundleMetaPath]); + assert.fileContent(uiBundleMetaPath, alphanumericName); + }); + it('should create project with agent template', () => { execCmd('template generate project --projectname agent1 --template agent --manifest', { ensureExitCode: 0,