Skip to content

Commit

Permalink
feat: args read stdin (#100)
Browse files Browse the repository at this point in the history
  • Loading branch information
RasPhilCo committed Jan 27, 2021
1 parent 57924df commit caea554
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/interfaces/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface Arg<T = string> {
parse?: ParseFn<T>;
default?: T | (() => T);
options?: string[];
ignoreStdin?: boolean;
}

export interface ArgBase<T> {
Expand All @@ -21,6 +22,7 @@ export interface ArgBase<T> {
default?: T | (() => Promise<T>);
input?: string;
options?: string[];
ignoreStdin?: boolean;
}

export type RequiredArg<T> = ArgBase<T> & {
Expand Down
24 changes: 23 additions & 1 deletion src/parser/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@ try {
debug = () => {}
}

const readStdin = async () => {
const {stdin} = process
let result
if (stdin.isTTY) return result
result = ''
stdin.setEncoding('utf8')
for await (const chunk of stdin) {
result += chunk
}
return result
}

export class Parser<T extends ParserInput, TFlags extends OutputFlags<T['flags']>, TArgs extends OutputArgs<T['args']>> {
private readonly argv: string[]

Expand Down Expand Up @@ -200,6 +212,7 @@ export class Parser<T extends ParserInput, TFlags extends OutputFlags<T['flags']
private async _argv(): Promise<any[]> {
const args: any[] = []
const tokens = this._argTokens
let stdinRead = false
for (let i = 0; i < Math.max(this.input.args.length, tokens.length); i++) {
const token = tokens[i]
const arg = this.input.args[i]
Expand All @@ -213,7 +226,16 @@ export class Parser<T extends ParserInput, TFlags extends OutputFlags<T['flags']
} else {
args[i] = token.input
}
} else if ('default' in arg) {
} else if (!arg.ignoreStdin && !stdinRead) {
// eslint-disable-next-line no-await-in-loop
let stdin = await readStdin()
if (stdin) {
stdin = stdin.trim()
args[i] = stdin
}
stdinRead = true
}
if (!args[i] && 'default' in arg) {
if (typeof arg.default === 'function') {
// eslint-disable-next-line no-await-in-loop
const f = await arg.default()
Expand Down

0 comments on commit caea554

Please sign in to comment.