mirror of
https://github.com/chenasraf/massarg.git
synced 2026-05-18 01:39:05 +00:00
feat: transform output name for options
This commit is contained in:
31
README.md
31
README.md
@@ -66,15 +66,20 @@ documentation of every option.
|
|||||||
const parser = massarg({
|
const parser = massarg({
|
||||||
name: 'my-cli',
|
name: 'my-cli',
|
||||||
description: "Does really amazing stuff, you wouldn't believe!",
|
description: "Does really amazing stuff, you wouldn't believe!",
|
||||||
bindHelpCommand: true,
|
|
||||||
}) // or: new Massarg()
|
}) // or: new Massarg()
|
||||||
.main((options) => console.log('main command', options))
|
.main((options) => console.log('main command', options))
|
||||||
|
.command({
|
||||||
|
name: 'foo',
|
||||||
|
description: 'a sub command',
|
||||||
|
aliases: ['f'],
|
||||||
|
run: (options) => console.log('foo command'),
|
||||||
|
})
|
||||||
.command(
|
.command(
|
||||||
massarg({
|
massarg({
|
||||||
name: 'sub',
|
name: 'bar',
|
||||||
description: 'a sub command',
|
description: 'another sub command',
|
||||||
aliases: ['s'],
|
aliases: ['s'],
|
||||||
run: (options) => console.log('sub command', options),
|
run: (options) => console.log('bar command', options),
|
||||||
}).option({
|
}).option({
|
||||||
name: 'file',
|
name: 'file',
|
||||||
description: 'Filename to use',
|
description: 'Filename to use',
|
||||||
@@ -82,6 +87,11 @@ const parser = massarg({
|
|||||||
parse: (filename) => path.resolve(process.cwd(), filename),
|
parse: (filename) => path.resolve(process.cwd(), filename),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
.option({
|
||||||
|
name: 'my-string',
|
||||||
|
description: 'A string argument',
|
||||||
|
aliases: ['s'],
|
||||||
|
})
|
||||||
.flag({
|
.flag({
|
||||||
name: 'flag',
|
name: 'flag',
|
||||||
description: 'a flag that will be related to any command (main or sub)',
|
description: 'a flag that will be related to any command (main or sub)',
|
||||||
@@ -93,8 +103,12 @@ const parser = massarg({
|
|||||||
output: 'Sub command: flag is true',
|
output: 'Sub command: flag is true',
|
||||||
})
|
})
|
||||||
.help({
|
.help({
|
||||||
binName: 'my-cli-app',
|
bindCommand: true,
|
||||||
footer: 'Copyright © 2021 Me, Myself and I',
|
footerText: `Copyright © ${new Date().getFullYear()} Me, Myself and I`,
|
||||||
|
titleStyle: {
|
||||||
|
bold: true,
|
||||||
|
color: 'brightWhite',
|
||||||
|
},
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -122,7 +136,10 @@ $ ./mybin
|
|||||||
# Main command runs without options
|
# Main command runs without options
|
||||||
|
|
||||||
$ ./mybin --my-string "Some string"
|
$ ./mybin --my-string "Some string"
|
||||||
# Main command runs with option { myString: "Some string" }
|
# Main command runs with options { myString: "Some string" }
|
||||||
|
|
||||||
|
$ ./mybin foo
|
||||||
|
# Foo sub command run with options {}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Commands
|
## Commands
|
||||||
|
|||||||
18
src/help.ts
18
src/help.ts
@@ -136,6 +136,7 @@ export type HelpItem = {
|
|||||||
name: string
|
name: string
|
||||||
aliases: string[]
|
aliases: string[]
|
||||||
description: string
|
description: string
|
||||||
|
hidden?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export class HelpGenerator {
|
export class HelpGenerator {
|
||||||
@@ -271,13 +272,16 @@ function generateHelpTable<T extends Partial<GenerateTableCommandConfig>>(
|
|||||||
...config
|
...config
|
||||||
}: Partial<T> = {},
|
}: Partial<T> = {},
|
||||||
): string {
|
): string {
|
||||||
const rows = items.map((o) => {
|
const rows = items
|
||||||
const name = `${namePrefix}${o.name}${
|
.map((o) => {
|
||||||
o.aliases.length ? ` | ${aliasPrefix}${o.aliases.join(`|${aliasPrefix}`)}` : ''
|
const name = `${namePrefix}${o.name}${
|
||||||
}`
|
o.aliases.length ? ` | ${aliasPrefix}${o.aliases.join(`|${aliasPrefix}`)}` : ''
|
||||||
const description = o.description
|
}`
|
||||||
return { name, description }
|
const description = o.description
|
||||||
})
|
const hidden = o.hidden || false
|
||||||
|
return { name, description, hidden }
|
||||||
|
})
|
||||||
|
.filter((r) => !r.hidden)
|
||||||
const maxNameLength = Math.max(...rows.map((o) => o.name.length))
|
const maxNameLength = Math.max(...rows.map((o) => o.name.length))
|
||||||
const nameStyle = (name: string) => format(name, config.nameStyle)
|
const nameStyle = (name: string) => format(name, config.nameStyle)
|
||||||
const descStyle = (desc: string) => format(desc, config.descriptionStyle)
|
const descStyle = (desc: string) => format(desc, config.descriptionStyle)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { z } from 'zod'
|
import { z } from 'zod'
|
||||||
import { isZodError, ParseError } from './error'
|
import { isZodError, ParseError } from './error'
|
||||||
|
import { toCamelCase } from './utils'
|
||||||
|
|
||||||
export const OptionConfig = <T extends z.ZodType>(type: T) =>
|
export const OptionConfig = <T extends z.ZodType>(type: T) =>
|
||||||
z.object({
|
z.object({
|
||||||
@@ -35,6 +36,10 @@ export const OptionConfig = <T extends z.ZodType>(type: T) =>
|
|||||||
* option.
|
* option.
|
||||||
*/
|
*/
|
||||||
isDefault: z.boolean().optional(),
|
isDefault: z.boolean().optional(),
|
||||||
|
/** Whether the option is hidden. Hidden options are not displayed in the help output. */
|
||||||
|
hidden: z.boolean().optional(),
|
||||||
|
/** Specify a custom name for the output, which will be used when parsing the args. */
|
||||||
|
outputName: z.string().optional(),
|
||||||
})
|
})
|
||||||
export type OptionConfig<T = unknown> = z.infer<ReturnType<typeof OptionConfig<z.ZodType<T>>>>
|
export type OptionConfig<T = unknown> = z.infer<ReturnType<typeof OptionConfig<z.ZodType<T>>>>
|
||||||
|
|
||||||
@@ -108,6 +113,7 @@ export class MassargOption<T = unknown> {
|
|||||||
parse: (value: string) => T
|
parse: (value: string) => T
|
||||||
isArray: boolean
|
isArray: boolean
|
||||||
isDefault: boolean
|
isDefault: boolean
|
||||||
|
outputName?: string
|
||||||
|
|
||||||
constructor(options: OptionConfig<T>) {
|
constructor(options: OptionConfig<T>) {
|
||||||
OptionConfig(z.any()).parse(options)
|
OptionConfig(z.any()).parse(options)
|
||||||
@@ -118,6 +124,7 @@ export class MassargOption<T = unknown> {
|
|||||||
this.parse = options.parse ?? ((x) => x as unknown as T)
|
this.parse = options.parse ?? ((x) => x as unknown as T)
|
||||||
this.isArray = options.array ?? false
|
this.isArray = options.array ?? false
|
||||||
this.isDefault = options.isDefault ?? false
|
this.isDefault = options.isDefault ?? false
|
||||||
|
this.outputName = options.outputName
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromTypedConfig<T = unknown>(config: TypedOptionConfig<T>): MassargOption<T> {
|
static fromTypedConfig<T = unknown>(config: TypedOptionConfig<T>): MassargOption<T> {
|
||||||
@@ -143,7 +150,7 @@ export class MassargOption<T = unknown> {
|
|||||||
argv.shift()
|
argv.shift()
|
||||||
input = argv.shift()!
|
input = argv.shift()!
|
||||||
const value = this.parse(input)
|
const value = this.parse(input)
|
||||||
return { key: this.name, value, argv }
|
return { key: this.outputName || toCamelCase(this.name), value, argv }
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (isZodError(e)) {
|
if (isZodError(e)) {
|
||||||
throw new ParseError({
|
throw new ParseError({
|
||||||
|
|||||||
27
src/utils.ts
27
src/utils.ts
@@ -86,3 +86,30 @@ export function deepMerge<T1, T2>(obj1: T1, obj2: T2): NonNullable<T1> & NonNull
|
|||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Splits a name into words, using camelCase, PascalCase, snake_case, and kebab-case or
|
||||||
|
* regular spaced strings.
|
||||||
|
*/
|
||||||
|
export function splitWords(str: string): string[] {
|
||||||
|
return str
|
||||||
|
.replace(/([a-z])([A-Z])/g, '$1 $2')
|
||||||
|
.replace(/([a-zA-Z])([0-9])/g, '$1 $2')
|
||||||
|
.replace(/([0-9])([a-zA-Z])/g, '$1 $2')
|
||||||
|
.replace(/([a-z])([_-])/g, '$1 $2')
|
||||||
|
.replace(/([_-])([a-zA-Z])/g, '$1 $2')
|
||||||
|
.split(/[_-]/)
|
||||||
|
.map((s) => s.trim())
|
||||||
|
.filter(Boolean)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toCamelCase(str: string): string {
|
||||||
|
return splitWords(str)
|
||||||
|
.map((s, i) => (i === 0 ? s : s[0].toUpperCase() + s.slice(1)))
|
||||||
|
.join('')
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toPascalCase(str: string): string {
|
||||||
|
return splitWords(str)
|
||||||
|
.map((s) => s[0].toUpperCase() + s.slice(1))
|
||||||
|
.join('')
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ test('constructor', () => {
|
|||||||
expect(massarg(opts)).toBeInstanceOf(MassargCommand)
|
expect(massarg(opts)).toBeInstanceOf(MassargCommand)
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('command', () => {
|
describe('sub command', () => {
|
||||||
test('add', () => {
|
test('add', () => {
|
||||||
const command = massarg(opts)
|
const command = massarg(opts)
|
||||||
expect(command.command).toBeInstanceOf(Function)
|
expect(command.command).toBeInstanceOf(Function)
|
||||||
@@ -36,149 +36,6 @@ describe('command', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('option', () => {
|
|
||||||
test('add', () => {
|
|
||||||
const command = massarg(opts)
|
|
||||||
expect(command.option).toBeInstanceOf(Function)
|
|
||||||
expect(
|
|
||||||
command.option({ name: 'test2', description: 'test2', aliases: [], defaultValue: '' }),
|
|
||||||
).toBeInstanceOf(MassargCommand)
|
|
||||||
})
|
|
||||||
test('validate', () => {
|
|
||||||
expect(() =>
|
|
||||||
massarg(opts).option({
|
|
||||||
name: 'test2',
|
|
||||||
description: 123 as any,
|
|
||||||
aliases: [],
|
|
||||||
defaultValue: '',
|
|
||||||
}),
|
|
||||||
).toThrow('Expected string, received number')
|
|
||||||
})
|
|
||||||
test('add duplicate', () => {
|
|
||||||
expect(() =>
|
|
||||||
massarg(opts)
|
|
||||||
.option({
|
|
||||||
name: 'test2',
|
|
||||||
description: 'test2',
|
|
||||||
aliases: [],
|
|
||||||
defaultValue: '',
|
|
||||||
})
|
|
||||||
.option({
|
|
||||||
name: 'test2',
|
|
||||||
description: 'test2',
|
|
||||||
aliases: [],
|
|
||||||
defaultValue: '',
|
|
||||||
}),
|
|
||||||
).toThrow('Option "test2" already exists')
|
|
||||||
})
|
|
||||||
test('add 2 defaults', () => {
|
|
||||||
expect(() =>
|
|
||||||
massarg(opts)
|
|
||||||
.option({
|
|
||||||
name: 'test',
|
|
||||||
description: 'test2',
|
|
||||||
aliases: [],
|
|
||||||
isDefault: true,
|
|
||||||
})
|
|
||||||
.option({
|
|
||||||
name: 'test2',
|
|
||||||
description: 'test2',
|
|
||||||
aliases: [],
|
|
||||||
isDefault: true,
|
|
||||||
}),
|
|
||||||
).toThrow(
|
|
||||||
'Option "test2" cannot be set as default because option "test" is already set as default',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('flag', () => {
|
|
||||||
test('add', () => {
|
|
||||||
const command = massarg(opts)
|
|
||||||
expect(command.flag).toBeInstanceOf(Function)
|
|
||||||
expect(command.flag({ name: 'test2', description: 'test2', aliases: [] })).toBeInstanceOf(
|
|
||||||
MassargCommand,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
test('add duplicate', () => {
|
|
||||||
expect(() =>
|
|
||||||
massarg(opts)
|
|
||||||
.flag({ name: 'test2', description: 'test2', aliases: [] })
|
|
||||||
.flag({ name: 'test2', description: 'test2', aliases: [] }),
|
|
||||||
).toThrow('Flag "test2" already exists')
|
|
||||||
})
|
|
||||||
test('validate', () => {
|
|
||||||
expect(() =>
|
|
||||||
massarg(opts).flag({
|
|
||||||
name: 'test2',
|
|
||||||
description: 123 as any,
|
|
||||||
aliases: [],
|
|
||||||
}),
|
|
||||||
).toThrow('Expected string, received number')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('example', () => {
|
|
||||||
test('example', () => {
|
|
||||||
const command = massarg(opts)
|
|
||||||
expect(command.example).toBeInstanceOf(Function)
|
|
||||||
expect(command.example({ description: 'test', input: '', output: '' })).toBeInstanceOf(
|
|
||||||
MassargCommand,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('help', () => {
|
|
||||||
test('default value', () => {
|
|
||||||
const command = massarg(opts)
|
|
||||||
expect(command.helpConfig).toEqual(defaultHelpConfig)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('init', () => {
|
|
||||||
const command = massarg(opts).help({
|
|
||||||
bindOption: true,
|
|
||||||
optionOptions: {
|
|
||||||
namePrefix: '__',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
expect(command.help).toBeInstanceOf(Function)
|
|
||||||
expect(command.helpConfig).toHaveProperty('bindOption', true)
|
|
||||||
expect(command.helpConfig).toHaveProperty('optionOptions.namePrefix', '__')
|
|
||||||
expect(command.helpConfig).toHaveProperty('optionOptions.aliasPrefix', '-')
|
|
||||||
expect(command.helpConfig).toHaveProperty('optionOptions.nameStyle.color', 'yellow')
|
|
||||||
})
|
|
||||||
|
|
||||||
test('binds command', () => {
|
|
||||||
const command = massarg(opts).help({
|
|
||||||
bindCommand: true,
|
|
||||||
})
|
|
||||||
expect(command.help).toBeInstanceOf(Function)
|
|
||||||
expect(command.helpConfig).toHaveProperty('bindCommand', true)
|
|
||||||
expect(command.commands.find((o) => o.name === 'help')).toBeTruthy()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('binds option', () => {
|
|
||||||
const command = massarg(opts).help({
|
|
||||||
bindOption: true,
|
|
||||||
})
|
|
||||||
expect(command.help).toBeInstanceOf(Function)
|
|
||||||
expect(command.helpConfig).toHaveProperty('bindOption', true)
|
|
||||||
expect(command.options.find((o) => o.name === 'help')).toBeTruthy()
|
|
||||||
})
|
|
||||||
|
|
||||||
test('help string', () => {
|
|
||||||
const command = massarg(opts)
|
|
||||||
expect(command.helpString()).toContain(`Usage:`)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('print help', () => {
|
|
||||||
const log = jest.spyOn(console, 'log').mockImplementation(() => {})
|
|
||||||
const command = massarg(opts)
|
|
||||||
command.printHelp()
|
|
||||||
expect(log).toHaveBeenCalled()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('getArgs', () => {
|
describe('getArgs', () => {
|
||||||
test('basic', () => {
|
test('basic', () => {
|
||||||
expect(massarg(opts).getArgs([])).toEqual({})
|
expect(massarg(opts).getArgs([])).toEqual({})
|
||||||
|
|||||||
14
test/example.test.ts
Normal file
14
test/example.test.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { MassargCommand } from '../src/command'
|
||||||
|
import { massarg } from '../src/index'
|
||||||
|
|
||||||
|
const opts = {
|
||||||
|
name: 'test',
|
||||||
|
description: 'test',
|
||||||
|
}
|
||||||
|
test('example', () => {
|
||||||
|
const command = massarg(opts)
|
||||||
|
expect(command.example).toBeInstanceOf(Function)
|
||||||
|
expect(command.example({ description: 'test', input: '', output: '' })).toBeInstanceOf(
|
||||||
|
MassargCommand,
|
||||||
|
)
|
||||||
|
})
|
||||||
56
test/help.test.ts
Normal file
56
test/help.test.ts
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import { defaultHelpConfig } from '../src/help'
|
||||||
|
import { massarg } from '../src/index'
|
||||||
|
|
||||||
|
const opts = {
|
||||||
|
name: 'test',
|
||||||
|
description: 'test',
|
||||||
|
}
|
||||||
|
|
||||||
|
test('default value', () => {
|
||||||
|
const command = massarg(opts)
|
||||||
|
expect(command.helpConfig).toEqual(defaultHelpConfig)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('init', () => {
|
||||||
|
const command = massarg(opts).help({
|
||||||
|
bindOption: true,
|
||||||
|
optionOptions: {
|
||||||
|
namePrefix: '__',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
expect(command.help).toBeInstanceOf(Function)
|
||||||
|
expect(command.helpConfig).toHaveProperty('bindOption', true)
|
||||||
|
expect(command.helpConfig).toHaveProperty('optionOptions.namePrefix', '__')
|
||||||
|
expect(command.helpConfig).toHaveProperty('optionOptions.aliasPrefix', '-')
|
||||||
|
expect(command.helpConfig).toHaveProperty('optionOptions.nameStyle.color', 'yellow')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('binds command', () => {
|
||||||
|
const command = massarg(opts).help({
|
||||||
|
bindCommand: true,
|
||||||
|
})
|
||||||
|
expect(command.help).toBeInstanceOf(Function)
|
||||||
|
expect(command.helpConfig).toHaveProperty('bindCommand', true)
|
||||||
|
expect(command.commands.find((o) => o.name === 'help')).toBeTruthy()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('binds option', () => {
|
||||||
|
const command = massarg(opts).help({
|
||||||
|
bindOption: true,
|
||||||
|
})
|
||||||
|
expect(command.help).toBeInstanceOf(Function)
|
||||||
|
expect(command.helpConfig).toHaveProperty('bindOption', true)
|
||||||
|
expect(command.options.find((o) => o.name === 'help')).toBeTruthy()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('help string', () => {
|
||||||
|
const command = massarg(opts)
|
||||||
|
expect(command.helpString()).toContain(`Usage:`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('print help', () => {
|
||||||
|
const log = jest.spyOn(console, 'log').mockImplementation(() => {})
|
||||||
|
const command = massarg(opts)
|
||||||
|
command.printHelp()
|
||||||
|
expect(log).toHaveBeenCalled()
|
||||||
|
})
|
||||||
97
test/option.test.ts
Normal file
97
test/option.test.ts
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
import { MassargCommand } from '../src/command'
|
||||||
|
import { massarg } from '../src/index'
|
||||||
|
|
||||||
|
const opts = {
|
||||||
|
name: 'test',
|
||||||
|
description: 'test',
|
||||||
|
}
|
||||||
|
describe('option', () => {
|
||||||
|
test('add', () => {
|
||||||
|
const command = massarg(opts)
|
||||||
|
expect(command.option).toBeInstanceOf(Function)
|
||||||
|
expect(
|
||||||
|
command.option({ name: 'test2', description: 'test2', aliases: [], defaultValue: '' }),
|
||||||
|
).toBeInstanceOf(MassargCommand)
|
||||||
|
})
|
||||||
|
test('validate', () => {
|
||||||
|
expect(() =>
|
||||||
|
massarg(opts).option({
|
||||||
|
name: 'test2',
|
||||||
|
description: 123 as any,
|
||||||
|
aliases: [],
|
||||||
|
defaultValue: '',
|
||||||
|
}),
|
||||||
|
).toThrow('Expected string, received number')
|
||||||
|
})
|
||||||
|
test('add duplicate', () => {
|
||||||
|
expect(() =>
|
||||||
|
massarg(opts)
|
||||||
|
.option({
|
||||||
|
name: 'test2',
|
||||||
|
description: 'test2',
|
||||||
|
aliases: [],
|
||||||
|
defaultValue: '',
|
||||||
|
})
|
||||||
|
.option({
|
||||||
|
name: 'test2',
|
||||||
|
description: 'test2',
|
||||||
|
aliases: [],
|
||||||
|
defaultValue: '',
|
||||||
|
}),
|
||||||
|
).toThrow('Option "test2" already exists')
|
||||||
|
})
|
||||||
|
test('add 2 defaults', () => {
|
||||||
|
expect(() =>
|
||||||
|
massarg(opts)
|
||||||
|
.option({
|
||||||
|
name: 'test',
|
||||||
|
description: 'test2',
|
||||||
|
aliases: [],
|
||||||
|
isDefault: true,
|
||||||
|
})
|
||||||
|
.option({
|
||||||
|
name: 'test2',
|
||||||
|
description: 'test2',
|
||||||
|
aliases: [],
|
||||||
|
isDefault: true,
|
||||||
|
}),
|
||||||
|
).toThrow(
|
||||||
|
'Option "test2" cannot be set as default because option "test" is already set as default',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
test('uses output name', () => {
|
||||||
|
const command = massarg(opts).option({
|
||||||
|
name: 'test2',
|
||||||
|
description: 'test2',
|
||||||
|
aliases: [],
|
||||||
|
outputName: 'test',
|
||||||
|
})
|
||||||
|
expect(command.getArgs(['--test2', 'test'])).toHaveProperty('test', 'test')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('flag', () => {
|
||||||
|
test('add', () => {
|
||||||
|
const command = massarg(opts)
|
||||||
|
expect(command.flag).toBeInstanceOf(Function)
|
||||||
|
expect(command.flag({ name: 'test2', description: 'test2', aliases: [] })).toBeInstanceOf(
|
||||||
|
MassargCommand,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
test('add duplicate', () => {
|
||||||
|
expect(() =>
|
||||||
|
massarg(opts)
|
||||||
|
.flag({ name: 'test2', description: 'test2', aliases: [] })
|
||||||
|
.flag({ name: 'test2', description: 'test2', aliases: [] }),
|
||||||
|
).toThrow('Flag "test2" already exists')
|
||||||
|
})
|
||||||
|
test('validate', () => {
|
||||||
|
expect(() =>
|
||||||
|
massarg(opts).flag({
|
||||||
|
name: 'test2',
|
||||||
|
description: 123 as any,
|
||||||
|
aliases: [],
|
||||||
|
}),
|
||||||
|
).toThrow('Expected string, received number')
|
||||||
|
})
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user