bob-core 0.9.12 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## Introduction
4
4
 
5
- BOB (Bash Operation Buddy) Core is a library that provides a set of functions to create your own CLI in TypeScript.
5
+ BOB (Bash Operation Buddy) Core is a library that provides a set of functions to create your own CLI in TypeScript easily.
6
6
 
7
7
  ## Usage
8
8
 
package/dist/Cli.d.ts CHANGED
@@ -2,6 +2,11 @@ import { CommandRegistry } from "./CommandRegistry";
2
2
  import { Command } from "./Command";
3
3
  import HelpCommand from "./commands/HelpCommand";
4
4
  import { ExceptionHandler } from "./ExceptionHandler";
5
+ export type CliOptions<C> = {
6
+ ctx?: C;
7
+ name?: string;
8
+ version?: string;
9
+ };
5
10
  export declare class Cli<C> {
6
11
  readonly commandRegistry: CommandRegistry;
7
12
  private readonly exceptionHandler;
@@ -10,7 +15,7 @@ export declare class Cli<C> {
10
15
  get CommandRegistryClass(): typeof CommandRegistry;
11
16
  get HelpCommandClass(): typeof HelpCommand;
12
17
  get ExceptionHandlerClass(): typeof ExceptionHandler;
13
- constructor(ctx?: C);
18
+ constructor(opts?: CliOptions<C>);
14
19
  setCommandResolver(resolver: (path: string) => Promise<Command<C>>): void;
15
20
  withCommands(...commands: Array<Command<C> | {
16
21
  new (): Command<C>;
package/dist/Cli.js CHANGED
@@ -21,11 +21,15 @@ class Cli {
21
21
  get ExceptionHandlerClass() {
22
22
  return ExceptionHandler_1.ExceptionHandler;
23
23
  }
24
- constructor(ctx) {
25
- this.ctx = ctx;
24
+ constructor(opts = {}) {
25
+ this.ctx = opts.ctx;
26
26
  this.commandRegistry = new this.CommandRegistryClass();
27
27
  this.exceptionHandler = new this.ExceptionHandlerClass();
28
- this.helpCommand = new this.HelpCommandClass(this.commandRegistry);
28
+ this.helpCommand = new this.HelpCommandClass({
29
+ cliName: opts.name,
30
+ cliVersion: opts.version,
31
+ commandRegistry: this.commandRegistry
32
+ });
29
33
  }
30
34
  setCommandResolver(resolver) {
31
35
  this.commandRegistry.setCommandResolver(resolver);
package/dist/Command.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { CommandHelper } from "./CommandHelper";
2
- import { ArgSignature, CommandParser } from "./CommandParser";
1
+ import { CommandParser } from "./CommandParser";
2
+ import { CommandOption } from "./contracts/CommandOption";
3
3
  export type CommandExample = {
4
4
  description: string;
5
5
  command: string;
6
6
  };
7
- export declare abstract class Command<C = any> extends CommandHelper {
7
+ export declare abstract class Command<C = any> {
8
8
  abstract signature: string;
9
9
  abstract description: string;
10
10
  protected ctx: C;
@@ -15,7 +15,7 @@ export declare abstract class Command<C = any> extends CommandHelper {
15
15
  protected parser: CommandParser;
16
16
  protected abstract handle(): Promise<void | number>;
17
17
  private get CommandParserClass();
18
- protected get defaultOptions(): ArgSignature[];
18
+ protected defaultOptions(): CommandOption<Command<C>>[];
19
19
  get command(): string;
20
20
  run(ctx: C, ...args: any[]): Promise<number>;
21
21
  protected setOption(name: string, value: any): void;
package/dist/Command.js CHANGED
@@ -1,13 +1,9 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.Command = void 0;
7
- const CommandHelper_1 = require("./CommandHelper");
8
4
  const CommandParser_1 = require("./CommandParser");
9
- const chalk_1 = __importDefault(require("chalk"));
10
- class Command extends CommandHelper_1.CommandHelper {
5
+ const HelpOption_1 = require("./options/HelpOption");
6
+ class Command {
11
7
  ctx;
12
8
  helperDefinitions = {};
13
9
  commandsExamples = [];
@@ -15,16 +11,8 @@ class Command extends CommandHelper_1.CommandHelper {
15
11
  get CommandParserClass() {
16
12
  return CommandParser_1.CommandParser;
17
13
  }
18
- get defaultOptions() {
19
- return [
20
- {
21
- name: 'help',
22
- optional: true,
23
- type: 'boolean',
24
- help: (0, chalk_1.default) `Display help for the given command. When no command is given display help for the {green list} command`,
25
- alias: ['h']
26
- }
27
- ];
14
+ defaultOptions() {
15
+ return [new HelpOption_1.HelpOption];
28
16
  }
29
17
  get command() {
30
18
  if (this.parser) {
@@ -34,9 +22,15 @@ class Command extends CommandHelper_1.CommandHelper {
34
22
  }
35
23
  async run(ctx, ...args) {
36
24
  this.ctx = ctx;
37
- this.parser = new this.CommandParserClass(this.signature, this.helperDefinitions, this.defaultOptions, ...args);
38
- if (args.includes('--help') || args.includes('-h')) {
39
- return this.help.call(this);
25
+ const defaultOptions = this.defaultOptions();
26
+ this.parser = new this.CommandParserClass(this.signature, this.helperDefinitions, defaultOptions, ...args);
27
+ for (const option of defaultOptions) {
28
+ if (this.parser.option(option.option)) {
29
+ const code = await option.handler.call(this);
30
+ if (code && code !== 0) {
31
+ return code;
32
+ }
33
+ }
40
34
  }
41
35
  this.parser.validate();
42
36
  return (await this.handle()) ?? 0;
@@ -1,3 +1,4 @@
1
+ import { CommandOption } from "./contracts/CommandOption";
1
2
  export type ArgSignature = {
2
3
  name: string;
3
4
  type: string;
@@ -5,7 +6,7 @@ export type ArgSignature = {
5
6
  variadic?: boolean;
6
7
  alias?: string[];
7
8
  help?: string;
8
- defaultValue?: string | boolean | Array<string> | null;
9
+ defaultValue: string | boolean | Array<string> | null;
9
10
  isOption?: boolean;
10
11
  };
11
12
  export declare class CommandParser {
@@ -13,13 +14,16 @@ export declare class CommandParser {
13
14
  protected readonly helperDefinitions: {
14
15
  [key: string]: string;
15
16
  };
16
- protected readonly defaultOptions: ArgSignature[];
17
+ protected readonly defaultCommandOptions: CommandOption<any>[];
17
18
  command: string;
18
19
  private arguments;
19
20
  private options;
20
21
  private argumentsSignature;
21
22
  private optionSignatures;
22
23
  private optionAliases;
24
+ constructor(signature: string, helperDefinitions: {
25
+ [key: string]: string;
26
+ }, defaultCommandOptions: CommandOption<any>[], ...args: any[]);
23
27
  option(name: string): any;
24
28
  setOption(name: string, value: any): void;
25
29
  optionHelp(name: string): string | undefined;
@@ -32,9 +36,6 @@ export declare class CommandParser {
32
36
  getOptionSignatures(): {
33
37
  [option: string]: ArgSignature;
34
38
  };
35
- constructor(signature: string, helperDefinitions: {
36
- [key: string]: string;
37
- }, defaultOptions?: ArgSignature[], ...args: any[]);
38
39
  private getParamValue;
39
40
  private handleArguments;
40
41
  private handleOptions;
@@ -12,13 +12,25 @@ const InvalidOption_1 = require("./errors/InvalidOption");
12
12
  class CommandParser {
13
13
  signature;
14
14
  helperDefinitions;
15
- defaultOptions;
15
+ defaultCommandOptions;
16
16
  command;
17
17
  arguments = {};
18
18
  options = {};
19
19
  argumentsSignature = {};
20
20
  optionSignatures = {};
21
21
  optionAliases = {};
22
+ constructor(signature, helperDefinitions, defaultCommandOptions, ...args) {
23
+ this.signature = signature;
24
+ this.helperDefinitions = helperDefinitions;
25
+ this.defaultCommandOptions = defaultCommandOptions;
26
+ const [command, ...signatureParams] = signature.split(/\{(.*?)\}/g).map(param => param.trim()).filter(Boolean);
27
+ const { _: paramValues, ...optionValues } = (0, minimist_1.default)(args);
28
+ this.command = command;
29
+ this.parseSignature(signatureParams);
30
+ this.parseDefaultOptions();
31
+ this.handleArguments(paramValues);
32
+ this.handleOptions(optionValues);
33
+ }
22
34
  option(name) {
23
35
  if (!this.optionSignatures[name]) {
24
36
  throw new MissingSignatureOption_1.MissingSignatureOption(name, Object.values(this.optionSignatures));
@@ -63,18 +75,6 @@ class CommandParser {
63
75
  getOptionSignatures() {
64
76
  return this.optionSignatures;
65
77
  }
66
- constructor(signature, helperDefinitions, defaultOptions = [], ...args) {
67
- this.signature = signature;
68
- this.helperDefinitions = helperDefinitions;
69
- this.defaultOptions = defaultOptions;
70
- const [command, ...signatureParams] = signature.split(/\{(.*?)\}/g).map(param => param.trim()).filter(Boolean);
71
- const { _: paramValues, ...optionValues } = (0, minimist_1.default)(args);
72
- this.command = command;
73
- this.parseSignature(signatureParams);
74
- this.parseDefaultOptions();
75
- this.handleArguments(paramValues);
76
- this.handleOptions(optionValues);
77
- }
78
78
  getParamValue(value, signature) {
79
79
  if (signature.type === 'boolean') {
80
80
  if (value === 'true' || value === '1') {
@@ -137,13 +137,22 @@ class CommandParser {
137
137
  }
138
138
  }
139
139
  parseDefaultOptions() {
140
- if (this.defaultOptions.length) {
141
- for (const option of this.defaultOptions) {
142
- this.optionSignatures[option.name] = option;
143
- this.options[option.name] = option.defaultValue;
140
+ if (this.defaultCommandOptions.length) {
141
+ for (const option of this.defaultCommandOptions) {
142
+ this.optionSignatures[option.option] = {
143
+ name: option.option,
144
+ type: option.defaultValue == null ? 'string' : typeof option.defaultValue,
145
+ optional: true,
146
+ alias: option.alias,
147
+ variadic: false,
148
+ help: option.description,
149
+ defaultValue: option.defaultValue ?? null,
150
+ isOption: true
151
+ };
152
+ this.options[option.option] = option.defaultValue;
144
153
  if (option.alias) {
145
154
  for (const alias of option.alias) {
146
- this.optionAliases[alias] = option.name;
155
+ this.optionAliases[alias] = option.option;
147
156
  }
148
157
  }
149
158
  }
@@ -2,10 +2,19 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const CommandParser_1 = require("./CommandParser");
4
4
  const MissingRequiredArgumentValue_1 = require("./errors/MissingRequiredArgumentValue");
5
+ class TestCommandOptions {
6
+ option = 'testOption';
7
+ description = 'Test option';
8
+ defaultValue = 'default';
9
+ alias = ['t'];
10
+ async handler() {
11
+ return 0;
12
+ }
13
+ }
5
14
  describe('CommandParser', () => {
6
15
  let commandParser;
7
- const parseCommand = (signature, args, helperDefinition = {}) => {
8
- return new CommandParser_1.CommandParser(signature, helperDefinition, [], ...args);
16
+ const parseCommand = (signature, args, helperDefinition = {}, defaultCommandOptions = []) => {
17
+ return new CommandParser_1.CommandParser(signature, helperDefinition, defaultCommandOptions, ...args);
9
18
  };
10
19
  it('should parse signature without arguments & options', () => {
11
20
  commandParser = parseCommand('test', []);
@@ -141,4 +150,28 @@ describe('CommandParser', () => {
141
150
  expect(commandParser.optionHelp('option')).toBe('option help');
142
151
  });
143
152
  });
153
+ describe('DefaultCommandOptions', () => {
154
+ it('should parse default command options', () => {
155
+ commandParser = parseCommand('test', [], {}, [new TestCommandOptions()]);
156
+ expect(commandParser.option('testOption')).toBe('default');
157
+ });
158
+ it('should parse default command options with provided value', () => {
159
+ commandParser = parseCommand('test', ['--testOption=value'], {}, [new TestCommandOptions()]);
160
+ expect(commandParser.option('testOption')).toBe('value');
161
+ });
162
+ it('should parse default command options with provided value with alias', () => {
163
+ commandParser = parseCommand('test', ['-t=value'], {}, [new TestCommandOptions()]);
164
+ expect(commandParser.option('testOption')).toBe('value');
165
+ });
166
+ it('should parse default command option help', () => {
167
+ commandParser = parseCommand('test', [], {}, [new TestCommandOptions()]);
168
+ expect(commandParser.optionHelp('testOption')).toBe('Test option');
169
+ });
170
+ it('should handle null default value', () => {
171
+ const option = new TestCommandOptions();
172
+ option.defaultValue = null;
173
+ commandParser = parseCommand('test', ['--testOption=value'], {}, [option]);
174
+ expect(commandParser.option('testOption')).toBe('value');
175
+ });
176
+ });
144
177
  });
@@ -1,9 +1,14 @@
1
1
  import { Command } from "../Command";
2
2
  import { CommandRegistry } from "../CommandRegistry";
3
+ export type HelpCommandOptions = {
4
+ commandRegistry: CommandRegistry;
5
+ cliName?: string;
6
+ cliVersion?: string;
7
+ };
3
8
  export default class HelpCommand extends Command {
4
- private commandRegistry;
9
+ private opts;
5
10
  signature: string;
6
11
  description: string;
7
- constructor(commandRegistry: CommandRegistry);
12
+ constructor(opts: HelpCommandOptions);
8
13
  protected handle(): Promise<void>;
9
14
  }
@@ -8,17 +8,19 @@ const chalk_1 = __importDefault(require("chalk"));
8
8
  const lodash_1 = require("lodash");
9
9
  const string_1 = require("../lib/string");
10
10
  class HelpCommand extends Command_1.Command {
11
- commandRegistry;
11
+ opts;
12
12
  signature = 'help';
13
13
  description = 'Show help';
14
- constructor(commandRegistry) {
14
+ constructor(opts) {
15
15
  super();
16
- this.commandRegistry = commandRegistry;
16
+ this.opts = opts;
17
17
  }
18
18
  async handle() {
19
- const commands = this.commandRegistry.getCommands();
20
- const version = require('../../package.json').version;
21
- console.log((0, chalk_1.default) `Bob CLI {green ${version}} 💪
19
+ const commands = this.opts.commandRegistry.getCommands();
20
+ const cliName = this.opts.cliName ?? 'Bob CLI';
21
+ const version = this.opts.cliVersion ?? '0.0.0';
22
+ const coreVersion = require('../../package.json').version;
23
+ console.log((0, chalk_1.default) `${cliName} {green ${version}} (core: {yellow ${coreVersion}})
22
24
 
23
25
  {yellow Usage}:
24
26
  command [options] [arguments]
@@ -0,0 +1,7 @@
1
+ export interface CommandOption<C> {
2
+ option: string;
3
+ alias?: string[];
4
+ defaultValue: string | boolean | Array<string> | null;
5
+ description?: string;
6
+ handler(this: C): Promise<number | void>;
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1 @@
1
+ export * from './CommandOption';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./CommandOption"), exports);
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
1
  export * from './Command';
2
2
  export * from './Cli';
3
3
  export * from './errors';
4
+ export * from './contracts';
5
+ export * from './options';
package/dist/index.js CHANGED
@@ -17,3 +17,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./Command"), exports);
18
18
  __exportStar(require("./Cli"), exports);
19
19
  __exportStar(require("./errors"), exports);
20
+ __exportStar(require("./contracts"), exports);
21
+ __exportStar(require("./options"), exports);
@@ -0,0 +1,9 @@
1
+ import { Command } from "../Command";
2
+ import { CommandOption } from "../contracts/CommandOption";
3
+ export declare class HelpOption implements CommandOption<Command> {
4
+ option: string;
5
+ alias: string[];
6
+ defaultValue: boolean;
7
+ description: string;
8
+ handler(this: Command): Promise<number | void>;
9
+ }
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.HelpOption = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const lodash_1 = require("lodash");
9
+ const string_1 = require("../lib/string");
10
+ class HelpOption {
11
+ option = 'help';
12
+ alias = ['h'];
13
+ defaultValue = false;
14
+ description = (0, chalk_1.default) `Display help for the given command. When no command is given display help for the {green list} command`;
15
+ async handler() {
16
+ const log = console.log;
17
+ const availableArguments = Object.values(this.parser.getArgumentSignatures());
18
+ const availableOptions = Object.values(this.parser.getOptionSignatures())
19
+ .map((signature) => ({
20
+ ...signature,
21
+ optionWithAlias: `--${signature.name}${signature.alias?.map(a => `, -${a}`).join('') ?? ''}`
22
+ }));
23
+ const requiredArguments = availableArguments.filter((signature) => !signature.optional);
24
+ log((0, chalk_1.default) `{yellow Description}:`);
25
+ log((0, chalk_1.default) ` ${this.description}\n`);
26
+ log((0, chalk_1.default) `{yellow Usage}:`);
27
+ log((0, chalk_1.default) ` ${this.command} ${requiredArguments.length > 0 ? requiredArguments.map((signature) => `<${signature.name}>`).join(' ') : '\b'} [options]`);
28
+ const maxOptionLength = (0, lodash_1.max)(availableOptions.map((signature) => signature.optionWithAlias.length)) ?? 0;
29
+ const maxArgumentLength = (0, lodash_1.max)(availableArguments.map((arg) => arg.name.length)) ?? 0;
30
+ const maxLength = maxArgumentLength > maxOptionLength ? maxArgumentLength : maxOptionLength;
31
+ if (availableArguments.length > 0) {
32
+ log((0, chalk_1.default) `\n{yellow Arguments}:`);
33
+ for (const signature of availableArguments) {
34
+ const spaces = (0, string_1.generateSpace)(maxLength - signature.name.length);
35
+ let message = (0, chalk_1.default) ` {green ${signature.name}} ${spaces} ${signature.help ?? '\b'}`;
36
+ if (signature.defaultValue !== undefined && signature.optional) {
37
+ const defaultValue = signature.type === 'array' ? JSON.stringify(signature.defaultValue) : signature.defaultValue;
38
+ message += (0, chalk_1.default) ` {yellow [default: ${defaultValue}]}`;
39
+ }
40
+ if (signature.variadic) {
41
+ message += (0, chalk_1.default) ` {white (variadic)}`;
42
+ }
43
+ log(message);
44
+ }
45
+ }
46
+ if (availableOptions.length > 0) {
47
+ log((0, chalk_1.default) `\n{yellow Options}:`);
48
+ for (const signature of availableOptions) {
49
+ const spaces = (0, string_1.generateSpace)(maxLength - signature.optionWithAlias.length);
50
+ let message = (0, chalk_1.default) `{green ${signature.optionWithAlias}} ${spaces} ${signature.help ?? '\b'}`;
51
+ if (signature.type) {
52
+ message += (0, chalk_1.default) ` {white (${signature.type})}`;
53
+ }
54
+ if (signature.defaultValue !== undefined && signature.optional) {
55
+ const defaultValue = signature.type === 'array' ? JSON.stringify(signature.defaultValue) : signature.defaultValue;
56
+ message += (0, chalk_1.default) ` {yellow [default: ${defaultValue}]}`;
57
+ }
58
+ log(message);
59
+ }
60
+ }
61
+ if (this.commandsExamples.length > 0) {
62
+ log((0, chalk_1.default) `\n{yellow Examples}:`);
63
+ let binaryName = process.argv[0].split('/').pop();
64
+ if (binaryName === 'node') {
65
+ binaryName += ' ' + process.argv[1].split('/').pop();
66
+ }
67
+ for (const [index, example] of this.commandsExamples.entries()) {
68
+ if (index > 0) {
69
+ log('');
70
+ }
71
+ log(` ${example.description}\n`);
72
+ log((0, chalk_1.default) ` {green ${binaryName} ${example.command}}`);
73
+ }
74
+ }
75
+ return -1;
76
+ }
77
+ }
78
+ exports.HelpOption = HelpOption;
@@ -0,0 +1 @@
1
+ export * from './HelpOption';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./HelpOption"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bob-core",
3
- "version": "0.9.12",
3
+ "version": "1.0.1",
4
4
  "description": "BOB Core",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/dist/Parser.d.ts DELETED
@@ -1,35 +0,0 @@
1
- export type ArgSignature = {
2
- name: string;
3
- type: string;
4
- optional?: boolean;
5
- variadic?: boolean;
6
- alias?: string[];
7
- help?: string;
8
- defaultValue?: string | boolean | Array<string> | null;
9
- isOption?: boolean;
10
- };
11
- export declare class Parser {
12
- protected readonly signature: string;
13
- protected readonly helperDefinitions: {
14
- [key: string]: string;
15
- };
16
- command: string;
17
- private arguments;
18
- private options;
19
- private argumentsSignature;
20
- private optionsSignature;
21
- option(name: string): any;
22
- argument(name: string): any;
23
- argumentsSignatures(): {
24
- [argument: string]: ArgSignature;
25
- };
26
- optionsSignatures(): {
27
- [option: string]: ArgSignature;
28
- };
29
- constructor(signature: string, helperDefinitions: {
30
- [key: string]: string;
31
- }, ...args: any[]);
32
- private parseSignature;
33
- private parseParamSignature;
34
- validate(): void;
35
- }
package/dist/Parser.js DELETED
@@ -1,162 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.Parser = void 0;
7
- const minimist_1 = __importDefault(require("minimist"));
8
- const MissingRequiredArgumentValue_1 = require("./errors/MissingRequiredArgumentValue");
9
- class Parser {
10
- signature;
11
- helperDefinitions;
12
- command;
13
- arguments = {};
14
- options = {};
15
- argumentsSignature = {};
16
- optionsSignature = {};
17
- option(name) {
18
- if (!this.optionsSignature[name]) {
19
- throw new Error(`Option ${name} not found`);
20
- }
21
- const signature = this.optionsSignature[name];
22
- if (signature.type === 'boolean') {
23
- if (this.options[name] === 'true' || this.options[name] === '1') {
24
- return true;
25
- }
26
- else if (this.options[name] === 'false' || this.options[name] === '0') {
27
- return false;
28
- }
29
- return Boolean(this.options[name]);
30
- }
31
- if (signature.type === 'array') {
32
- if (!this.options[name]) {
33
- return [];
34
- }
35
- return Array.isArray(this.options[name]) ? this.options[name] : [this.options[name]];
36
- }
37
- return this.options[name];
38
- }
39
- argument(name) {
40
- return this.arguments[name];
41
- }
42
- argumentsSignatures() {
43
- return this.argumentsSignature;
44
- }
45
- optionsSignatures() {
46
- return this.optionsSignature;
47
- }
48
- constructor(signature, helperDefinitions, ...args) {
49
- this.signature = signature;
50
- this.helperDefinitions = helperDefinitions;
51
- const [command, ...params] = signature.split(/\{(.*?)\}/g).map(param => param.trim()).filter(Boolean);
52
- const { _: paramValues, ...optionValues } = (0, minimist_1.default)(args);
53
- this.command = command;
54
- this.parseSignature(params, optionValues, paramValues);
55
- }
56
- parseSignature(params, optionValues, paramValues) {
57
- for (const paramSignature of params) {
58
- const param = this.parseParamSignature(paramSignature);
59
- if (param.isOption) {
60
- const optionValue = optionValues[param.name];
61
- this.options[param.name] = optionValue ?? param.defaultValue ?? null;
62
- this.optionsSignature[param.name] = param;
63
- for (const alias of param.alias ?? []) {
64
- if (optionValues[alias]) {
65
- this.options[param.name] = optionValues[alias];
66
- this.optionsSignature[param.name] = param;
67
- }
68
- }
69
- }
70
- else {
71
- if (param.variadic) {
72
- const paramValue = paramValues.splice(0, paramValues.length);
73
- this.arguments[param.name] = paramValue ?? [];
74
- }
75
- else {
76
- const paramValue = paramValues.shift();
77
- this.arguments[param.name] = paramValue ?? param.defaultValue ?? null;
78
- }
79
- this.argumentsSignature[param.name] = param;
80
- }
81
- }
82
- }
83
- parseParamSignature(argument) {
84
- let cleanedArgs = argument;
85
- let isOptional = false;
86
- let isVariadic = false;
87
- if (cleanedArgs.endsWith('?')) {
88
- cleanedArgs = cleanedArgs.slice(0, -1);
89
- isOptional = true;
90
- }
91
- if (cleanedArgs.endsWith('*')) {
92
- cleanedArgs = cleanedArgs.slice(0, -1);
93
- isVariadic = true;
94
- }
95
- const arg = {
96
- name: cleanedArgs,
97
- optional: isOptional,
98
- type: isVariadic ? 'array' : 'string',
99
- help: undefined,
100
- defaultValue: isVariadic ? [] : null,
101
- variadic: isVariadic,
102
- isOption: false
103
- };
104
- if (arg.name.includes(':')) {
105
- const [name, help] = arg.name.split(':');
106
- arg.name = name.trim();
107
- arg.help = help.trim();
108
- }
109
- if (arg.name.includes('=')) {
110
- const [name, defaultValue] = arg.name.split('=');
111
- arg.name = name.trim();
112
- arg.defaultValue = defaultValue.trim();
113
- arg.optional = true;
114
- if (!arg.defaultValue.length) {
115
- arg.defaultValue = null;
116
- }
117
- else if (arg.defaultValue === 'true') {
118
- arg.defaultValue = true;
119
- arg.type = 'boolean';
120
- }
121
- else if (arg.defaultValue === 'false') {
122
- arg.defaultValue = false;
123
- arg.type = 'boolean';
124
- }
125
- }
126
- else {
127
- if (arg.name.startsWith('--')) {
128
- arg.optional = true;
129
- arg.defaultValue = false;
130
- arg.type = 'boolean';
131
- }
132
- }
133
- if (arg.name.includes('|')) {
134
- const [name, ...alias] = arg.name.split('|');
135
- arg.name = name.trim();
136
- arg.alias = alias.map(a => a.trim());
137
- }
138
- if (arg.name.startsWith('--')) {
139
- arg.isOption = true;
140
- arg.name = arg.name.slice(2);
141
- }
142
- if (arg.defaultValue === '*') {
143
- arg.defaultValue = [];
144
- arg.type = 'array';
145
- }
146
- arg.help = arg.help ?? this.helperDefinitions[arg.name] ?? this.helperDefinitions[`--${arg.name}`];
147
- return arg;
148
- }
149
- validate() {
150
- // validate arguments
151
- for (const [argument, value] of Object.entries(this.arguments)) {
152
- const argSignature = this.argumentsSignature[argument];
153
- if (!value && !argSignature.optional) {
154
- throw new MissingRequiredArgumentValue_1.MissingRequiredArgumentValue(argSignature);
155
- }
156
- if (!value?.length && argSignature.variadic && !argSignature.optional) {
157
- throw new MissingRequiredArgumentValue_1.MissingRequiredArgumentValue(argSignature);
158
- }
159
- }
160
- }
161
- }
162
- exports.Parser = Parser;
@@ -1,11 +0,0 @@
1
- import { BobError } from "./BobError";
2
- export type BadParameterProps = {
3
- param: string;
4
- value?: string;
5
- reason?: string;
6
- };
7
- export declare class BadParameter extends BobError {
8
- readonly param: BadParameterProps;
9
- constructor(param: BadParameterProps);
10
- pretty(): void;
11
- }
@@ -1,36 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.BadParameter = void 0;
7
- const BobError_1 = require("./BobError");
8
- const chalk_1 = __importDefault(require("chalk"));
9
- class BadParameter extends BobError_1.BobError {
10
- param;
11
- constructor(param) {
12
- let message = `Argument "${param.param}" value is invalid.`;
13
- if (param.reason) {
14
- message += ` Reason: ${param.reason}`;
15
- }
16
- else {
17
- message += ` Value: "${param.value}"`;
18
- }
19
- super(message);
20
- this.param = param;
21
- }
22
- pretty() {
23
- const log = console.log;
24
- log((0, chalk_1.default) ` {white.bgRed ERROR } Argument {bold.yellow ${this.param.param}} value is invalid. `);
25
- if (this.param.value || this.param.reason) {
26
- log('');
27
- }
28
- if (this.param.value) {
29
- log((0, chalk_1.default) ` {blue Value}: ${this.param.value}`);
30
- }
31
- if (this.param.reason) {
32
- log((0, chalk_1.default) ` {yellow Reason}: ${this.param.reason}`);
33
- }
34
- }
35
- }
36
- exports.BadParameter = BadParameter;