Extending the Salesforce CLI with a Customized Plugin – Latest News Web Dev

As extra companies transfer to the cloud and DevOps methodologies proceed to evolve, increasingly developers are getting snug with working within the terminal. Whereas conventional CLI instructions like grep and cat are well-known instruments for reaching small targets, extra sophisticated duties require extra sturdy tooling.

These days, CLI applications include richer interactive experiences. One such program is the Salesforce CLI, the command-line interface for Salesforce DX. It’s a CLI that helps simplify frequent operations when constructing an software for Salesforce developers. The Salesforce CLI itself is constructed on prime of oclif—additionally from Salesforce—which is an open-source framework for constructing command-line interfaces. Oclif is written in TypeScript, and it has a really sturdy group supporting it. Better of all, it has an structure that prioritizes plugin assist, which permits customers to increase the CLI for their very own wants.

On this put up, we’ll create a customized plugin for sfdx. Our plugin will generate fixture knowledge for a Lightning app that runs on a Salesforce org. This knowledge will likely be used to populate our mission with random names and addresses to ensure that us to check the usability of our mission.


Earlier than getting began, set up the next:

  • A comparatively current model of Node.js. You need to set up the newest model accessible, resembling 12.20.0 or 14.13.1
  • The Salesforce CLI tool, put in globally because the sfdx-cli NPM bundle
  • TypeScript (So long as you already know JavaScript, deep familiarity with TypeScript isn’t required.)

To make completely positive that you’ve got all the required software program, comply with this guide on preparing for Salesforce CLI plugin development.

Subsequent, in case you don’t have a Salesforce org, sign up for a free Developer Edition org. Enable Dev Hub for your Salesforce org. As soon as your DevHub is enabled, you’ll have to affiliate it together with your Salesforce CLI set up. To try this, run the next command:

sfdx auth:web:login -d -a DevHub

This can open a brand new browser window that can ask in your Salesforce credentials. When you’ve gone via that circulate, sfdx will inform you when the authentication is full.

Lastly, you’ll be able to create a scratch org, which is sort of a momentary Salesforce org. You should use the scratch org to check what creating on the Salesforce platform appears to be like like.

Getting began

Open up a terminal window, and navigate to a folder in your new mission. Then, clone the next GitHub repository:

git clone https://github.com/trailheadapps/dreamhouse-lwc.git

The Dreamhouse app is a pattern Lightning software that lists realtors and their related properties. The app comes with some fixture knowledge, however since our purpose is to construct an sfdx plugin that creates a set of randomized fixture knowledge for this software, we are able to do away with these information. To take action, delete the next information out of your newly cloned repository:

  • knowledge/brokers-data.json
  • knowledge/properties-data.json

You must also take away their references from the information/sample-data-plan.json file; a diff of that may appear to be this:

Plain Textual content


--- a/knowledge/sample-data-plan.json
+++ b/knowledge/sample-data-plan.json
@@ -1,17 +1,9 @@
-    {
-        "sobject": "Broker__c",
-        "saveRefs": true,
-        "files": ["brokers-data.json"]
-    },
-    {
-        "sobject": "Property__c",
-        "resolveRefs": true,
-        "information": ["properties-data.json"]
-    },

Subsequent, let’s see what the app truly appears to be like like. Run the set up script which comes with the repository—both bin/install-scratch.sh or bin/install-scratch.bat, relying in your working system—to push the entire Lightning app to your Salesforce org.

This opens a browser window and takes you to your Salesforce occasion. Click on on the App Launcher icon within the higher left nook (it’s the row of dots) and choose the Dreamhouse app. You need to see a Quarterly Efficiency chart, with none knowledge. You too can click on on the Properties menu, and notice that there are zero objects accessible.

That is all to be anticipated. Our Salesforce CLI plugin will create the fictional properties which our app will use.

Creating the plugin

In a brand new folder outdoors of the dreamhouse-lwc mission, run this command:

sfdx plugins:generate fixture-data-demo

This can scaffold a brand new plugin in a listing known as fixture-data-demo. You’ll be requested a sequence of questions, however you’ll be able to simply preserve hitting Enter to just accept all the defaults.

After npm finishes putting in all the dependencies, we are able to take a look at whether or not or not the plugin was arrange accurately. Run bin/run hi there:org -u $USERNAME, the place $USERNAMEis your Salesforce consumer identify. You need to see a greeting in response.

One of many good issues about extending the Salesforce CLI is that lots of the tough selections round working with command flags or arguments are vastly simplified for you. There’s even a take a look at runner that requires little or no configuration in your half. Let’s begin constructing out our plugin to see these options in motion.

You may need observed two attention-grabbing issues concerning the command we used to run to get our earlier greeting:

  1. We used bin/run to execute our hi there:org command. bin/run executes sfdx, whereas loading a native copy of your plugin. That’s, the plugin you might be creating can solely be used on this listing; it’s not accessible outdoors of this scope simply but.
  2. All sfdx instructions are preceded by a namespace to keep away from conflicts with different plugins. On this case, that namespace is hi there. Navigate to the src/instructions listing in your just lately scaffolded mission, and also you’ll see a listing known as hi there, with a single file, org.ts.

