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

@oclif/core

Package Overview
Dependencies
Maintainers
5
Versions
406
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@oclif/core - npm Package Compare versions

Comparing version 0.5.13 to 0.5.14

lib/help/formatter.d.ts

7

CHANGELOG.md

@@ -5,2 +5,9 @@ # Changelog

### [0.5.14](https://github.com/oclif/core/compare/v0.5.13...v0.5.14) (2021-06-17)
### Features
* help improvements and customizability ([#184](https://github.com/oclif/core/issues/184)) ([cb2109b](https://github.com/oclif/core/commit/cb2109b113864534ceb08978ae1b209be7ae70d8))
### [0.5.13](https://github.com/oclif/core/compare/v0.5.12...v0.5.13) (2021-06-09)

@@ -7,0 +14,0 @@

36

lib/command.d.ts

@@ -11,16 +11,23 @@ import * as Interfaces from './interfaces';

static _base: string;
/** A command ID, used mostly in error or verbose reporting */
/** A command ID, used mostly in error or verbose reporting. */
static id: string;
static title: string | undefined;
/**
* The tweet-sized description for your class, used in a parent-commands
* sub-command listing and as the header for the command help
* sub-command listing and as the header for the command help.
*/
static summary?: string;
/**
* A full description of how to use the command.
*
* If no summary, the first line of the description will be used as the summary.
*/
static description: string | undefined;
/** hide the command from help? */
/** Hide the command from help? */
static hidden: boolean;
/** An override string (or strings) for the default usage documentation */
/**
* An override string (or strings) for the default usage documentation.
*/
static usage: string | string[] | undefined;
static help: string | undefined;
/** An array of aliases for this command */
/** An array of aliases for this command. */
static aliases: string[];

@@ -33,4 +40,17 @@ /** When set to false, allows a variable amount of arguments */

static plugin: Interfaces.Plugin | undefined;
/** An array of example strings to show at the end of the command's help */
static examples: string[] | undefined;
/**
* An array of examples to show at the end of the command's help.
*
* IF only a string is provided, it will try to look for a line that starts
* with the cmd.bin as the example command and the rest as the description.
* If found, the command will be formatted appropriately.
*
* ```
* EXAMPLES:
* A description of a particular use case.
*
* $ <%= config.bin => command flags
* ```
*/
static examples: Interfaces.Example[];
static parserOptions: {};

@@ -37,0 +57,0 @@ static disableJsonFlag: boolean | undefined;

@@ -144,3 +144,3 @@ "use strict";

Command._base = `${pjson.name}@${pjson.version}`;
/** An array of aliases for this command */
/** An array of aliases for this command. */
Command.aliases = [];

@@ -172,3 +172,4 @@ /** When set to false, allows a variable amount of arguments */

description: 'format output as json',
helpGroup: 'GLOBAL',
}),
};

@@ -84,2 +84,2 @@ import { Options, Plugin as IPlugin } from '../interfaces/plugin';

}
export declare function toCached(c: Command.Class, plugin?: IPlugin): Command;
export declare function toCached(c: Command.Class, plugin?: IPlugin): Promise<Command>;

@@ -251,3 +251,3 @@ "use strict";

if (name && !topics.find(t => t.name === name)) {
topics.push({ name, description: c.description });
topics.push({ name, description: c.summary || c.description });
}

@@ -392,29 +392,11 @@ parts.pop();

