I am new to SFDX plugin development. I have a node CLI tool I am trying to integrate into the SFDX CLI. I have added my js file with node modules to the directory src/commands/digitsec/s4/
When I run bin/run commands:digitsec:s4:runScan it starts the process, I can see my CLI hit my server and logs in successfully, but after this, I get a bunch of errors saying that node modules are not found:
(node:5268) Error Plugin: s4: command digitsec:s4:node_modules:axios:lib:helpers:spread not found
module: @oclif/[email protected]
task: toCached
plugin: s4
root: C:\Documents\Desktop\Digitsec\S4SalesforceCLIPlugin\s4
See more details with DEBUG=*
» Error: command commands:digitsec:s4:runScan not found
The thing is though, the command has already started and run the first function of my CLI. How does the SFDX cli lose track of my command after it has already been started?
Also, I have tried installing the @oclif and @salesforce dependencies in the S4 folder to try and see if the issue was missing those dependencies. When I install these dependencies within my plugin folder though, the entire command fails to run, and just prints out i: 1++ to infinity in console.
After installing just the @oclif/config package within the S4 folder, I no longer get the errors popping up, but when running my command it hangs after starting and console logs 'the result is 84'
After installing either @salesforce/core or @salesforce/command is when the problem starts. I guess the issue has to be in in one/both of these packages.
Thank you in advance
Edit: To be able to reproduce, follow the steps here https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_plugins.meta/sfdx_cli_plugins/cli_plugins_generate_scaffold.htm
After setting up the basic hello world tutorial, we are going to adjust the org.ts file to be
import { flags, SfdxCommand } from '@salesforce/command';
import { Messages, SfdxError } from '@salesforce/core';
import { AnyJson } from '@salesforce/ts-types';
import * as child from 'child_process';
import { Console } from 'console';
import * as util from 'util';
// Initialize Messages with the current plugin directory
Messages.importMessagesDirectory(__dirname);
// Load the specific messages for this file. Messages from @salesforce/command, @salesforce/core,
// or any library that is using the messages framework can also be loaded this way.
const messages = Messages.loadMessages('test', 'org');
export default class Org extends SfdxCommand {
public static description = messages.getMessage('commandDescription');
public static examples = [
`$ sfdx hello:org --targetusername [email protected] --targetdevhubusername [email protected]
Hello world! This is org: MyOrg and I will be around until Tue Mar 20 2018!
My hub org id is: 00Dxx000000001234
`,
`$ sfdx hello:org --name myname --targetusername [email protected]
Hello myname! This is org: MyOrg and I will be around until Tue Mar 20 2018!
`
];
public static args = [{name: 'file'}];
protected static flagsConfig = {
// flag with a value (-n, --name=VALUE)
name: flags.string({char: 'n', description: messages.getMessage('nameFlagDescription')}),
force: flags.boolean({char: 'f', description: messages.getMessage('forceFlagDescription')})
};
public async run(): Promise<AnyJson> {
var output = '';
console.log(__dirname);
var foo: child.ChildProcess = child.exec("node ./src/commands/hello/testcli/s4", (stdout) => {
console.log(stdout);
});
foo.stdout.pipe(process.stdout);
foo.stdout.on('data', function(data) {
if(data.toString().search('pending') >= 0 || data.toString().search('completed') >= 0 ){
console.log(data.toString());
output += data.toString();
}
});
foo.on('close', function (req, res) {
console.log(`req: ${req}`);
console.log(`res: ${res}`);
})
// Return an object to be displayed with --json
return { orgId: output };
}
}
Then, generate a new folder within commands/hello/ called testcli. We will generate a js file named s4.js within here. This will contain
module.exports = async function (user, pass, file, org, orgid, s4url) {
var fs = require('fs');
const axios = require('axios');
var FormData = require('form-data');
const Path = require('path');
const https = require('https');
}
Create a package.json file within the testcli and install the required modules. When you then try to run bin/run hello:org you should get this in the errors
(node:18136) [MODULE_NOT_FOUND] Error Plugin: test: Cannot find module 'async'
Require stack:
- C:\Users\Documents\Desktop\test\src\commands\hello\testcli\node_modules\asynckit\bench.js
- C:\Users\Documents\Desktop\test\node_modules\@oclif\config\lib\plugin.js
- C:\Users\Documents\Desktop\test\node_modules\@oclif\config\lib\config.js
- C:\Users\Documents\Desktop\test\node_modules\@oclif\config\lib\index.js
- C:\Users\Documents\Desktop\test\node_modules\@oclif\command\lib\command.js
- C:\Users\Documents\Desktop\test\node_modules\@oclif\command\lib\index.js
- C:\Users\Documents\Desktop\test\bin\run
module: @oclif/[email protected]
If you then cd into the testcli folder, and try to install the @oclif without the @salesforce modules. Then you try to run, I get a response in console of:
the result is 84
And then if you install the @salesforce modules on top of that, we go back to i:++ to 1,000,000. Same result if you remove the @oclif modules and just keep the @salesforce modules
Edit2: So not exactly sure what the issue was, but after removing the node_modules from testCLI folder, reinstalling just the necessary node_modules, then running "yarn test" seemed to resolve the issue. I am still not sure what exactly caused this.