Let’s suppose we would like our plugin to run as sfdx fixtures:generate. In that case, rename the hi there folder to fixtures, and the org.ts file to generate.ts.

You’ll be able to delete all the code that’s within the newly renamed generate.ts. Within the subsequent a part of this information, we’ll present code blocks that it is best to paste into the file as an alternative. As we progress, we’ll describe what our code does so to comply with alongside.

First, let’s arrange our import statements:

Plain Textual content


import * as os from 'os';
import { guarantees as fsPromises } from 'fs';
import * as path from 'path';

import { flags, SfdxCommand } from '@salesforce/command';
import { Messages } from '@salesforce/core';
import { AnyJson } from '@salesforce/ts-types';

import * as mkdirp from 'mkdirp';
import * as Probability from 'likelihood';

The primary set represents core Node modules that we’ll want to make use of in our CLI plugin. The second set represents core modules required by sfdx. Lastly, the third set represents third-party npm packages that our plugin must operate. Let’s not neglect so as to add these module dependencies to our mission.

npm set up mkdirp likelihood --save

Transferring on, paste these traces after the import statements:

// Initialize Messages with the present plugin listing

// Load the particular messages for this file. Messages from @salesforce/command, @salesforce/core,
// or any library that's utilizing the messages framework may also be loaded this fashion.
const messages = Messages.loadMessages('fixture-data-demo', 'generate');

We’ll get to the usage of this messages variable shortly. For now, preserve it in thoughts, and proceed pasting these code blocks:

Plain Textual content


export default class Generate extends SfdxCommand {
 public static description = messages.getMessage('commandDescription');

 public static examples = messages.getMessage('examples').break up(os.EOL);