exports.Config = Config;
function toCached(c, plugin) {
return {
id: c.id,
description: c.description,
usage: c.usage,
pluginName: plugin && plugin.name,
pluginType: plugin && plugin.type,
hidden: c.hidden,
aliases: c.aliases || [],
examples: c.examples || c.example,
flags: util_2.mapValues(c.flags || {}, (flag, name) => {
if (flag.type === 'boolean') {
return {
name,
type: flag.type,
char: flag.char,
description: flag.description,
hidden: flag.hidden,
required: flag.required,
helpLabel: flag.helpLabel,
allowNo: flag.allowNo,
};
}
return {
async function toCached(c, plugin) {
const flags = {};
for (const [name, flag] of Object.entries(c.flags || {})) {
if (flag.type === 'boolean') {
flags[name] = {
name,
type: flag.type,
char: flag.char,
summary: flag.summary,
description: flag.description,

@@ -424,17 +406,48 @@ hidden: flag.hidden,

helpLabel: flag.helpLabel,
helpGroup: flag.helpGroup,
allowNo: flag.allowNo,
};
}
else {
flags[name] = {
name,
type: flag.type,
char: flag.char,
summary: flag.summary,
description: flag.description,
hidden: flag.hidden,
required: flag.required,
helpLabel: flag.helpLabel,
helpValue: flag.helpValue,
helpGroup: flag.helpGroup,
multiple: flag.multiple,
options: flag.options,
default: typeof flag.default === 'function' ? flag.default({ options: {}, flags: {} }) : flag.default,
// eslint-disable-next-line no-await-in-loop
default: typeof flag.default === 'function' ? await flag.default({ options: {}, flags: {} }) : flag.default,
};
}),
args: c.args ? c.args.map(a => ({
name: a.name,
description: a.description,
required: a.required,
options: a.options,
default: typeof a.default === 'function' ? a.default({}) : a.default,
hidden: a.hidden,
})) : [],
}
}
const argsPromise = (c.args || []).map(async (a) => ({
name: a.name,
description: a.description,
required: a.required,
options: a.options,
default: typeof a.default === 'function' ? await a.default({}) : a.default,
hidden: a.hidden,
}));
const args = await Promise.all(argsPromise);
return {
id: c.id,
summary: c.summary,
description: c.description,
usage: c.usage,
pluginName: plugin && plugin.name,
pluginType: plugin && plugin.type,
hidden: c.hidden,
aliases: c.aliases || [],
examples: c.examples || c.example,
flags,
args,
};
}
exports.toCached = toCached;

@@ -215,3 +215,3 @@ "use strict";

try {
return [id, config_1.toCached(await this.findCommand(id, { must: true }), this)];
return [id, await config_1.toCached(await this.findCommand(id, { must: true }), this)];
}

@@ -218,0 +218,0 @@ catch (error) {

@@ -13,4 +13,4 @@ import { OptionFlag, Definition, BooleanFlag, EnumFlagOptions } from './interfaces';

export { stringFlag as string };
export { boolean, integer } from './parser';
export { boolean, integer, url } from './parser';
export declare const version: (opts?: Partial<BooleanFlag<boolean>>) => BooleanFlag<void>;
export declare const help: (opts?: Partial<BooleanFlag<boolean>>) => BooleanFlag<void>;

@@ -25,2 +25,3 @@ "use strict";

exports.integer = parser_1.integer;
exports.url = parser_1.url;
exports.version = (opts = {}) => {

@@ -27,0 +28,0 @@ return Parser.flags.boolean(Object.assign(Object.assign({

import * as Interfaces from '../interfaces';
export default class CommandHelp {
import { Example } from '../interfaces/command';
import { HelpFormatter } from './formatter';
export declare type HelpSection = {
header: string;
body: string | [string, string | undefined][] | undefined;
} | undefined;
export declare type HelpSectionRenderer = (data: {
cmd: Interfaces.Command;
flags: Interfaces.Command.Flag[];
args: Interfaces.Command.Arg[];
}, header: string) => HelpSection[] | string | undefined;
export declare class CommandHelp extends HelpFormatter {
command: Interfaces.Command;
config: Interfaces.Config;
opts: Interfaces.HelpOptions;
render: (input: string) => string;
constructor(command: Interfaces.Command, config: Interfaces.Config, opts: Interfaces.HelpOptions);
generate(): string;
protected groupFlags(flags: Interfaces.Command.Flag[]): {
mainFlags: Interfaces.Command.Flag[];
flagGroups: {
[index: string]: Interfaces.Command.Flag[];
};
};
protected sections(): Array<{
header: string;
generate: HelpSectionRenderer;
}>;
protected usage(flags: Interfaces.Command.Flag[]): string;

@@ -13,6 +33,9 @@ protected defaultUsage(_: Interfaces.Command.Flag[]): string;

protected aliases(aliases: string[] | undefined): string | undefined;
protected examples(examples: string[] | undefined | string): string | undefined;
protected args(args: Interfaces.Command['args']): string | undefined;
protected examples(examples: Example[] | undefined | string): string | undefined;
protected args(args: Interfaces.Command['args']): [string, string | undefined][] | undefined;
protected arg(arg: Interfaces.Command['args'][0]): string;
protected flags(flags: Interfaces.Command.Flag[]): string | undefined;
protected flagHelpLabel(flag: Interfaces.Command.Flag, showOptions?: boolean): string;
protected flags(flags: Interfaces.Command.Flag[]): [string, string | undefined][] | undefined;
protected flagsDescriptions(flags: Interfaces.Command.Flag[]): string | undefined;
}
export default CommandHelp;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Chalk = require("chalk");
const indent = require("indent-string");
const stripAnsi = require("strip-ansi");
const list_1 = require("./list");
const util_1 = require("../util");
const util_2 = require("./util");
const { underline, bold, } = Chalk;
const formatter_1 = require("./formatter");
// Don't use os.EOL because we need to ensure that a string
// written on any platform, that may use \r\n or \n, will be
// split on any platform, not just the os specific EOL at runtime.
const POSSIBLE_LINE_FEED = /\r\n|\n/;
const { underline, } = Chalk;
let { dim, } = Chalk;

@@ -14,9 +16,8 @@ if (process.env.ConEmuANSI === 'ON') {

}
const wrap = require('wrap-ansi');
class CommandHelp {
class CommandHelp extends formatter_1.HelpFormatter {
constructor(command, config, opts) {
super(config, opts);
this.command = command;
this.config = config;
this.opts = opts;
this.render = util_2.template(this);
}

@@ -32,14 +33,75 @@ generate() {

const args = (cmd.args || []).filter(a => !a.hidden);
let output = util_1.compact([
this.usage(flags),
this.args(args),
this.flags(flags),
this.description(),
this.aliases(cmd.aliases),
this.examples(cmd.examples || cmd.example),
]).join('\n\n');
if (this.opts.stripAnsi)
output = stripAnsi(output);
const output = util_1.compact(this.sections().map(({ header, generate }) => {
const body = generate({ cmd, flags, args }, header);
// Generate can return a list of sections
if (Array.isArray(body)) {
return body.map(helpSection => helpSection && helpSection.body && this.section(helpSection.header, helpSection.body)).join('\n\n');
}
return body && this.section(header, body);
})).join('\n\n');
return output;
}
groupFlags(flags) {
const mainFlags = [];
const flagGroups = {};
for (const flag of flags) {
const group = flag.helpGroup;
if (group) {
if (!flagGroups[group])
flagGroups[group] = [];
flagGroups[group].push(flag);
}
else {
mainFlags.push(flag);
}
}
return { mainFlags, flagGroups };
}
sections() {
return [
{
header: this.opts.usageHeader || 'USAGE',
generate: ({ flags }) => this.usage(flags),
},
{
header: 'ARGUMENTS',
generate: ({ args }, header) => [{ header, body: this.args(args) }],
},
{
header: 'FLAGS',
generate: ({ flags }, header) => {
const { mainFlags, flagGroups } = this.groupFlags(flags);
const flagSections = [];
const mainFlagBody = this.flags(mainFlags);
if (mainFlagBody)
flagSections.push({ header, body: mainFlagBody });
Object.entries(flagGroups).forEach(([name, flags]) => {
const body = this.flags(flags);
if (body)
flagSections.push({ header: `${name.toUpperCase()} ${header}`, body });
});
return util_1.compact(flagSections);
},
},
{
header: 'DESCRIPTION',
generate: () => this.description(),
},
{
header: 'ALIASES',
generate: ({ cmd }) => this.aliases(cmd.aliases),
},
{
header: 'EXAMPLES',
generate: ({ cmd }) => {
const examples = cmd.examples || cmd.example;
return this.examples(examples);
},
},
{
header: 'FLAG DESCRIPTIONS',
generate: ({ flags }) => this.flagsDescriptions(flags),
},
];
}
usage(flags) {

@@ -50,6 +112,3 @@ const usage = this.command.usage;

.join('\n');
return [
bold('USAGE'),
indent(wrap(this.render(body), this.opts.maxWidth - 2, { trim: false, hard: true }), 2),
].join('\n');
return this.wrap(body);
}

@@ -64,9 +123,17 @@ defaultUsage(_) {

const cmd = this.command;
const description = cmd.description && this.render(cmd.description).split('\n').slice(1).join('\n');
if (!description)
return;
return [
bold('DESCRIPTION'),
indent(wrap(description.trim(), this.opts.maxWidth - 2, { trim: false, hard: true }), 2),
].join('\n');
let description;
if (this.opts.hideCommandSummaryInDescription) {
description = (cmd.description || '').split(POSSIBLE_LINE_FEED).slice(1);
}
else if (cmd.description) {
description = [
...(cmd.summary || '').split(POSSIBLE_LINE_FEED),
...(cmd.description || '').split(POSSIBLE_LINE_FEED),
];
}
if (description) {
// Lines separated with only one newline or more than 2 can be hard to read in the terminal.
// Always separate by two newlines.
return this.wrap(util_1.compact(description).join('\n\n'));
}
}

@@ -77,6 +144,3 @@ aliases(aliases) {

const body = aliases.map(a => ['$', this.config.bin, a].join(' ')).join('\n');
return [
bold('ALIASES'),
indent(wrap(body, this.opts.maxWidth - 2, { trim: false, hard: true }), 2),
].join('\n');
return body;
}

@@ -86,7 +150,43 @@ examples(examples) {

return;
const body = util_1.castArray(examples).map(a => this.render(a)).join('\n');
return [
bold('EXAMPLE' + (examples.length > 1 ? 'S' : '')),
indent(wrap(body, this.opts.maxWidth - 2, { trim: false, hard: true }), 2),
].join('\n');
const formatIfCommand = (example) => {
example = this.render(example);
if (example.startsWith(this.config.bin))
return dim(`$ ${example}`);
if (example.startsWith(`$ ${this.config.bin}`))
return dim(example);
return example;
};
const isCommand = (example) => stripAnsi(formatIfCommand(example)).startsWith(`$ ${this.config.bin}`);
const body = util_1.castArray(examples).map(a => {
let description;
let command;
if (typeof a === 'string') {
const lines = a
.split(POSSIBLE_LINE_FEED)
.filter(line => Boolean(line));
// If the example is <description>\n<command> then format correctly
if (lines.length === 2 && !isCommand(lines[0]) && isCommand(lines[1])) {
description = lines[0];
command = lines[1];
}
else {
return lines.map(line => formatIfCommand(line)).join('\n');
}
}
else {
description = a.description;
command = a.command;
}
const multilineSeparator = this.config.platform === 'win32' ?
this.config.shell.includes('powershell') ? '`' : '^' :
'\\';
// The command will be indented in the section, which is also indented
const finalIndentedSpacing = this.indentSpacing * 2;
// First indent keeping room for escaped newlines
const multilineCommand = this.indent(this.wrap(formatIfCommand(command), finalIndentedSpacing + 4))
// Then add the escaped newline
.split(POSSIBLE_LINE_FEED).join(` ${multilineSeparator}\n `);
return `${this.wrap(description, finalIndentedSpacing)}\n\n${multilineCommand}`;
}).join('\n\n');
return body;
}

@@ -96,3 +196,3 @@ args(args) {

return;
const body = list_1.renderList(args.map(a => {
return args.map(a => {
const name = a.name.toUpperCase();

@@ -105,7 +205,3 @@ let description = a.description || '';

return [name, description ? dim(description) : undefined];
}), { stripAnsi: this.opts.stripAnsi, maxWidth: this.opts.maxWidth - 2 });
return [
bold('ARGUMENTS'),
indent(body, 2),
].join('\n');
});
}

@@ -118,31 +214,40 @@ arg(arg) {

}
flagHelpLabel(flag, showOptions = false) {
let label = flag.helpLabel;
if (!label) {
const labels = [];
if (flag.char)
labels.push(`-${flag.char[0]}`);
if (flag.name) {
if (flag.type === 'boolean' && flag.allowNo) {
labels.push(`--[no-]${flag.name.trim()}`);
}
else {
labels.push(`--${flag.name.trim()}`);
}
}
label = labels.join(', ');
}
if (flag.type === 'option') {
let value = flag.helpValue || (this.opts.showFlagNameInTitle ? flag.name : '<value>');
if (!flag.helpValue && flag.options) {
if (showOptions || this.opts.showFlagOptionsInTitle)
value = `${flag.options.join('|')}`;
else
value = '<option>';
}
if (flag.multiple)
value += '...';
if (!value.includes('|'))
value = underline(value);
label += `=${value}`;
}
return label;
}
flags(flags) {
if (flags.length === 0)
return;
const body = list_1.renderList(flags.map(flag => {
let left = flag.helpLabel;
if (!left) {
const label = [];
if (flag.char)
label.push(`-${flag.char[0]}`);
if (flag.name) {
if (flag.type === 'boolean' && flag.allowNo) {
label.push(`--[no-]${flag.name.trim()}`);
}
else {
label.push(`--${flag.name.trim()}`);
}
}
left = label.join(', ');
}
if (flag.type === 'option') {
let value = flag.helpValue || flag.name;
if (!flag.helpValue && flag.options) {
value = flag.options.join('|');
}
if (!value.includes('|'))
value = underline(value);
left += `=${value}`;
}
let right = flag.description || '';
return flags.map(flag => {
const left = this.flagHelpLabel(flag);
let right = flag.summary || flag.description || '';
if (flag.type === 'option' && flag.default) {

@@ -153,10 +258,28 @@ right = `[default: ${flag.default}] ${right}`;

right = `(required) ${right}`;
if (flag.type === 'option' && flag.options && !flag.helpValue && !this.opts.showFlagOptionsInTitle) {
right += `\n<options: ${flag.options.join('|')}>`;
}
return [left, dim(right.trim())];
}), { stripAnsi: this.opts.stripAnsi, maxWidth: this.opts.maxWidth - 2 });
return [
bold('OPTIONS'),
indent(body, 2),
].join('\n');
});
}
flagsDescriptions(flags) {
const flagsWithExtendedDescriptions = flags.filter(flag => flag.summary && flag.description);
if (flagsWithExtendedDescriptions.length === 0)
return;
const body = flagsWithExtendedDescriptions.map(flag => {
// Guaranteed to be set because of the filter above, but make ts happy
const summary = flag.summary || '';
let flagHelp = this.flagHelpLabel(flag, true);
if (flagHelp.length + summary.length + 2 < this.opts.maxWidth) {
flagHelp += ' ' + summary;
}
else {
flagHelp += '\n\n' + this.indent(this.wrap(summary, this.indentSpacing * 2));
}
return `${flagHelp}\n\n${this.indent(this.wrap(flag.description || '', this.indentSpacing * 2))}`;
}).join('\n\n');
return body;
}
}
exports.CommandHelp = CommandHelp;
exports.default = CommandHelp;
import * as Interfaces from '../interfaces';
import CommandHelp from './command';
import { HelpFormatter } from './formatter';
export { CommandHelp } from './command';
export { standardizeIDFromArgv, loadHelpClass } from './util';
export declare abstract class HelpBase {
export declare abstract class HelpBase extends HelpFormatter {
constructor(config: Interfaces.Config, opts?: Partial<Interfaces.HelpOptions>);
protected config: Interfaces.Config;
protected opts: Interfaces.HelpOptions;
/**

@@ -20,3 +21,3 @@ * Show help, used in multi-command CLIs

export declare class Help extends HelpBase {
render: (input: string) => string;
protected CommandHelpClass: typeof CommandHelp;
private get _topics();

@@ -33,2 +34,4 @@ protected get sortedCommands(): Interfaces.Command.Plugin[];

protected formatCommands(commands: Interfaces.Command[]): string;
protected summary(c: Interfaces.Command): string | undefined;
protected description(c: Interfaces.Command): string;
protected formatTopic(topic: Interfaces.Topic): string;

@@ -35,0 +38,0 @@ protected formatTopics(topics: Interfaces.Topic[]): string;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Chalk = require("chalk");
const indent = require("indent-string");
const stripAnsi = require("strip-ansi");
const errors_1 = require("../errors");
const command_1 = require("./command");
const list_1 = require("./list");
const root_1 = require("./root");
const screen_1 = require("../screen");
const util_1 = require("../util");
const util_2 = require("./util");
const formatter_1 = require("./formatter");
var command_2 = require("./command");
exports.CommandHelp = command_2.CommandHelp;
var util_3 = require("./util");
exports.standardizeIDFromArgv = util_3.standardizeIDFromArgv;
exports.loadHelpClass = util_3.loadHelpClass;
const wrap = require('wrap-ansi');
const { bold, } = Chalk;
function getHelpSubject(args) {

@@ -29,8 +26,7 @@ for (const arg of args) {

}
class HelpBase {
class HelpBase extends formatter_1.HelpFormatter {
constructor(config, opts = {}) {
super(config, opts);
if (!config.topicSeparator)
config.topicSeparator = ':'; // back-support @oclif/config
this.config = config;
this.opts = Object.assign({ maxWidth: screen_1.stdtermwidth }, opts);
}

@@ -42,3 +38,3 @@ }

super(config, opts);
this.render = util_2.template(this);
this.CommandHelpClass = command_1.default;
}

@@ -102,5 +98,5 @@ /*

const subCommands = this.sortedCommands.filter(c => c.id.startsWith(name + ':') && c.id.split(':').length === depth + 1);
const title = command.description && this.render(command.description).split('\n')[0];
if (title)
console.log(title + '\n');
const summary = this.summary(command);
if (summary)
console.log(summary + '\n');
console.log(this.formatCommand(command));

@@ -160,3 +156,3 @@ console.log('');

}
const help = new command_1.default(command, this.config, this.opts);
const help = new this.CommandHelpClass(command, this.config, this.opts);
return help.generate();

@@ -167,3 +163,3 @@ }

return '';
const body = list_1.renderList(commands.map(c => {
const body = this.renderList(commands.map(c => {
if (this.config.topicSeparator !== ':')

@@ -173,3 +169,3 @@ c.id = c.id.replace(/:/g, this.config.topicSeparator);

c.id,
c.description && this.render(c.description.split('\n')[0]),
this.summary(c),
];

@@ -179,12 +175,21 @@ }), {

stripAnsi: this.opts.stripAnsi,
maxWidth: this.opts.maxWidth - 2,
indentation: 2,
});
return [
bold('COMMANDS'),
indent(body, 2),
].join('\n');
return this.section('COMMANDS', body);
}
summary(c) {
if (c.summary)
return this.render(c.summary.split('\n')[0]);
return c.description && this.render(c.description).split('\n')[0];
}
description(c) {
const description = this.render(c.description || '');
if (c.summary) {
return description;
}
return description.split('\n').slice(1).join('\n');
}
formatTopic(topic) {
let description = this.render(topic.description || '');
const title = description.split('\n')[0];
const summary = description.split('\n')[0];
description = description.split('\n').slice(1).join('\n');

@@ -195,11 +200,5 @@ let topicID = `${topic.name}:COMMAND`;

let output = util_1.compact([
title,
[
bold('USAGE'),
indent(wrap(`$ ${this.config.bin} ${topicID}`, this.opts.maxWidth - 2, { trim: false, hard: true }), 2),
].join('\n'),
description && ([
bold('DESCRIPTION'),
indent(wrap(description, this.opts.maxWidth - 2, { trim: false, hard: true }), 2),
].join('\n')),
summary,
this.section(this.opts.usageHeader || 'USAGE', `$ ${this.config.bin} ${topicID}`),
description && this.section('DESCRIPTION', this.wrap(description)),
]).join('\n\n');

@@ -213,3 +212,3 @@ if (this.opts.stripAnsi)

return '';
const body = list_1.renderList(topics.map(c => {
const body = this.renderList(topics.map(c => {
if (this.config.topicSeparator !== ':')

@@ -224,8 +223,5 @@ c.name = c.name.replace(/:/g, this.config.topicSeparator);

stripAnsi: this.opts.stripAnsi,
maxWidth: this.opts.maxWidth - 2,
indentation: 2,
});
return [
bold('TOPICS'),
indent(body, 2),
].join('\n');
return this.section('TOPICS', body);
}

@@ -232,0 +228,0 @@ /**

import * as Interfaces from '../interfaces';
export default class RootHelp {
import { HelpFormatter } from './formatter';
export default class RootHelp extends HelpFormatter {
config: Interfaces.Config;
opts: Interfaces.HelpOptions;
render: (input: string) => string;
constructor(config: Interfaces.Config, opts: Interfaces.HelpOptions);

@@ -7,0 +7,0 @@ root(): string;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Chalk = require("chalk");
const indent = require("indent-string");
const stripAnsi = require("strip-ansi");
const util_1 = require("../util");
const util_2 = require("./util");
const wrap = require('wrap-ansi');
const { bold, } = Chalk;
class RootHelp {
const formatter_1 = require("./formatter");
class RootHelp extends formatter_1.HelpFormatter {
constructor(config, opts) {
super(config, opts);
this.config = config;
this.opts = opts;
this.render = util_2.template(this);
}

@@ -31,6 +27,3 @@ root() {

usage() {
return [
bold('USAGE'),
indent(wrap(`$ ${this.config.bin} [COMMAND]`, this.opts.maxWidth - 2, { trim: false, hard: true }), 2),
].join('\n');
return this.section(this.opts.usageHeader || 'USAGE', this.wrap(`$ ${this.config.bin} [COMMAND]`));
}

@@ -43,14 +36,8 @@ description() {

return;
return [
bold('DESCRIPTION'),
indent(wrap(description, this.opts.maxWidth - 2, { trim: false, hard: true }), 2),
].join('\n');
return this.section('DESCRIPTION', this.wrap(description));
}
version() {
return [
bold('VERSION'),
indent(wrap(this.config.userAgent, this.opts.maxWidth - 2, { trim: false, hard: true }), 2),
].join('\n');
return this.section('VERSION', this.wrap(this.config.userAgent));
}
}
exports.default = RootHelp;
import { Config, LoadOptions } from './config';
import { ArgInput, FlagInput } from './parser';
export interface Command {
import { ArgInput, BooleanFlagProps, FlagInput, OptionFlagProps } from './parser';
export declare type Example = string | {
description: string;
command: string;
};
export interface CommandProps {
/** A command ID, used mostly in error or verbose reporting. */
id: string;
/** Hide the command from help? */
hidden: boolean;
/** An array of aliases for this command. */
aliases: string[];
/**
* The tweet-sized description for your class, used in a parent-commands
* sub-command listing and as the header for the command help.
*/
summary?: string;
/**
* A full description of how to use the command.
*
* If no summary, the first line of the description will be used as the summary.
*/
description?: string;
/**
* An override string (or strings) for the default usage documentation.
*/
usage?: string | string[];
examples?: string[];
/**
* An array of examples to show at the end of the command's help.
*
* IF only a string is provide, it will try to look for a line that starts
* with the cmd.bin as the example command and the rest as the description.
* If found, the command will be formatted appropriately.
*
* ```
* EXAMPLES:
* A description of a particular use case.
*
* $ <%= config.bin => command flags
* ```
*/
examples?: Example[];
}
export interface Command extends CommandProps {
type?: string;

@@ -29,33 +65,10 @@ pluginName?: string;

namespace Flag {
interface Boolean {
type: 'boolean';
name: string;
required?: boolean;
char?: string;
hidden?: boolean;
description?: string;
helpLabel?: string;
allowNo?: boolean;
interface Boolean extends BooleanFlagProps {
}
interface Option {
type: 'option';
name: string;
required?: boolean;
char?: string;
hidden?: boolean;
description?: string;
helpLabel?: string;
helpValue?: string;
interface Option extends OptionFlagProps {
default?: string;
options?: string[];
}
}
interface Base {
interface Base extends CommandProps {
_base: string;
id: string;
hidden: boolean;
aliases: string[];
description?: string;
usage?: string | string[];
examples?: string[];
}

@@ -62,0 +75,0 @@ interface Class extends Base {

@@ -5,2 +5,28 @@ export interface HelpOptions {

stripAnsi?: boolean;
/**
* By default, option values on flags are shown in the flag's description. This is because
* long options list ruin the formatting of help. If a CLI knows all commands will not
* do this, it can be turned off at a help level using this property. An individual flag
* can set this using `flag.helpValue=options.join('|')`.
*/
showFlagOptionsInTitle?: boolean;
/**
* By default, titles show flag values as `<value>`. Some CLI developers may prefer titles
* to show the flag name as the value. i.e. `--myflag=myflag` instead of `--myflag=<value>`.
* An individual flag can set this using `flag.helpValue=flag.name`.
*/
showFlagNameInTitle?: boolean;
/**
* By default, the command summary is show at the top of the help and as the first line in
* the command description. Repeating the summary in the command description improves readability
* especially for long command help output. If there is no `command.summary`, the first line of
* the description is treated as the summary. Some CLIs, especially with very simple commands, may
* not want the duplication.
*/
hideCommandSummaryInDescription?: boolean;
/**
* Use USAGE, but some may want to use USAGE as used in gnu man pages. See help recommendations at
* http://www.gnu.org/software/help2man/#--help-recommendations
*/
usageHeader?: string;
}
export { AlphabetLowercase, AlphabetUppercase } from './alphabet';
export { Config, ArchTypes, PlatformTypes, LoadOptions } from './config';
export { Command } from './command';
export { Command, Example } from './command';
export { OclifError, PrettyPrintableError } from './errors';

@@ -5,0 +5,0 @@ export { HelpOptions } from './help';

@@ -88,9 +88,39 @@ import { AlphabetLowercase, AlphabetUppercase } from './alphabet';

export declare type Default<T> = T | ((context: DefaultContext<T>) => Promise<T>);
export declare type FlagBase<T, I> = {
export declare type FlagProps = {
name: string;
char?: AlphabetLowercase | AlphabetUppercase;
/**
* A short summary of flag usage to show in the flag list.
* If not provided, description will be used.
*/
summary?: string;
/**
* A description of flag usage. If summary is provided, the description
* is assumed to be a longer description and will be shown in a separate
* section within help.
*/
description?: string;
/**
* The flag label to show in help. Defaults to "[-<char>] --<name>" where -<char> is
* only displayed if the char is defined.
*/
helpLabel?: string;
/**
* Shows this flag in a separate list in the help.
*/
helpGroup?: string;
hidden?: boolean;
required?: boolean;
};
export declare type BooleanFlagProps = FlagProps & {
type: 'boolean';
allowNo: boolean;
};
export declare type OptionFlagProps = FlagProps & {
type: 'option';
helpValue?: string;
options?: string[];
multiple: boolean;
};
export declare type FlagBase<T, I> = FlagProps & {
dependsOn?: string[];

@@ -105,5 +135,3 @@ exclusive?: string[];

};
export declare type BooleanFlag<T> = FlagBase<T, boolean> & {
type: 'boolean';
allowNo: boolean;
export declare type BooleanFlag<T> = FlagBase<T, boolean> & BooleanFlagProps & {
/**

@@ -114,9 +142,5 @@ * specifying a default of false is the same not specifying a default

};
export declare type OptionFlag<T> = FlagBase<T, string> & {
type: 'option';
helpValue?: string;
export declare type OptionFlag<T> = FlagBase<T, string> & OptionFlagProps & {
default?: Default<T | undefined>;
multiple: boolean;
input: string[];
options?: string[];
};

@@ -123,0 +147,0 @@ export declare type Definition<T> = {

@@ -0,1 +1,2 @@

import { HelpOptions } from './help';
export interface PJSON {

@@ -16,3 +17,2 @@ [k: string]: any;

schema?: number;
title?: string;
description?: string;

@@ -28,2 +28,3 @@ topicSeparator?: ':' | ' ';

helpClass?: string;
helpOptions?: HelpOptions;
aliases?: {

@@ -30,0 +31,0 @@ [name: string]: string | null;

@@ -53,3 +53,3 @@ "use strict";

const Help = await help_1.loadHelpClass(config);
const help = new Help(config);
const help = new Help(config, config.pjson.helpOptions);
await help.showHelp(argv);

@@ -56,0 +56,0 @@ return;

@@ -0,1 +1,3 @@

/// <reference types="node" />
import { URL } from 'url';
import { Definition, OptionFlag, BooleanFlag } from '../interfaces';

@@ -8,2 +10,7 @@ export declare function build<T>(defaults: {

export declare const integer: Definition<number>;
/**
* Initializes a string as a URL. Throws an error
* if the string is not a valid URL.
*/
export declare const url: Definition<URL>;
export declare function option<T>(options: {

@@ -10,0 +17,0 @@ parse: OptionFlag<T>['parse'];

"use strict";
// tslint:disable interface-over-type-literal
Object.defineProperty(exports, "__esModule", { value: true });
const url_1 = require("url");
function build(defaults) {

@@ -21,2 +22,16 @@ return (options = {}) => {

});
/**
* Initializes a string as a URL. Throws an error
* if the string is not a valid URL.
*/
exports.url = build({
parse: async (input) => {
try {
return new url_1.URL(input);
}
catch (_a) {
throw new Error(`Expected a valid url but received: ${input}`);
}
},
});
function option(options) {

@@ -23,0 +38,0 @@ return build(options)();

@@ -21,3 +21,3 @@ "use strict";

const usage = flag.type === 'option' ? ` ${flag.name.toUpperCase()}` : '';
let description = flag.description || '';
let description = flag.summary || flag.description || '';
if (options.displayRequired && flag.required)

@@ -24,0 +24,0 @@ description = `(required) ${description}`;

@@ -0,1 +1,2 @@

/// <reference types="node" />
import * as args from './args';

@@ -10,4 +11,3 @@ import * as flags from './flags';

}>(argv: string[], options: Input<TFlags>): Promise<ParserOutput<TFlags, TArgs>>;
declare const boolean: typeof flags.boolean;
declare const integer: import("../interfaces").Definition<number>;
export { boolean, integer };
declare const boolean: typeof flags.boolean, integer: import("../interfaces").Definition<number>, url: import("../interfaces").Definition<import("url").URL>;
export { boolean, integer, url };

@@ -31,5 +31,5 @@ "use strict";

exports.parse = parse;
const boolean = flags.boolean;
const { boolean, integer, url } = flags;
exports.boolean = boolean;
const integer = flags.integer;
exports.integer = integer;
exports.url = url;

@@ -203,9 +203,9 @@ "use strict";

this.metaData.flags[k] = { setFromDefault: true };
if (typeof flag.default === 'function') {
// eslint-disable-next-line no-await-in-loop
const defaultValue = (typeof flag.default === 'function' ? await flag.default(Object.assign({ options: flag, flags }, this.context)) : flag.default);
const parsedValue = flag.type === 'option' && flag.parse ?
// eslint-disable-next-line no-await-in-loop
flags[k] = await flag.default(Object.assign({ options: flag, flags }, this.context));
}
else {
flags[k] = flag.default;
}
await flag.parse(defaultValue, this.context) :
defaultValue;
flags[k] = parsedValue;
}

@@ -212,0 +212,0 @@ }

{
"name": "@oclif/core",
"description": "base library for oclif CLIs",
"version": "0.5.13",
"version": "0.5.14",
"author": "Jeff Dickey @jdxcode",

@@ -6,0 +6,0 @@ "bugs": "https://github.com/oclif/core/issues",

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