UNPKG

sfdx-hardis

Version:

Swiss-army-knife Toolbox for Salesforce. Allows you to define a complete CD/CD Pipeline. Orchestrate base commands and assist users with interactive wizards

125 lines (117 loc) 6.79 kB
import { SfCommand, Flags, requiredOrgFlagWithDeprecations } from '@salesforce/sf-plugins-core'; import { Messages, SfError } from '@salesforce/core'; import c from 'chalk'; import { isCI, uxLog } from '../../../../common/utils/index.js'; import { prompts } from '../../../../common/utils/prompts.js'; import { soqlQuery } from '../../../../common/utils/apiUtils.js'; Messages.importMessagesDirectoryFromMetaUrl(import.meta.url); const messages = Messages.loadMessages('sfdx-hardis', 'org'); export default class HardisOrgCommunityUpdate extends SfCommand { static summary = messages.getMessage('orgCommunityUpdate'); static description = ` ## Command Behavior **Updates the status of one or more Salesforce Experience Cloud (Community) networks.** This command provides a way to programmatically change the status of your Salesforce Communities, allowing you to manage their availability. This is particularly useful for: - **Maintenance:** Taking communities offline for planned maintenance (\`DownForMaintenance\`). - **Activation/Deactivation:** Bringing communities online or offline (\`Live\`, \`DownForMaintenance\`). - **Automation:** Integrating community status changes into CI/CD pipelines or scheduled jobs. Key functionalities: - **Network Selection:** You can specify one or more community network names (separated by commas) using the \`--name\` flag. - **Status Update:** You can set the new status for the selected communities using the \`--status\` flag. Supported values are \`Live\` and \`DownForMaintenance\`. - **Confirmation Prompt:** In non-CI environments, it provides a confirmation prompt before executing the update, ensuring intentional changes. <details markdown="1"> <summary>Technical explanations</summary> The command's technical implementation involves: - **Salesforce SOQL Query:** It first queries the Salesforce \`Network\` object using SOQL to retrieve the \`Id\`, \`Name\`, and \`Status\` of the specified communities. This ensures that only existing communities are targeted. - **SObject Update:** It then constructs an array of \`Network\` sObjects with their \`Id\` and the new \`Status\` and performs a DML update operation using \`conn.sobject("Network").update()\`. The \`allOrNone: false\` option is used to allow partial success in case some updates fail. - **Error Handling and Reporting:** It iterates through the update results, logging success or failure for each community. It also provides a summary of successful and erroneous updates. - **User Interaction:** Uses \`prompts\` to confirm the update action with the user when not running in a CI environment. - **Salesforce Connection:** Establishes a connection to the target Salesforce org using the \`target-org\` flag. </details> `; static examples = [ `$ sf hardis:org:community:update --name 'MyNetworkName' --status DownForMaintenance`, `$ sf hardis:org:community:update --name 'MyNetworkName,MySecondNetworkName' --status Live` ]; static flags = { name: Flags.string({ description: 'List of Networks Names that you want to update, separated by comma', char: 'n', required: true, }), status: Flags.string({ description: 'New status for the community, available values are: Live, DownForMaintenance', char: 's', required: true, }), debug: Flags.boolean({ char: 'd', default: false, description: messages.getMessage('debugMode'), }), 'target-org': requiredOrgFlagWithDeprecations, }; async run() { const { flags } = await this.parse(HardisOrgCommunityUpdate); const networkNames = flags.name ? flags.name.split(',') : []; const status = flags.status ? flags.status : ''; const debugMode = flags.debug || false; const conn = flags['target-org'].getConnection(); if (networkNames.length === 0) { throw new SfError(`Error: No network name(s) provided.`); } const networksConstraintIn = networkNames.map((networkName) => `'${networkName}'`).join(','); const networksQuery = `SELECT Id, Name, Status FROM Network WHERE Name IN (${networksConstraintIn})`; const networksQueryRes = await soqlQuery(networksQuery, conn); if (debugMode) { uxLog("log", this, c.grey(`Query result:\n${JSON.stringify(networksQueryRes, null, 2)}`)); } // Check empty result if (networksQueryRes.length === 0) { const outputString = `No matching network records were found with the given names.`; uxLog("warning", this, c.yellow(outputString)); return { outputString }; } const idToNameMap = new Map(networksQueryRes.records.map(network => [network.Id, network.Name])); // Request configuration from user if (!isCI) { const confirmUpdate = await prompts({ type: 'confirm', name: 'value', initial: true, message: c.cyanBright(`Are you sure you want to update these ${c.bold(idToNameMap.size)} networks' status to '${status}' in org ${c.green(flags['target-org'].getUsername())}?`), description: 'Confirm that you want to change the status of the selected community networks', }); if (confirmUpdate.value !== true) { const outputString = 'Script cancelled by user.'; uxLog("warning", this, c.yellow(outputString)); return { outputString }; } } // Process Network update const networkUpdates = networksQueryRes.records.map((network) => { return { Id: network.Id, Status: status }; }); const updateResults = await conn.sobject("Network").update(networkUpdates, { allOrNone: false }); let updateSuccessNb = 0; let updateErrorsNb = 0; for (const ret of updateResults) { if (ret.success) { updateSuccessNb++; uxLog("success", this, c.green(`'${c.bold(idToNameMap.get(ret.id))}' Network was updated.`)); } else { updateErrorsNb++; uxLog("error", this, c.red(`Error ${updateErrorsNb}: Network '${idToNameMap.get(ret.id)}' failed to update: [${ret.errors[0].message}]`)); } } // Return an object to be displayed with --json return { orgId: flags['target-org'].getOrgId(), communityUpdatesSuccess: updateSuccessNb, communityUpdatesErrors: updateErrorsNb, outputString: `${updateSuccessNb} network(s) were updated.`, }; } } //# sourceMappingURL=update.js.map