@salesforce/plugin-templates
Version:
Commands to create metadata from a default or custom template
96 lines • 4.03 kB
JavaScript
/*
* Copyright (c) 2026, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import path from 'node:path';
import { Flags, SfCommand, Ux } from '@salesforce/sf-plugins-core';
import { TemplateType } from '@salesforce/templates';
import { Messages, SfProject } from '@salesforce/core';
import { getCustomTemplates, runGenerator } from '../../../../utils/templateCommand.js';
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
const messages = Messages.loadMessages('@salesforce/plugin-templates', 'digitalExperienceSite');
/**
* Strips spaces and non-alphanumeric characters so display names map to template directories
* (e.g. "Build Your Own (LWR)" → "BuildYourOwnLWR").
*/
function normalizeTemplateName(name) {
return name.replace(/[^a-zA-Z0-9]/g, '');
}
export default class GenerateSite extends SfCommand {
static state = 'preview';
static summary = messages.getMessage('summary');
static description = messages.getMessage('description');
static examples = messages.getMessages('examples');
static flags = {
'target-org': Flags.optionalOrg(),
name: Flags.string({
char: 'n',
summary: messages.getMessage('flags.name.summary'),
required: true,
}),
'template-name': Flags.string({
char: 't',
summary: messages.getMessage('flags.template-name.summary'),
options: ['Build Your Own (LWR)'],
required: true,
}),
'url-path-prefix': Flags.string({
char: 'p',
summary: messages.getMessage('flags.url-path-prefix.summary'),
// each site must have a unique url path prefix, if not provided assume it's empty
// to mimic UI's behavior
default: '',
}),
'admin-email': Flags.string({
char: 'e',
summary: messages.getMessage('flags.admin-email.summary'),
}),
'output-dir': Flags.directory({
char: 'd',
summary: messages.getMessage('flags.output-dir.summary'),
description: messages.getMessage('flags.output-dir.description'),
}),
};
/**
* Resolves the default output directory by reading the project's sfdx-project.json.
* Returns the path to the default package directory,
* or falls back to the current directory if not in a project context.
*/
static async getDefaultOutputDir() {
try {
const project = await SfProject.resolve();
const defaultPackage = project.getDefaultPackage();
return path.join(defaultPackage.path, 'main', 'default');
}
catch {
return '.';
}
}
async run() {
const { flags } = await this.parse(GenerateSite);
let adminEmail = flags['admin-email'];
if (!adminEmail) {
const org = flags['target-org'];
// If this ever fails to return a username, the default value will be appeneded ".invalid"
// in admin workspace with a note asking the admin to set a valid email and verify it.
adminEmail = org?.getConnection()?.getUsername() ?? 'senderEmail@example.com';
}
const outputDir = flags['output-dir'] ?? (await GenerateSite.getDefaultOutputDir());
const flagsAsOptions = {
sitename: flags.name,
urlpathprefix: flags['url-path-prefix'],
adminemail: adminEmail,
template: normalizeTemplateName(flags['template-name']),
outputdir: outputDir,
};
return runGenerator({
templateType: TemplateType.DigitalExperienceSite,
opts: flagsAsOptions,
ux: new Ux({ jsonEnabled: this.jsonEnabled() }),
templates: getCustomTemplates(this.configAggregator),
});
}
}
//# sourceMappingURL=site.js.map