Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

nestjs-console

Package Overview
Dependencies
Maintainers
1
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nestjs-console - npm Package Compare versions

Comparing version 1.2.0 to 2.0.0-rc2

lib/bootstrap/abstract.d.ts

6

CHANGELOG.md

@@ -11,3 +11,3 @@ # Changelog

- Move commander as Peer Dependencies
- Move commander as Peer Dependency
- Update to support commander@^3.0.0

@@ -81,4 +81,4 @@

[unreleased]: https://github.com/Pop-Code/nestjs-console/compare/v1.2.0...HEAD
[1.1.4]: https://github.com/Pop-Code/nestjs-console/compare/v1.0.3...v1.1.4
[1.0.3]: https://github.com/Pop-Code/nestjs-console/compare/v1.0.2...v1.0.3
[1.2.0]: https://github.com/Pop-Code/nestjs-console/compare/v1.1.4...v1.2.0
[1.1.4]: https://github.com/Pop-Code/nestjs-console/compare/v1.0.2...v1.1.4
[1.0.2]: https://github.com/Pop-Code/nestjs-console/compare/v1.0.1...v1.0.2

@@ -85,0 +85,0 @@ [1.0.1]: https://github.com/Pop-Code/nestjs-console/compare/v1.0.0...v1.0.1

@@ -6,5 +6,3 @@ import { ConsoleService } from './service';

contextOptions?: NestApplicationContextOptions;
service?: {
new (...args: any[]): ConsoleService;
};
service?: new (...args: any[]) => ConsoleService;
withContainer?: boolean;

@@ -15,5 +13,5 @@ }

app: import("@nestjs/common").INestApplicationContext;
boot(argv?: string[]): import("./commander").ICommand;
boot(argv?: string[]): import("commander").CommanderStatic.Command;
}>;
static createAppContext(options: BootstrapConsoleOptions): Promise<import("@nestjs/common").INestApplicationContext>;
}
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());

@@ -24,3 +25,3 @@ });

