Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/bmstefanski/nestjs-shell
π An interactive shell for NestJS which allows you to plug-in your custom commands and use them when the app's running
https://github.com/bmstefanski/nestjs-shell
console javascript nest nestjs nestjs-library nestjs-module nodejs shell terminal typescript
Last synced: 3 days ago
JSON representation
π An interactive shell for NestJS which allows you to plug-in your custom commands and use them when the app's running
- Host: GitHub
- URL: https://github.com/bmstefanski/nestjs-shell
- Owner: bmstefanski
- License: mit
- Created: 2020-05-27T12:52:00.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2023-07-18T22:26:29.000Z (over 1 year ago)
- Last Synced: 2024-04-22T21:10:36.974Z (7 months ago)
- Topics: console, javascript, nest, nestjs, nestjs-library, nestjs-module, nodejs, shell, terminal, typescript
- Language: TypeScript
- Homepage:
- Size: 1.49 MB
- Stars: 47
- Watchers: 3
- Forks: 0
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-javascript - nestjs-shell - in your custom commands and use them when the app's running (Packages)
- awesome-javascript - nestjs-shell - in your custom commands and use them when the app's running (Packages)
README
NestJS Shell
## Description
I wanted to create as simple as possible API without redundant use cases. Which allows you to create a simple command in less than a minute (counting installation time).
Currently, there are a few libraries that provide something similar to this, but they violate your app's execution file with their code and require you to re-run the app's instance every time you want to execute a command.
So I decided to give you full control of where and when shell's instance should start and a way to execute commands in runtime.For more examples, go there: https://github.com/bmstefanski/nestjs-shell-example
## Features
- [x] π Non-blocking runtime console
- [x] π No dependencies
- [x] π€ Simple and stable API
- [x] π‘οΈ Well tested
- [x] π₯οΈ Modifiable error messages and prompt sign
- [x] π¨οΈ Elastic output printer (you can write own printer or use any logger you want)
- [x] π Optional, required and varargs parameters
- [ ] π Travis or GitHub Actions based CI## Installation
```
# production use
$ yarn add nestjs-shell# development use
$ yarn add -D nestjs-shell
```## Usage
##### Execution and registration
```typescript
import { ShellModule, ShellFacade } from 'nestjs-shell'// `ShellModule` is Global, so please put it only in your main module and it will work flawlessly in others.
@Module({ imports: [ShellModule] })
export class YourAppMainModule implements OnApplicationBootstrap {
constructor(private readonly shellFacade: ShellFacade) {}public async onApplicationBootstrap(): Promise {
// You can use it without passing any arguments and use default configuration or configure it in your own way.
await this.shellFacade.bootstrap()// It does not have to be here, you can register components anywhere you want and as many times as you need.
this.shellFacade.registerComponents(
new SayCommandComponent(),
new AnotherSecondTestCommandComponent(new SomeDependency()),
)
}
}
```##### Simple example with required, optional and varargs parameters
```typescript
import { ShellCommand, ShellComponent } from 'nestjs-shell'/* Please do not put @Injectable() or any other decorator that creates a new instance of a class,
it may cause bugs and it is definitely not going to work the way you want.
*/
export class SayCommandComponent extends ShellComponent {/* Only `name` property is required, so by default you have no prefix, no description and no pattern
and it works fine!
*/
/* Pattern ideology is simple:
if your parameter name is wrapped with `<` and `>` then it's required
if your parameter name is wrapped with `[` and `]` then it's optional
if there is `@` sign inside any brackets (`[` or `<`) then it's varargs.
Same as in JavaScript varargs, they can only be placed in the last parameter.
*/
@ShellCommand({
name: 'say',
prefix: '.',
description: 'Sends a message to the console',
pattern: ' [@message]',
})
public async sayCommand(sender: string, message: string): Promise {
return `${sender} says: ${message || 'Nothing'}`
}// There is no limit to the amount of commands in one ShellComponent.
@ShellCommand({
name: 'said',
prefix: '/',
description: 'Sends a message to the console that has been said',
pattern: ' <@message>',
})
/* You don't have to keep function's parameters in the same order as pattern ones.
They are applied by name, not order.
*/
public async saidCommand(sender: string, message: string): Promise {
return `${sender} said: ${message}`
}
}
```##### Constructor dependencies
```typescript
import { ShellCommand, ShellComponent } from 'nestjs-shell'export class AnotherSecondTestCommandComponent extends ShellComponent {
constructor(private readonly someDependency: TestDependency) {
super()
}/* You can use as much prefixes as you want..
if you do not specify any then it uses the default, which is '' (empty string)
*/
@ShellCommand({
name: '.help',
description: 'Displays all commands with description and usage',
})
public async help(): Promise {
// Method's execution context is ALWAYS set to the actual class instance and so `this` keyword works as expected.
return [
'Here are all available commands: ',
'-------------------------------------',
...this.someDependency,
...this.shellFacade.getAllCommands().map((command) => {
return `-> ${command.name} ${command.pattern} - ${command.description || 'Description not available'}`
}),
'-------------------------------------',
].join('\n')
}
}
```## API specification
The library shares its methods through the facade, named `ShellFacade`. In the table below, you can see a brief description of each method.
```typescript
import { ShellFacade } from 'nestjs-shell'
```| Method | Description | Arguments |
| :------------------- | :-------------------------------------------------------------------: | :-------------------------------: |
| `bootstrap` | Enables terminal | `BootstrapOptions` |
| `registerComponents` | Adds command components to the registry | `...components: ShellComponent[]` |
| `getAllCommands` | Returns immutable (or to be more precise: deep copy of a) collection) | naught |```typescript
type BootstrapOptions = {
prompt?: string = 'β€³'
messages?: { notFound?: string; wrongUsage?: string } = {
notFound: 'Say what? I might have heard $input',
wrongUsage: 'Wrong usage: $command $pattern',
}
shellPrinter?: ((value: any) => void) = (value: any) => console.log(value)
}
```## Contributions and license
> **Note:** If you want to contribute, please keep in mind that I don't want to support various use cases, it should remain as simple as it is. So if you desire to improve code rather than add features, then I would greatly appreciate it ππ»ππΌππ½ππΎππΏ.
Nestjs-shell is [MIT licensed](LICENSE)