Skip to content

Commit

Permalink
feat: jsdoc
Browse files Browse the repository at this point in the history
  • Loading branch information
AbigailDeng authored and AbigailDeng committed Jul 1, 2024
1 parent 53555f4 commit fac80f7
Show file tree
Hide file tree
Showing 30 changed files with 893 additions and 192 deletions.
78 changes: 64 additions & 14 deletions src/command/baseSubCommand.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
/**
* @file base sub command
* @author atom-yang
*/
import { interopImportCJSDefault } from 'node-cjs-interop';
import asyncValidator from 'async-validator';
const Schema = interopImportCJSDefault(asyncValidator);

import inquirer from 'inquirer';
import ora from 'ora';
import { logger } from '../utils/myLogger.js';
Expand All @@ -16,17 +13,25 @@ import { globalOptionsPrompts, strictGlobalOptionValidatorDesc } from '../utils/
const defaultOraOptions = {
text: 'AElf loading...'
};
/**
* @typedef {import('commander').Command} Command
* @typedef {import('ora').Options} OraOptions
* @typedef {import('../../types/rc/index.js').default} Registry
*/

/**
* @class
*/
class BaseSubCommand {
/**
* @param {string} commandName sub command name
* @param {Object[]} parameters sub command parameters
* @param {{ [key: string]: any }[]} parameters sub command parameters
* @param {string} description sub command description
* @param {Object[]} options sub command options
* @param {{ [key: string]: any }[]} options sub command options
* @param {string[]} usage make examples
* @param {Registry} rc instance of Registry
* @param {Object} validatorDesc rules of async-validator
* @param {Object} oraOptions an ora options
* @param {{ [key: string]: any }} validatorDesc rules of async-validator
* @param {{ [key: string]: any }} oraOptions an ora options
*/
constructor(
commandName,
Expand Down Expand Up @@ -54,11 +59,17 @@ class BaseSubCommand {
};
});
}

/**
* Sets custom prompts.
* @param {any} val - The value to set for custom prompts.
*/
setCustomPrompts(val) {
this.customPrompts = val;
}

/**
* Initializes the sub command with commander.
* @param {Command} commander - The commander instance.
*/
init(commander) {
let command = commander.command(`${this.commandName} ${this.getParameters()}`).description(this.description);

Expand All @@ -79,6 +90,10 @@ class BaseSubCommand {
});
}

/**
* Retrieves parameters as a string.
* @returns {string} Parameters string.
*/
getParameters() {
return this.parameters
.map(v => {
Expand All @@ -89,12 +104,23 @@ class BaseSubCommand {
.join(' ');
}

/**
* Handles errors related to universal options.
* @param {any} error - The error to handle.
*/
handleUniOptionsError(error) {
const { errors = [] } = error;
// @ts-ignore
logger.error(errors.reduce((acc, i) => `${acc}${i.message}\n`, ''));
process.exit(1);
}

/**
* Retrieves universal configuration.
* @static
* @param {Command} commander - The commander instance.
* @returns {Record<string, any>} Universal configuration.
*/
static getUniConfig(commander) {
const result = {};
['password', 'endpoint', 'account', 'datadir'].forEach(v => {
Expand All @@ -106,6 +132,12 @@ class BaseSubCommand {
return result;
}

/**
* Parses a boolean value.
* @static
* @param {any} val - The value to parse.
* @returns {any} Parsed boolean value.
*/
static parseBoolean(val) {
if (val === 'true') {
return true;
Expand All @@ -116,6 +148,12 @@ class BaseSubCommand {
return val;
}

/**
* Normalizes configuration object.
* @static
* @param {any} obj - The configuration object to normalize.
* @returns {Record<string, any>} Normalized configuration object.
*/
static normalizeConfig(obj) {
// dash to camel-case
// 'true', 'false' to true, false
Expand All @@ -128,7 +166,16 @@ class BaseSubCommand {
});
return result;
}

/**
* Runs the sub command.
* @param {Command} commander - The commander instance.
* @param {...any} args - Additional arguments.
* @returns {Promise<{
* localOptions: { [key: string]: any },
* options: { [key: string]: any },
* subOptions: { [key: string]: any }
* } | void>} Promise resolving to options or void.
*/
async run(commander, ...args) {
let subCommandOptions = {};
args.slice(0, this.parameters.length).forEach((v, i) => {
Expand All @@ -141,7 +188,7 @@ class BaseSubCommand {
const lastArg = args.slice(this.parameters.length)[0];
const localOptions = {};
this.options.forEach(({ name }) => {
localOptions[name] = lastArg?.[name] || undefined;
localOptions[name] = lastArg[name] || undefined;
});
const uniOptions = BaseSubCommand.getUniConfig(commander);
// get options from global config and process.argv
Expand All @@ -152,7 +199,7 @@ class BaseSubCommand {
});

const globalPrompts = globalOptionsPrompts.filter(
prompt => this.validatorDesc[prompt.name]?.required && !options[prompt.name]
prompt => this.validatorDesc[prompt.name].required && !options[prompt.name]
);
const globalPromptsAns = await inquirer.prompt(globalPrompts);
options = {
Expand Down Expand Up @@ -188,7 +235,10 @@ class BaseSubCommand {
subOptions: subCommandOptions
};
}

/**
* Generates examples for usage.
* @returns {string[]} Array of example strings.
*/
makeExamples() {
return this.usage.map(cmd => `aelf-command ${this.commandName} ${cmd}`);
}
Expand Down
42 changes: 36 additions & 6 deletions src/command/call.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
/**
* @file call read-only method on contract
* @author atom-yang
*/
import AElf from 'aelf-sdk';
import inquirer from 'inquirer';
import chalk from 'chalk';
Expand All @@ -18,7 +14,21 @@ import {
import { getWallet } from '../utils/wallet.js';
import { logger } from '../utils/myLogger.js';

/**
* @typedef {import('commander').Command} Command
* @typedef {import('ora').Options} OraOptions
* @typedef {import('../../types/rc/index.js').default} Registry
*/
class CallCommand extends BaseSubCommand {
/**
* Creates an instance of CallCommand.
* @param {Registry} rc The instance of the Registry.
* @param {string} [name] The name of the command.
* @param {string} [description] The description of the command.
* @param {Object[]} [parameters] The parameters for the command.
* @param {string[]} [usage] The usage examples for the command.
* @param {any[]} [options] The options for the command.
*/
constructor(
rc,
name = 'call',
Expand All @@ -29,22 +39,40 @@ class CallCommand extends BaseSubCommand {
) {
super(name, parameters, description, options, usage, rc);
}

/**
* Calls a method with specified parameters.
* @param {any} method The method to call.
* @param {any} params The parameters for the method call.
* @returns {Promise<any>} A promise that resolves with the result of the method call.
*/
async callMethod(method, params) {
this.oraInstance.start('Calling method...');
const result = await method.call(params);
this.oraInstance.succeed('Calling method successfully!');
return result;
}

/**
* Processes address after prompting for input.
* @param {any} aelf The AElf instance.
* @param {any} wallet The wallet instance.
* @param {Object.<string, any>} answerInput The input parameters.
* @returns {Promise<any>} A promise that resolves with the processed result.
*/
async processAddressAfterPrompt(aelf, wallet, answerInput) {
let { contractAddress } = BaseSubCommand.normalizeConfig(answerInput);
contractAddress = await getContractInstance(contractAddress, aelf, wallet, this.oraInstance);
return contractAddress;
}

/**
* Runs the command.
* @param {Command} commander The Commander instance.
* @param {...any[]} args Additional arguments passed to the command.
* @returns {Promise<void>} A promise that resolves when the command execution completes.
*/
async run(commander, ...args) {
this.setCustomPrompts(true);
// @ts-ignore
const { options, subOptions } = await super.run(commander, ...args);
const subOptionsLength = Object.keys(subOptions).length;
const { endpoint, datadir, account, password } = options;
Expand Down Expand Up @@ -102,10 +130,12 @@ class CallCommand extends BaseSubCommand {
params = '';
}
const result = await this.callMethod(method, params);
// @ts-ignore
logger.info(`\nResult:\n${JSON.stringify(result, null, 2)}`);
this.oraInstance.succeed('Succeed!');
} catch (e) {
this.oraInstance.fail('Failed!');
// @ts-ignore
logger.fatal(e);
}
}
Expand Down
36 changes: 30 additions & 6 deletions src/command/config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
/**
* @file get block height
* @author atom-yang
*/
import { interopImportCJSDefault } from 'node-cjs-interop';
import asyncValidator from 'async-validator';
const Schema = interopImportCJSDefault(asyncValidator);
Expand All @@ -17,7 +13,17 @@ const configCommandValidatorDesc = {
}
};

/**
* @typedef {import('commander').Command} Command
* @typedef {import('async-validator').Rules} Rules
* @typedef {import('async-validator').Values} Values
* @typedef {import('../../types/rc/index.js').default} Registry
*/
class ConfigCommand extends BaseSubCommand {
/**
* Constructs a new ConfigCommand instance.
* @param {Registry} rc - The registry instance.
*/
constructor(rc) {
super(
'config',
Expand All @@ -29,7 +35,12 @@ class ConfigCommand extends BaseSubCommand {
configCommandValidatorDesc
);
}

/**
* Validates parameters based on the provided rules.
* @param {Rules} rule - The validation rules.
* @param {Values} parameters - The parameters to validate.
* @returns {Promise<void>} A promise that resolves when the validation is complete.
*/
async validateParameters(rule, parameters) {
const validator = new Schema(rule);
try {
Expand All @@ -39,6 +50,11 @@ class ConfigCommand extends BaseSubCommand {
}
}

/**
* Handles the list operation and returns the processed content as a string.
* @param {any} content - The content to process.
* @returns {string} The processed content.
*/
handleList(content) {
return Object.entries(content)
.filter(([, value]) => {
Expand All @@ -50,9 +66,15 @@ class ConfigCommand extends BaseSubCommand {
.map(([key, value]) => `${key}=${value}\n`)
.join('');
}

/**
* Executes the command.
* @param {Command} commander - The commander instance.
* @param {...any} args - Additional arguments.
* @returns {Promise<void>} A promise that resolves when the command execution is complete.
*/
async run(commander, ...args) {
this.setCustomPrompts(true);
// @ts-ignore
const { subOptions } = await super.run(commander, ...args);
// todo: specified which .aelfrc file to read or write
const { flag, key, value } = subOptions;
Expand Down Expand Up @@ -85,6 +107,7 @@ class ConfigCommand extends BaseSubCommand {
switch (flag) {
case 'get':
result = this.rc.getOption(key);
// @ts-ignore
logger.info(result);
break;
case 'set':
Expand All @@ -102,6 +125,7 @@ class ConfigCommand extends BaseSubCommand {
}
} catch (e) {
this.oraInstance.fail('Failed!');
// @ts-ignore
logger.error(e);
}
}
Expand Down
24 changes: 20 additions & 4 deletions src/command/console.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
/**
* @file console command
* @author atom-yang
*/
import repl from 'repl';
import AElf from 'aelf-sdk';
import columnify from 'columnify';
Expand All @@ -10,12 +6,29 @@ import BaseSubCommand from './baseSubCommand.js';
import { getWallet } from '../utils/wallet.js';
import { logger } from '../utils/myLogger.js';

/**
* @typedef {import('commander').Command} Command
* @typedef {import('../../types/rc/index.js').default} Registry
*/
class ConsoleCommand extends BaseSubCommand {
/**
* Constructs a new ConsoleCommand instance.
* @param {Registry} rc - The registry instance.
* @param {string} [name] - The name of the command.
* @param {string} [description] - The description of the command.
*/
constructor(rc, name = 'console', description = 'Open a node REPL') {
super(name, [], description, [], [''], rc);
}

/**
* Executes the command.
* @param {Command} commander - The commander instance.
* @param {...any} args - Additional arguments.
* @returns {Promise<void>} A promise that resolves when the command execution is complete.
*/
async run(commander, ...args) {
// @ts-ignore
const { options } = await super.run(commander, ...args);
const { datadir, account, password, endpoint } = options;
try {
Expand Down Expand Up @@ -45,7 +58,9 @@ class ConsoleCommand extends BaseSubCommand {
}
}
);
// @ts-ignore
logger.info('Welcome to aelf interactive console. Ctrl + C to terminate the program. Double tap Tab to list objects');
// @ts-ignore
logger.info(
boxen(columns, {
padding: 1,
Expand All @@ -61,6 +76,7 @@ class ConsoleCommand extends BaseSubCommand {
r.context._account = wallet;
} catch (e) {
this.oraInstance.fail('Failed!');
// @ts-ignore
logger.error(e);
}
}
Expand Down
Loading

0 comments on commit fac80f7

Please sign in to comment.