Skip to content

Commit

Permalink
feat: add 'only' option to allowStdin (#900)
Browse files Browse the repository at this point in the history
* feat: add 'only' option to allowStdin

* test: add more allowStdin tests
  • Loading branch information
mdonnalley committed Jan 2, 2024
1 parent dd97db0 commit 4f7346e
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 3 deletions.
5 changes: 3 additions & 2 deletions src/interfaces/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,10 +222,11 @@ export type OptionFlagProps = FlagProps & {
*/
delimiter?: ','
/**
* Allow input value to be read from stdin.
* Allow input value to be read from stdin if the provided value is `-`.
* If set to `only`, the flag will only accept input from stdin.
* Should only be used on one flag at a time.
*/
allowStdin?: boolean
allowStdin?: boolean | 'only'
}

export type FlagParserContext = Command & {token: FlagToken}
Expand Down
4 changes: 4 additions & 0 deletions src/parser/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,10 @@ export class Parser<
throw new CLIError(`Flag --${name} expects a value`)
}

if (flag.allowStdin === 'only' && input !== '-') {
throw new CLIError(`Flag --${name} can only be read from stdin. The value must be "-".`)
}

if (flag.allowStdin && input === '-') {
const stdin = await readStdin()
if (stdin) {
Expand Down
44 changes: 43 additions & 1 deletion test/parser/parse.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1872,7 +1872,7 @@ describe('allowStdin', () => {
sandbox.restore()
})

it('should read stdin as input for flag', async () => {
it('should read stdin as input for flag when value is "-"', async () => {
sandbox.stub(parser, 'readStdin').returns(stdinPromise)
const out = await parse(['--myflag', '-'], {
flags: {
Expand All @@ -1883,4 +1883,46 @@ describe('allowStdin', () => {
expect(out.flags.myflag).to.equals(stdinValue)
expect(out.raw[0].input).to.equal('x')
})

it('should not read stdin when value is not "-"', async () => {
sandbox.stub(parser, 'readStdin').returns(stdinPromise)
const out = await parse(['--myflag', 'foo'], {
flags: {
myflag: Flags.string({allowStdin: true}),
},
})

expect(out.flags.myflag).to.equals('foo')
expect(out.raw[0].input).to.equal('foo')
})

it('should read stdin as input for flag when allowStdin is "only" and when value is "-"', async () => {
sandbox.stub(parser, 'readStdin').returns(stdinPromise)
const out = await parse(['--myflag', '-'], {
flags: {
myflag: Flags.string({allowStdin: 'only'}),
},
})

expect(out.flags.myflag).to.equals(stdinValue)
expect(out.raw[0].input).to.equal('x')
})

it('should throw if allowStdin is "only" but value is not "-"', async () => {
sandbox.stub(parser, 'readStdin').returns(stdinPromise)
try {
await parse(['--myflag', 'INVALID'], {
flags: {
myflag: Flags.string({allowStdin: 'only'}),
},
})
expect.fail('Should have thrown an error')
} catch (error) {
if (error instanceof CLIError) {
expect(error.message).to.equal('Flag --myflag can only be read from stdin. The value must be "-".')
} else {
expect.fail('Should have thrown a CLIError')
}
}
})
})

0 comments on commit 4f7346e

Please sign in to comment.