 protected static flagsConfig = {
   // flag with a price (-n, --name=VALUE)
   depend: flags.integer({
     char: 'c',
     description: messages.getMessage('numberFlagDescription'),
     default: 10

Okay, now we’re attending to some good things. Our generate command is mapped to a category known as Generate, which extends the SfdxCommand class. Due to this inheritance, quite a lot of performance is offered for us by sfdx. We arrange some variables for a command description and for examples—since this offers with messages, we’ll elaborate on this half shortly. Extra importantly, we’re organising a flag known as depend, which has a shortcode of n. That signifies that we are able to name our command with a --count or -c flag with the intention to present some further configuration. On this case, if no dependis offered, the default worth will likely be 10.

Subsequent, we’ll get to the fixture knowledge era:

   const likelihood = new Probability();

   const brokerData = { data: [] };
   const propertyData = { data: [] };

   for (let i = 0; i < quantity; i++) {
     const brokerName = likelihood.identify();

       "attributes": {
         "sort": "Broker__c",
         "referenceId": `${brokerName.change(/s/g, "")}Ref`
       "identify": brokerName,
       "Title__c": "Senior Dealer",
       "Phone__c": likelihood.telephone(),
       "Mobile_Phone__c": likelihood.telephone(),
       "Email__c": likelihood.electronic mail(),
       "Picture__c": `https:${likelihood.avatar()}`

     const deal with = likelihood.deal with();
       "attributes": {
         "sort": "Property__c",
         "referenceId": `${deal with.change(/s/g, "")}Ref`
     "Title": likelihood.sentence({ phrases: 5 }),
     "Address__c": deal with,
     "City__c": likelihood.metropolis(),
     "State__c": likelihood.state(),
     "Zip__c": likelihood.zip(),
     "Price__c": likelihood.floating({ fastened: 2, min: 100000, max: 1000000 }),
     "Beds__c": likelihood.pure({ min: 1, max: 5 }),
     "Baths__c": likelihood.pure({ min: 1, max: 5 }),
     "Location__Longitude__s": likelihood.longitude(),
     "Location__Latitude__s": likelihood.latitude(),
     "Picture__c": `https://s3-us-west-1.amazonaws.com/sfdc-demo/realty/home${likelihood.pure({ min: 1, max: 10 })}.jpg`,
     "Thumbnail__c": `https://s3-us-west-1.amazonaws.com/sfdc-demo/realty/home${likelihood.pure({ min: 1, max: 10 })}sq.jpg`,
     "Tags__c": "victorian",
     "Description__c": likelihood.sentence({ phrases: 10 })

   await mkdirp('knowledge');
   await fsPromises.writeFile(path.be part of('knowledge', 'brokers-data.json'), JSON.stringify(brokerData, null, 2));
   await fsPromises.writeFile(path.be part of('knowledge', 'properties-data.json'), JSON.stringify(propertyData, null, 2));

   return "All executed! Test the information listing. :)";

This appears to be like like quite a lot of code, however don’t fear! Our Dreamhouse app has a number of customized objects. Amongst these objects are Brokers and Properties. We have to present values for his or her particular person attributes. We create some variables to retailer this data as JSON (brokerData and propertyData). Then, we loop via this as many occasions as matches our quantity worth, and we use our beforehand imported Probability bundle to generate random values for names, telephone numbers, addresses, and so forth. When that’s completed, we create a listing known as knowledge, and write these fixtures out as JSON.

Okay, as promised, let’s return to that messages variable. You need to have a folder in your plugin known as messages, with a file known as org.json. Rename this file to generate.json, and open it up. Right here is the place all the assist strings are outlined in your CLI command. Substitute the contents with the next JSON:

 "commandDescription": "generate an inventory of addresses and names",
 "countFlagDescription": "variety of objects to generate",
 "examples": [
   "sfdx fixtures:generate --count 5"

With a view to higher perceive what this JSON file does, execute bin/run fixtures:generate --help on the command line in our terminal. You will notice these strings displayed as assist documentation. That’s the aim of all of the message code famous above: mapping these strings to instructions and flags for a greater UX. It’s necessary to supply your customers with some steerage on easy methods to use your command.

Testing and Releasing

In fact, no piece of software program is full with out checks. The Salesforce CLI comes with a testing library that makes it simpler to construct out this important a part of development.

Very similar to the supply code, our listing and file construction ought to match our command identify. Open up the take a look at/instructions listing and rename hi there to fixtures, and org.take a look at.ts to generate.take a look at.ts.

Our total take a look at file will likely be somewhat small, so we received’t go into it line-by-line the way in which we did with the supply code.

import { count on, take a look at } from '@salesforce/command/lib/take a look at';

import * as path from 'path';
import { guarantees as fsPromises } from 'fs';

const dataPath = path.be part of(__dirname, '..', '..', '..', 'knowledge');

describe('fixtures:org', () => {
 take a look at
   .it('runs fixtures:generate', async (ctx) => {
     const brokersFilename = path.be part of(dataPath, 'brokers-data.json');
     const propertiesFilename = path.be part of(dataPath, 'properties-data.json');

     // Fulfills with undefined upon success.
     count on(await fsPromises.entry(brokersFilename)).to.be.equal(undefined);
     count on(await fsPromises.entry(propertiesFilename)).be.equal(undefined);

Right here, we’re executing the command via the command('fixtures:generate') methodology name. Then, we’re utilizing Node’s access methodology to confirm that our JSON information had been created. Go forward and name npm take a look at, and also you’ll see your newly created take a look at move!

You may see some linting errors, however you’ll be able to ignore them. Alternatively, you’ll be able to edit bundle.json to take away the posttest script—that’s what runs the linter after your checks full.

With our plugin code full and examined, it’s time to see it in motion. Now, you might have a globally put in model of sfdx, however a domestically developed plugin. We’d like a solution to load the plugin into our international set up. Fortuitously, sfdx comes with a command to do exactly that:

sfdx plugins:hyperlink

Whenever you run this command in your plugin listing, sfdx will load this native plugin so to try it out in your individual Lightning app earlier than distributing it. In case you uncover that you could make adjustments to the plugin after it’s been linked, simply run sfdx plugins:uninstall $PLUGIN_NAMEto unlink it.

Now, within the terminal, navigate again to your beforehand cloned listing for the Dreamhouse app. As soon as there, sort sfdx fixtures:generate. You need to now have a knowledge listing, full with a number of model new JSON information full of randomly generated knowledge. Let’s go forward and import these new adjustments into our org after which see the outcomes:

sfdx pressure:knowledge:tree:import -f knowledge/brokers-data.json, knowledge/properties-data.json
sfdx pressure:org:open

Identical to earlier than, navigate to the Dreamhouse app via the App Launcher. Nevertheless, this time you’ll discover precise data, which characterize the fixtures you simply generated! The Brokers tab, for instance, is filled with all the identical data as those generated by the plugin:

Studying extra

Growing Salesforce CLI plugins advantages each developers _and _users. For developers, a lot of the boilerplate of offering documentation, argument dealing with, and testing is taken care of. Customers can count on each customized plugin to behave in predictable methods, and these plugins unlock highly effective new capabilities they’ll use to make their Lightning app development just a bit bit simpler.

We’ve solely scratched the floor of what it means to work with Salesforce CLI. There’s a extra in-depth tutorial on the ins and outs of Salesforce development over on Trailhead; I even discovered an entire category of amazing things you can do with sfdx. As well as, their documentation consists of some greatest practices and efficiency strategies. Completely happy coding!

Abu Sayed is the Best Web, Game, XR and Blockchain Developer in Bangladesh. Don't forget to Checkout his Latest Projects.

Checkout extra Articles on Sayed.CYou

#Extending #Salesforce #CLI #Customized #Plugin #Latest News #Web #Dev