From 8a97f2087d07290474d9bf224057322ae2abe4bc Mon Sep 17 00:00:00 2001 From: Mike Donnalley Date: Thu, 22 Feb 2024 09:38:24 -0700 Subject: [PATCH 1/3] fix: only set timeout for TTY --- src/cli-ux/prompt.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cli-ux/prompt.ts b/src/cli-ux/prompt.ts index 0befdb805..7735b357c 100644 --- a/src/cli-ux/prompt.ts +++ b/src/cli-ux/prompt.ts @@ -36,7 +36,8 @@ function normal(options: IPromptConfig, retries = 100): Promise { output: process.stdout, }) let timeout: NodeJS.Timeout - if (options.timeout) { + // Only set the timeout if the input is a TTY + if (options.timeout && process.stdin.isTTY) { timeout = setTimeout(() => ac.abort(), options.timeout) signal.addEventListener( 'abort', From 271b66b18ad4689a55180bc751a20d547ec2fb8b Mon Sep 17 00:00:00 2001 From: Mike Donnalley Date: Thu, 22 Feb 2024 11:02:03 -0700 Subject: [PATCH 2/3] chore: use options.isTTY --- src/cli-ux/prompt.ts | 2 +- test/cli-ux/prompt.test.ts | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/cli-ux/prompt.ts b/src/cli-ux/prompt.ts index 7735b357c..afed56bc4 100644 --- a/src/cli-ux/prompt.ts +++ b/src/cli-ux/prompt.ts @@ -37,7 +37,7 @@ function normal(options: IPromptConfig, retries = 100): Promise { }) let timeout: NodeJS.Timeout // Only set the timeout if the input is a TTY - if (options.timeout && process.stdin.isTTY) { + if (options.timeout && options.isTTY) { timeout = setTimeout(() => ac.abort(), options.timeout) signal.addEventListener( 'abort', diff --git a/test/cli-ux/prompt.test.ts b/test/cli-ux/prompt.test.ts index 387be7dca..0f28c02ef 100644 --- a/test/cli-ux/prompt.test.ts +++ b/test/cli-ux/prompt.test.ts @@ -33,7 +33,7 @@ describe('prompt', () => { expect(answer).to.equal('answer') }) - it('should not require input', async () => { + it('should not require input if required = false', async () => { stubReadline(['']) const answer = await ux.prompt('Require input?', {required: false}) expect(answer).to.equal('') @@ -45,6 +45,16 @@ describe('prompt', () => { expect(answer).to.equal('default') }) + it('should timeout after provided timeout', async () => { + stubReadline(['']) + try { + await ux.prompt('Require input?', {timeout: 10}) + expect.fail('should have thrown') + } catch (error: any) { + expect(error.message).to.equal('Prompt timeout') + } + }) + it('should confirm with y', async () => { stubReadline(['y']) const answer = await ux.confirm('yes/no?') From 7ede36d8b9293dfbd95dc42cebb4ddfc028fcb12 Mon Sep 17 00:00:00 2001 From: Mike Donnalley Date: Thu, 22 Feb 2024 11:09:41 -0700 Subject: [PATCH 3/3] test: stub process.stdin.isTTY --- test/cli-ux/prompt.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/test/cli-ux/prompt.test.ts b/test/cli-ux/prompt.test.ts index 0f28c02ef..1afe3922b 100644 --- a/test/cli-ux/prompt.test.ts +++ b/test/cli-ux/prompt.test.ts @@ -47,6 +47,7 @@ describe('prompt', () => { it('should timeout after provided timeout', async () => { stubReadline(['']) + sandbox.stub(process, 'stdin').value({isTTY: true}) try { await ux.prompt('Require input?', {timeout: 10}) expect.fail('should have thrown')