Skip to content

Commit deb0765

Browse files
authored
fix: add support all properties for a command class in manifest
@W-9791511@
1 parent 5ce80a0 commit deb0765

File tree

6 files changed

+52
-13
lines changed

6 files changed

+52
-13
lines changed

src/config/config.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,7 @@ export async function toCached(c: Command.Class, plugin?: IPlugin): Promise<Comm
586586

587587
const args = await Promise.all(argsPromise)
588588

589-
return {
589+
const stdProperties = {
590590
id: c.id,
591591
summary: c.summary,
592592
description: c.description,
@@ -602,4 +602,15 @@ export async function toCached(c: Command.Class, plugin?: IPlugin): Promise<Comm
602602
flags,
603603
args,
604604
}
605+
606+
// do not include these properties in manifest
607+
const ignoreCommandProperties = ['plugin', '_flags']
608+
const stdKeys = Object.keys(stdProperties)
609+
const keysToAdd = Object.keys(c).filter(property => ![...stdKeys, ...ignoreCommandProperties].includes(property))
610+
const additionalProperties: any = {}
611+
keysToAdd.forEach(key => {
612+
additionalProperties[key] = (c as any)[key]
613+
})
614+
615+
return {...stdProperties, ...additionalProperties}
605616
}

src/help/command.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import stripAnsi = require('strip-ansi')
44
import {castArray, compact, sortBy} from '../util'
55
import * as Interfaces from '../interfaces'
66
import {Example} from '../interfaces/command'
7-
import {HelpFormatter} from './formatter'
7+
import {HelpFormatter, HelpSection, HelpSectionRenderer} from './formatter'
88
import {DocOpts} from './docopts'
99