const appModule = app.get(module_1.ConsoleModule);
appModule.scan(app, options.module);
appModule.scan(app, [options.module]);
return {

@@ -27,0 +28,0 @@ app,

@@ -1,6 +0,7 @@

import * as commander from 'commander';
export interface ICommand extends commander.Command {
forwardSubCommands(): ICommand;
import { Command } from 'commander';
export declare class CommandError extends Error {
readonly command: Command;
constructor(message: string, command: Command);
}
declare function forwardSubCommands(): ICommand;
export { commander, forwardSubCommands };
export declare function createCli(): import("commander").Command;
export declare function onSubCommand(command: Command, args: string[], unknown: string[]): void;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const commander = require("commander");
exports.commander = commander;
function forwardSubCommands() {
if (this._args.length > 0) {
throw new Error('Sub commands cannot be applied to command with explicit args');
const commander_1 = require("commander");
class CommandError extends Error {
constructor(message, command) {
super(message);
this.command = command;
}
const listener = (args, unknown) => {
args = args || [];
unknown = unknown || [];
const parsed = this.parseOptions(unknown);
if (parsed.args.length) {
args = parsed.args.concat(args);
}
if (!args.length) {
this.help();
process.exit(0);
}
unknown = parsed.unknown;
this.parseArgs(args, unknown);
};
const parent = this.parent || this;
const name = parent === this ? '*' : this._name;
parent.on('command:' + name, listener.bind(this));
if (this._alias) {
parent.on('command:' + this._alias, listener.bind(this));
}
exports.CommandError = CommandError;
function createCli() {
const cli = new commander_1.Command();
cli.on('command:*', (args, unknown) => {
throw new CommandError(`"${args[0]}" command not found`, cli);
});
return cli;
}
exports.createCli = createCli;
function onSubCommand(command, args, unknown) {
const commandArgs = command.parseOptions(args.concat(unknown));
command.parseArgs(commandArgs.args, commandArgs.unknown);
if (commandArgs.unknown.length === 0 && commandArgs.args.length === 0) {
command.help();
}
return this;
}
exports.forwardSubCommands = forwardSubCommands;
commander.Command.prototype.forwardSubcommands = forwardSubCommands;
exports.onSubCommand = onSubCommand;
//# sourceMappingURL=commander.js.map

@@ -1,4 +0,22 @@

import { ICommandDecoratorOptions, IConsoleOptions } from './interfaces';
export declare const InjectCommander: () => (target: Object, key: string | symbol, index?: number) => void;
export declare const Command: (options: ICommandDecoratorOptions) => (target: any, method: string | symbol) => void;
export declare const Console: (options?: IConsoleOptions) => (target: any) => void;
import { CommandOptions } from 'commander';
export declare function InjectCommander(): (target: Object, key: string | symbol, index?: number) => void;
export interface ICommandOptions {
flags: string;
description?: string;
fn?: ((arg1: any, arg2: any) => void) | RegExp;
defaultValue?: any;
}
export interface ICommandDecoratorOptions {
command: string;
description?: string;
alias?: string;
options?: ICommandOptions[];
commandOptions?: CommandOptions;
}
export declare function Command(options: ICommandDecoratorOptions): (target: any, method: string | symbol) => void;
export interface IConsoleOptions {
name?: string;
description?: string;
alias?: string;
}
export declare function Console(options?: IConsoleOptions): (target: any) => void;

@@ -5,9 +5,14 @@ "use strict";

const constants_1 = require("./constants");
exports.InjectCommander = () => {
function InjectCommander() {
return common_1.Inject(constants_1.COMMANDER_SERVICE_TOKEN);
};
exports.Command = (options) => {
}
exports.InjectCommander = InjectCommander;
function Command(options) {
return (target, method) => Reflect.defineMetadata(constants_1.COMMAND_METADATA_NAME, options, target, method);
};
exports.Console = (options) => (target) => Reflect.defineMetadata(constants_1.CONSOLE_METADATA_NAME, options || {}, target);
}
exports.Command = Command;
function Console(options) {
return (target) => Reflect.defineMetadata(constants_1.CONSOLE_METADATA_NAME, options || {}, target);
}
exports.Console = Console;
//# sourceMappingURL=decorators.js.map

@@ -1,8 +0,10 @@

export * from './bootstrap';
export { ICommand } from './commander';
export * from './bootstrap/abstract';
export * from './bootstrap/console';
export * from './bootstrap/server';
export * from './commands/application-manager';
export * from './constants';
export * from './decorators';
export * from './interfaces';
export * from './helpers';
export * from './module';
export * from './scanner';
export * from './service';

@@ -6,5 +6,9 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
__export(require("./bootstrap"));
__export(require("./bootstrap/abstract"));
__export(require("./bootstrap/console"));
__export(require("./bootstrap/server"));
__export(require("./commands/application-manager"));
__export(require("./constants"));
__export(require("./decorators"));
__export(require("./helpers"));
__export(require("./module"));

@@ -11,0 +15,0 @@ __export(require("./scanner"));

@@ -8,3 +8,3 @@ import { INestApplicationContext } from '@nestjs/common';

constructor(service: ConsoleService);
scan(app: INestApplicationContext, includedModules?: Function[]): void;
scan(app: INestApplicationContext, includedModules?: any[]): void;
}

@@ -19,3 +19,5 @@ "use strict";

provide: constants_1.COMMANDER_SERVICE_TOKEN,
useValue: new commander_1.commander.Command()
useFactory: () => {
return commander_1.createCli();
}
};

@@ -29,14 +31,19 @@ let ConsoleModule = class ConsoleModule {

const scanResponse = this.scanner.scan(app, includedModules);
let cli = this.service.getCli();
const cli = this.service.getCli();
scanResponse.forEach(({ methods, instance, metadata }) => {
let parent = cli;
if (metadata.name) {
instance._cli = this.service.subCommands(cli, metadata.name, metadata.description);
parent = this.service.getCli(metadata.name);
if (!parent) {
parent = this.service.createSubCommand(metadata, cli);
}
}
else {
instance._cli = cli;
}
for (const method of methods) {
const command = instance._cli
.command(method.metadata.command, null, method.metadata.commandOptions)
.description(method.metadata.description);
const command = parent.command(method.metadata.command);
if (method.metadata.description) {
command.description(method.metadata.description);
}
if (method.metadata.alias) {
command.alias(method.metadata.alias);
}
if (Symbol.iterator in Object(method.metadata.options)) {

@@ -43,0 +50,0 @@ for (const opt of method.metadata.options) {

@@ -1,6 +0,16 @@

import { IScanResponse } from './interfaces';
import { IConsoleOptions, ICommandDecoratorOptions } from './decorators';
import { INestApplicationContext } from '@nestjs/common';
export interface IMethodsMetadata {
name: string;
metadata: ICommandDecoratorOptions;
}
export interface IScanResponse {
instance: any;
metadata: IConsoleOptions;
methods: IMethodsMetadata[];
}
export declare class ConsoleScanner {
private getModules;
private getInstanceMethods;
scan(app: any, includedModules?: Function[]): Set<IScanResponse>;
scan(app: INestApplicationContext, includedModules?: any[]): Set<IScanResponse>;
}

@@ -25,4 +25,5 @@ "use strict";

const { metatype, name } = p;
if (typeof metatype !== 'function')
if (typeof metatype !== 'function') {
return;
}
const consoleMetadata = Reflect.getMetadata(constants_1.CONSOLE_METADATA_NAME, metatype);

@@ -34,5 +35,5 @@ if (!consoleMetadata) {

const methods = this.getInstanceMethods(instance);
const methodsMetadata = methods.map(m => ({
name: m,
metadata: Reflect.getMetadata(constants_1.COMMAND_METADATA_NAME, instance, m)
const methodsMetadata = methods.map(methodMetadata => ({
name: methodMetadata,
metadata: Reflect.getMetadata(constants_1.COMMAND_METADATA_NAME, instance, methodMetadata)
}));

@@ -39,0 +40,0 @@ set.add({

import { INestApplicationContext } from '@nestjs/common';
import * as ora from 'ora';
import { ICommand } from './commander';
import { IWithApplicationContext } from './interfaces';
export declare class ConsoleService implements IWithApplicationContext {
protected readonly cli: ICommand;
import { Command } from 'commander';
import { IConsoleOptions } from './decorators';
export declare class ConsoleService {
protected cli: Command;
protected container: INestApplicationContext;
constructor(cli: ICommand);
static createSpinner(text?: string): ora.Ora;
getCli(): ICommand;
setContainer(container: INestApplicationContext): IWithApplicationContext;
protected commands: Map<string, Command>;
constructor(cli: Command);
resetCli(): void;
displayErrorWithHelp(command: Command, error: Error): never;
displayFatalError(command: Command, error: Error): boolean;
getCli(name?: string): Command;
setContainer(container: INestApplicationContext): ConsoleService;
getContainer(): INestApplicationContext;
init(argv: string[]): ICommand;
subCommands(parent: ICommand, command: string, description: string): ICommand;
init(argv: string[]): Command;
createSubCommand(options: IConsoleOptions, parent: Command): Command;
}

@@ -16,15 +16,24 @@ "use strict";

const common_1 = require("@nestjs/common");
const ora = require("ora");
const commander_1 = require("./commander");
const commander_1 = require("commander");
const commander_2 = require("./commander");
const decorators_1 = require("./decorators");
const helpers_1 = require("./helpers");
let ConsoleService = class ConsoleService {
constructor(cli) {
this.cli = cli;
this.commands = new Map();
}
static createSpinner(text) {
return ora.default(text);
resetCli() {
this.cli = commander_2.createCli();
}
getCli() {
return this.cli;
displayErrorWithHelp(command, error) {
return command.help((h) => `${helpers_1.formatResponse(error)}\n${h}`);
}
displayFatalError(command, error) {
command.exitOverride();
return process.stdout.write(helpers_1.formatResponse(error));
}
getCli(name) {
return name ? this.commands.get(name) : this.cli;
}
setContainer(container) {

@@ -38,14 +47,43 @@ this.container = container;

init(argv) {
this.cli.on('command:*', () => {
this.cli.help();
});
const args = this.cli.parse(argv);
if (argv.length === 2) {
this.cli.help();
const cli = this.getCli();
try {
if (cli.commands.length === 0) {
this.displayFatalError(cli, new commander_2.CommandError(`The cli does not contains subcommand`, cli));
return process.exit(1);
}
const command = cli.parse(argv);
command.help();
return command;
}
return args;
catch (e) {
if (e instanceof commander_2.CommandError) {
this.displayErrorWithHelp(e.command, e);
return process.exit(1);
}
else {
throw e;
}
}
}
subCommands(parent, command, description) {
const subCommand = parent.command(command).description(description);
return commander_1.forwardSubCommands.bind(subCommand)();
createSubCommand(options, parent) {
if (parent._args.length > 0) {
throw new Error('Sub commands cannot be applied to command with explicit args');
}
const command = parent
.command(options.name)
.description(options.description)
.alias(options.alias);
const name = command.name();
const _onSubCommand = (args, unknown) => {
commander_2.onSubCommand(command, args, unknown);
};
parent.on('command:' + name, _onSubCommand);
if (options.alias) {
parent.on('command:' + options.alias, _onSubCommand);
}
command.on('command:*', (args) => {
throw new commander_2.CommandError(`"${args[0]}" command not found`, command);
});
this.commands.set(name, command);
return command;
}

@@ -56,5 +94,5 @@ };

__param(0, decorators_1.InjectCommander()),
__metadata("design:paramtypes", [Object])
__metadata("design:paramtypes", [commander_1.Command])
], ConsoleService);
exports.ConsoleService = ConsoleService;
//# sourceMappingURL=service.js.map
{
"name": "nestjs-console",
"version": "1.2.0",
"version": "2.0.0-rc2",
"description": "A NestJS module that provide a cli",

@@ -20,28 +20,36 @@ "keywords": [

"@nestjs/core": "^6",
"commander": "^3.0.0"
"commander": "^4.0.1"
},
"dependencies": {
"ora": "^3.4.0"
"lodash": "4.17.15",
"ora": "4.0.3",
"prettier": "1.19.1"
},
"devDependencies": {
"@nestjs/common": "6.5.3",
"@nestjs/core": "6.5.3",
"@nestjs/testing": "6.5.3",
"@types/jest": "24.0.17",
"@types/node": "^12.7.1",
"@types/ora": "3.2.0",
"codecov": "3.5.0",
"commander": "3.0.0",
"jest": "24.8.0",
"@nestjs/common": "6.10.13",
"@nestjs/core": "6.10.13",
"@nestjs/platform-express": "6.10.13",
"@nestjs/testing": "6.10.13",
"@types/jest": "24.0.25",
"@types/node": "13.1.2",
"@types/prettier": "1.19.0",
"codecov": "3.6.1",
"commander": "4.0.1",
"jest": "24.9.0",
"reflect-metadata": "0.1.13",
"rxjs": "6.5.2",
"ts-jest": "24.0.2",
"ts-node": "8.3.0",
"tsconfig-paths": "3.8.0",
"typedoc": "0.15.0",
"typescript": "3.5.3"
"rxjs": "6.5.4",
"ts-jest": "24.2.0",
"ts-node": "8.5.4",
"tsconfig-paths": "3.9.0",
"tslint": "5.20.1",
"typedoc": "0.15.6",
"typescript": "3.7.4"
},
"scripts": {
"build": "rm -Rf ./lib && tsc",
"build": "rm -Rf ./lib && tsc -b",
"doc": "rm -Rf ./docs && typedoc ./src && touch ./docs/.nojekyll",
"console": "node lib/test/console.js",
"console:dev": "ts-node -r tsconfig-paths/register src/test/console.ts",
"console:server": "node lib/test/console-server.js",
"console:server:dev": "ts-node -r tsconfig-paths/register src/test/console-server.ts",
"test:ci": "jest --runInBand",

@@ -51,4 +59,5 @@ "test": "jest",

"test:cov": "jest --coverage --runInBand",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand"
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"lint": "tslint -c tslint.json -t verbose 'src/**/*.{ts,js}'"
}
}

@@ -46,9 +46,7 @@ [![nestjs-console](https://raw.githubusercontent.com/Pop-Code/nestjs-console/master/resources/logo-frame.png)][npm]

BootstrapConsole.init({ module: MyModule })
.then(({ app, boot }) => {
// do something with your app container if you need (app)
// boot the cli
boot(/*process.argv*/);
})
.catch(e => console.log('Error', e));
BootstrapConsole.init({ module: MyModule }).then(({ app, boot }) => {
// do something with your app container if you need (app)
// boot the cli
boot(/*process.argv*/);
});
```

@@ -77,8 +75,6 @@

There are 2 ways of registering providers methods to the console.
Using decorators (>=v1.1) or using the _ConsoleService_.
Using @decorators (>=v1.1 and >=v2 for multi dimensions) or using the _ConsoleService_.
At the moment, it's not possible to have more than 2 dimensions in the commands stack using decorators.
Example of cli stack
Example of possible cli stack using decorators
```

@@ -91,16 +87,2 @@ Cli -> Command_A -> [

Command_B1 -> execution,
Command_B2 -> execution
]
-> Command_C -> execution
```
Example of possible cli stack using the ConsoleService (More flexible, Multi dimensions)
```
Cli -> Command_A -> [
Command_A1 -> execution,
Command_A2 -> execution
]
-> Command_B -> [
Command_B1 -> execution,
Command_B2 -> [

@@ -116,3 +98,3 @@ Command_B2_a -> execution

As an example, we will define a cli with 2 commands (new and list), one of the command (new) will have 2 sub commands (directory and file)
As a simple example, we will define a cli with 2 commands (new and list), one of the command (new) will have 2 sub commands (directory and file)

@@ -134,3 +116,3 @@ ```

// service.ts - a nestjs provider using console decorators
import { Console, Command } from 'nestjs-console';
import { Console, Command, createSpinner } from 'nestjs-console';

@@ -145,3 +127,3 @@ @Console()

// See Ora npm package for details about spinner
const spin = this.consoleService.createSpinner();
const spin = createSpinner();
spin.start(`Listing files in directory ${directory}`);

@@ -151,5 +133,3 @@

const files = await new Promise(done =>
setTimeout(() => {
done(['fileA', 'fileB']);
}, 1000)
setTimeout(() => done(['fileA', 'fileB']), 1000)
);

@@ -226,6 +206,2 @@

constructor(private readonly consoleService: ConsoleService) {
this.listContent = this.listContent.bind(this);
this.createFile = this.createFile.bind(this);
this.createDirectory = this.createDirectory.bind(this);
// get the root cli

@@ -259,18 +235,18 @@ const cli = this.consoleService.getCli();

async listContent(directory: string): void | Promise<void> {
listContent = async (directory: string): void | Promise<void> => {
console.log(`Listing files in directory ${directory}`);
// your code...
process.exit(0); // it's important to exit the process.
}
};
async createFile(name: string): void | Promise<void> {
createFile = async (name: string): void | Promise<void> => {
console.log(`Creating a file named ${name}`);
process.exit(0); // it's important to exit the process.
}
};
async createDirectory(name: string): void | Promise<void> {
createDirectory = async (name: string): void | Promise<void> => {
console.log(`Creating a directory named ${name}`);
// your code...
process.exit(0); // it's important to exit the process.
}
};
}

@@ -329,21 +305,2 @@ ```

### Create a Custom ConsoleService
You can create any number of custom ConsoleService and any nummber of entrypoints (BootstrapConsole).
The Commander provider can be injected using the decorators `@InjectCommander()`.
The decorator can be imported from nestjs-console `import { InjectCommander } from 'nestjs-console';
```ts
import { Injectable } from '@nestjs/common';
import { InjectCommander, Command, ConsoleService } from 'nestjs-console';
@Injectable()
export class CustomConsole extends ConsoleService {
constructor(@InjectCommander() protected readonly cli: Command) {
super(cli);
// do something with the cli, instance of npm commander
}
}
```
### [API DOCUMENTATION][doclink]

@@ -350,0 +307,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc