Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: jsdoc #70

Merged
merged 3 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 62 additions & 12 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 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
Loading