sfdx-node
v3.8.0
Published
Utility to wrap the Salesforce CLI for use in NodeJS
Downloads
9,406
Readme
SFDX-Node
Wrapper for the Salesforce CLI to use in Node.js
Installation
npm install sfdx-node
Usage
The Salesforce CLI is based on OCLIF and is a combination of different OCLIF plugins. This module includes all the commands in force
, auth
and config
namespaces. To use Salesforce CLI commands within Node.js programs, we wrap the namespace, topics, and camelcase the commands.
For example:
sfdx force:org:list
becomessfdx.force.org.list()
sfdx force:package:version:create
becomessfdx.force.package.versionCreate()
sfdx auth:web:login
becomessfdx.auth.web.login()
sfdx config:set
becomessfdx.config.set()
sfdx NAMESPACE:TOPIC:COMMAND:SUB -> sfdx.namespace.topic.commandSub();
Command parameters can be passed in as an object to the command using the flag names. So sfdx force:org:create --setalias myorg --setdefaultusername
can be executed as below:
const sfdx = require('sfdx-node');
// Create a new scratch org with alias myorg and set it as default org
sfdx.force.org.create({
setalias: 'myorg',
setdefaultusername: true
});
Similarly, the special command arguments can be passing in as an array named args
inside an object, as the second method argument.
So, sfdx alias:set [email protected] [email protected]
can be executed as below:
const sfdx = require('sfdx-node');
// Set/overwrite aliases for already authorized orgs
sfdx.alias.set({},{
args: ['[email protected]', '[email protected]']
});
Commands all return a JS Promise.
const sfdx = require('sfdx-node');
//authorize a dev hub
sfdx.auth.web.login({
setdefaultdevhubusername: true,
setalias: 'HubOrg'
})
.then(() => sfdx.force.source.push()) //push source
.then(() => {
// Display confirmation of source push
console.log('Source pushed to scratch org');
});
Using _quiet
for showing/hiding command output
It is possible to control the visibility of the output (success or failure) generated by a Salesforce CLI command, executed through this module.
Output can be made visible by passing in the flag _quiet
as false
. Default value for flag _quiet
is true
, which means that the default
behavior of this module is to hide the output of a Salesforce CLI command.
const sfdx = require('sfdx-node');
// Fetch all the aliases, but do not show how the Salesforce CLI command output
sfdx.alias.list()
.then((listResult) => {
// Do something with the fetched list of all aliases
console.log('Alias list:', listResult);
});
// Fetch all the aliases, and show the Salesforce CLI command output
sfdx.alias.list({
_quiet: false
})
.then((listResult) => {
// Do something else with the fetched list of all aliases
});
Using _rejectOnError
for promise rejection (in case of a command failure)
Majority of the Salesforce CLI commands, when executed through node, do not reject the promise when an error occurs. They rather resolve with
undefined
. Promise rejection can be forced by passing in the flag _rejectOnError
as true
. A few Salesforce CLI commands reject the promise
as their out-of-the-box behavior, without using this _rejectOnError
flag.
const sfdx = require('sfdx-node');
// Pull the remote changes from the scratch org
sfdx.force.source.pull({
_rejectOnError: true
})
.then((pullResult) => {
// Successfully pulled from scratch org
console.log('Changes pulled from scratch org:', pullResult);
})
.catch((pullError) => {
// Promise rejected in case of conflicts or some other issue while pulling from scratch org
console.log('Errors occurred during pull operation:', pullError);
});
Rejecting promises is not the default bahavior of this module, unless the promise is rejected by Salesforce CLI command itself. This _rejectOnError
flag needs to be passed in as true
for every command that is expected to reject the promise in case of an error.
Promise rejection overlapping for parallel calls
When multiple CLI commands are executed in parallel using this module, while also making use of _rejectOnError
, more than one or even all the commands
may end up rejecting the promises. This can happen because the errors are shared among all the parallel executions.
To avoid this, make use of sfdx-node/parallel
module. It works in the same way as the main module, except for the fact that each command is executed in
it's own child process. This ensures that each command execution has it's own context and it doesn't share errors with other commands executing in parallel.
const sfdx = require('sfdx-node/parallel');
// Get source status for first scratch org
sfdx.force.source.status({
targetusername: '[email protected]',
_rejectOnError: true
})
.then((statusResult) => {
// Source status for first scratch org
console.log('First org source status:', statusResult);
})
.catch((statusError) => {
// Error occurred during source status check for first scratch org
console.log('First org error:', statusError);
});
// Get source status for second scratch org
sfdx.force.source.status({
targetusername: '[email protected]',
_rejectOnError: true
})
.then((statusResult) => {
// Source status for second scratch org
console.log('Second org source status:', statusResult);
})
.catch((statusError) => {
// Error occurred during source status check for second scratch org
console.log('Second org error:', statusError);
});