@athenna/core
Version:
One foundation for multiple applications.
125 lines (124 loc) • 3.3 kB
JavaScript
/**
* @athenna/core
*
* (c) João Lenon <lenon@athenna.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { Is, Module, Options, String } from '@athenna/common';
import { CommandBuilder } from '#src/repl/helpers/CommandBuilder';
export class ReplImpl {
/**
* Start the repl session.
*/
async start(options) {
options = Options.create(options, {
prompt: ''
});
const { start } = await this.importRepl();
this.session = start(options);
return this.session;
}
/**
* Shutdown all Athenna providers on exit.
*/
shutdownProviders() {
this.session?.on('exit', async () => {
process.exit(0);
});
return this;
}
/**
* Define a command in the repl session.
*/
command(signature) {
return new CommandBuilder(signature, this.session);
}
/**
* Define a command using the implementation class.
*/
commandImpl(command) {
this.command(command.signature())
.help(command.help())
.action(command.action)
.register();
return this;
}
/**
* Display the repl prompt.
*/
displayPrompt(preserveCursor) {
this.session.displayPrompt(preserveCursor);
return this;
}
/**
* Set a different prompt to the repl session.
*/
setPrompt(prompt) {
this.session.setPrompt(prompt);
return this;
}
/**
* Write some message in the repl session.
*/
write(message, key) {
this.session.write(message, key);
return this;
}
/**
* Clean the repl session content by simulating
* pressing CTRL + L.
*/
clean() {
return this.write('', { ctrl: true, name: 'l' });
}
/**
* Remove the domain error handler from the repl session.
*/
removeDomainErrorHandler() {
this.write('delete process?.domain?._events?.error\n');
return this;
}
/**
* Set a key value in the repl context.
*/
setInContext(key, value) {
this.session.context[key] = value;
return this;
}
/**
* Import a module in the repl session.
*/
async import(key, path) {
this.setInContext(key, await import(path));
}
/**
* Import a module and register all it properties
* in the repl context.
*/
async importAll(path) {
let module = await Module.resolve(path, Config.get('rc.parentURL'), {
import: true,
getModule: false
});
if (module.default && Object.keys(module).length === 1) {
module = module.default;
}
if (Is.String(module) || !Object.keys(module).length) {
let key = module.name;
if (!key || key === 'default') {
key = String.toCamelCase(path.split('/').pop());
}
this.setInContext(key, module);
return;
}
Object.keys(module).forEach(key => this.setInContext(key, module[key]));
}
/**
* Import the repl module.
*/
async importRepl() {
return await import('pretty-repl');
}
}