1010
// Don't use os.EOL because we need to ensure that a string
@@ -22,10 +22,6 @@ let {
2222
if (process.env.ConEmuANSI === 'ON') {
2323
dim = Chalk.gray
2424
}
25-
26-
export type HelpSection = {header: string; body: string | [string, string | undefined][] | undefined} | undefined;
27-
export type HelpSectionRenderer = (data: {cmd: Interfaces.Command; flags: Interfaces.Command.Flag[]; args: Interfaces.Command.Arg[]}, header: string) => HelpSection[] | string | undefined;
28-
2925
export class CommandHelp extends HelpFormatter {
3026
constructor(
3127
public command: Interfaces.Command,
@@ -57,7 +53,7 @@ export class CommandHelp extends HelpFormatter {
5753

5854
protected groupFlags(flags: Interfaces.Command.Flag[]) {
5955
const mainFlags: Interfaces.Command.Flag[] = []
60-
const flagGroups: {[index: string]: Interfaces.Command.Flag[]} = {}
56+
const flagGroups: { [index: string]: Interfaces.Command.Flag[] } = {}
6157

6258
for (const flag of flags) {
6359
const group = flag.helpGroup
@@ -72,7 +68,7 @@ export class CommandHelp extends HelpFormatter {
7268
return {mainFlags, flagGroups}
7369
}
7470

75-
protected sections(): Array<{header: string; generate: HelpSectionRenderer}> {
71+
protected sections(): Array<{ header: string; generate: HelpSectionRenderer }> {
7672
return [
7773
{
7874
header: this.opts.usageHeader || 'USAGE',
@@ -131,7 +127,7 @@ export class CommandHelp extends HelpFormatter {
131127
if (line.length > allowedSpacing) {
132128
const splitIndex = line.substring(0, allowedSpacing).lastIndexOf(' ')
133129
return line.substring(0, splitIndex) + '\n' +
134-
this.indent(this.wrap(line.substring(splitIndex), this.indentSpacing * 2))
130+
this.indent(this.wrap(line.substring(splitIndex), this.indentSpacing * 2))
135131
}
136132
return this.wrap(line)
137133
})

src/help/formatter.ts

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ const {
1414
bold,
1515
} = Chalk
1616

17+
export type HelpSectionKeyValueTable = {name: string; description: string}[]
18+
export type HelpSection = {header: string; body: string | HelpSectionKeyValueTable | [string, string | undefined][] | undefined} | undefined;
19+
export type HelpSectionRenderer = (data: {cmd: Interfaces.Command; flags: Interfaces.Command.Flag[]; args: Interfaces.Command.Arg[]}, header: string) => HelpSection | HelpSection[] | string | undefined;
20+
1721
export class HelpFormatter {
1822
indentSpacing = 2
1923

@@ -163,13 +167,31 @@ export class HelpFormatter {
163167
return output.trim()
164168
}
165169

166-
public section(header: string, body: string | [string, string | undefined][]) {
170+
public section(header: string, body: string | HelpSection | HelpSectionKeyValueTable | [string, string | undefined][]): string {
167171
// Always render template strings with the provided render function before wrapping and indenting
168-
body = Array.isArray(body) ? body.map(([left, right]) => ([this.render(left), right && this.render(right)])) : this.render(body)
172+
let newBody: any
173+
if (typeof body! === 'string') {
174+
newBody = this.render(body!)
175+
} else if (Array.isArray(body)) {
176+
newBody = (body! as [string, string | undefined | HelpSectionKeyValueTable][]).map(entry => {
177+
if ('name' in entry) {
178+
const tableEntry = entry as unknown as {name: string; description: string}
179+
return ([this.render(tableEntry.name), this.render(tableEntry.description)])
180+
}
181+
const [left, right] = entry
182+
return ([this.render(left), right && this.render(right as string)])
183+
})
184+
} else if ('header' in body!) {
185+
return this.section(body!.header, body!.body)
186+
} else {
187+
newBody = (body! as unknown as HelpSectionKeyValueTable)
188+
.map((entry: { name: string; description: string }) => ([entry.name, entry.description]))
189+
.map(([left, right]) => ([this.render(left), right && this.render(right)]))
190+
}
169191

170192
const output = [
171193
bold(header),
172-
this.indent(Array.isArray(body) ? this.renderList(body, {stripAnsi: this.opts.stripAnsi, indentation: 2}) : body),
194+
this.indent(Array.isArray(newBody) ? this.renderList(newBody, {stripAnsi: this.opts.stripAnsi, indentation: 2}) : newBody),
173195
].join('\n')
174196
return this.opts.stripAnsi ? stripAnsi(output) : output
175197
}

src/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,27 @@ import {Config, Plugin, tsPath, toCached} from './config'
77
import * as Interfaces from './interfaces'
88
import * as Errors from './errors'
99
import * as Flags from './flags'
10-
import {HelpBase, Help, loadHelpClass} from './help'
10+
import {CommandHelp, HelpBase, Help, loadHelpClass} from './help'
1111
import {toStandardizedId, toConfiguredId} from './help/util'
1212
import * as Parser from './parser'
1313
import {Hook} from './interfaces/hooks'
1414
import {settings, Settings} from './settings'
15+
import {HelpSection, HelpSectionRenderer, HelpSectionKeyValueTable} from './help/formatter'
1516

1617
const flush = require('../flush')
1718

1819
export {
1920
Command,
21+
CommandHelp,
2022
Config,
2123
Errors,
2224
Flags,
2325
loadHelpClass,
2426
Help,
2527
HelpBase,
28+
HelpSection,
29+
HelpSectionRenderer,
30+
HelpSectionKeyValueTable,
2631
Hook,
2732
Interfaces,
2833
Parser,

src/interfaces/command.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ export interface CommandProps {
5252
* ```
5353
*/
5454
examples?: Example[];
55+
5556
}
5657

5758
export interface Command extends CommandProps {

test/help/format-commands.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,16 @@ describe('formatCommand', () => {
3434
.it('outputs an empty string when no commands are given', (ctx: any) => expect(ctx.output).to.equal(''))
3535

3636
test
37+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
38+
// @ts-ignore
3739
.formatCommands([AppsDestroy, AppsCreate])
3840
.it('shows a list of the provided commands', (ctx: any) => expect(ctx.output).to.equal(`COMMANDS
3941
apps:destroy Destroy an app
4042
apps:create Create an app`))
4143

4244
test
45+
// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
46+
// @ts-ignore
4347
.formatCommands([class extends Command {
4448
static id = 'hello:world'
4549

0 commit comments

Comments
 (0)