sfdx-node
Version:
Utility to wrap the Salesforce CLI for use in NodeJS
149 lines (138 loc) • 4.61 kB
JavaScript
const fs = require('fs');
const path = require('path');
const _ = require('lodash');
let cmdArray;
const allCommands = [];
const dxPlugins = [{
name: '@salesforce/plugin-alias/lib/index.js',
namespace: 'alias',
}, {
name: '@salesforce/plugin-apex/lib/index.js',
namespace: 'force',
}, {
name: '@salesforce/plugin-auth/lib/index.js',
namespace: 'auth',
}, {
name: '@salesforce/plugin-config/lib/index.js',
namespace: 'config',
}, {
name: '@salesforce/plugin-community/lib/index.js',
namespace: 'force',
}, {
name: '@salesforce/plugin-custom-metadata/lib/index.js',
namespace: 'force',
}, {
name: '@salesforce/plugin-data/lib/index.js',
namespace: 'force',
}, {
name: '@salesforce/plugin-limits/lib/index.js',
namespace: 'force',
}, {
name: '@salesforce/plugin-org/lib/index.js',
namespace: 'force',
},
{
name: '@salesforce/plugin-packaging/lib/index.js',
namespace: 'force',
},
{
name: '@salesforce/plugin-signups/lib/index.js',
namespace: 'force',
}, {
name: '@salesforce/plugin-schema/lib/index.js',
namespace: 'force',
}, {
name: '@salesforce/plugin-source/lib/index.js',
namespace: 'force',
}, {
name: '@salesforce/plugin-templates/lib/index.js',
namespace: 'force',
}, {
name: '@salesforce/plugin-user/lib/index.js',
namespace: 'force',
}, {
name: '@salesforce/sfdx-plugin-lwc-test/lib/index.js',
namespace: 'force',
}, {
name: 'salesforce-alm',
namespace: 'force',
}];
/**
* Recursively step through a directory to find out all command files (.js). Pushes the file name and command key into an array.
* @param {string} suffix Input directory name
* @param {string} commandBaseDir Path to the commands directory
*/
const processCommandsDir = (suffix, commandBaseDir) => {
const cmdsDir = path.join(commandBaseDir, suffix);
// Loop through the input directory
fs.readdirSync(cmdsDir).forEach((fileOrDir) => {
const cmdDefPath = path.join(cmdsDir, fileOrDir);
if (fs.statSync(cmdDefPath).isDirectory()) {
// If the current item is a directory, process the same
processCommandsDir(path.join(suffix, fileOrDir), commandBaseDir);
} else if (path.extname(cmdDefPath) === '.js') {
// If it's a JS file, push the file name and command key into the array
const obj = {};
obj['commandFile'] = cmdDefPath;
const fileNameWithoutExt = fileOrDir.replace('.js', '');
obj['commandKey'] = path.join(suffix, fileNameWithoutExt);
cmdArray.push(obj);
} else {
// Ignore any non-JS files
}
});
};
/**
* Loops through all the pre-defined plugins, iterates through their commands direcctories and
* then populates and returns an array with all the information required for progrmmatically
* executing each command.
*/
const readAllPlugins = () => {
// Populate the command array
_.forEach(dxPlugins, (plugin) => {
const { name, namespace } = plugin;
cmdArray = [];
const packagePath = path.dirname(require.resolve(name));
const commandBaseDir = path.join(packagePath, 'commands');
processCommandsDir(namespace, commandBaseDir);
// Loop through each command and create the function to execute a command
_.forEach(cmdArray, (cmdObj) => {
let topic;
const { commandKey, commandFile } = cmdObj;
const cmdKeyParts = commandKey.split(path.sep);
const commandClassNamePartsArray = [];
const methodNamePartsArray = [];
_(cmdKeyParts).slice(1).forEach((part, index) => {
if (index === 0) {
// Determine the command topic
topic = part;
} else {
// Except topic, collect all parts of the final method name in an array
methodNamePartsArray.push(part);
}
// Collect all parts of the command class name in an array
commandClassNamePartsArray.push(_.startCase(part));
});
// Command ID, e.g. force:org:create or auth:device:login
const commandId = cmdKeyParts.join(':');
// Actual exported method name
const methodName = _.camelCase(methodNamePartsArray.join('-'));
// Construct the command name as exported by each command module, e.g. OrgCreateCommand
const commandExportedClassName = commandClassNamePartsArray.concat('Command').join('');
// Finally, create the custom method for this command
allCommands.push({
namespace,
topic,
methodName,
commandId,
commandExportedClassName,
commandFile,
});
});
});
};
const getAllSFDXCommands = () => allCommands;
readAllPlugins();
module.exports = {
getAllSFDXCommands,
};