diff --git a/.changeset/shaggy-pens-sort.md b/.changeset/shaggy-pens-sort.md new file mode 100644 index 0000000000..b36496d9a6 --- /dev/null +++ b/.changeset/shaggy-pens-sort.md @@ -0,0 +1,6 @@ +--- +'@aws-amplify/cli-core': patch +'@aws-amplify/backend-cli': patch +--- + +add a required input prompt for use in region input diff --git a/packages/cli-core/API.md b/packages/cli-core/API.md index b966cfeca1..616c6aee11 100644 --- a/packages/cli-core/API.md +++ b/packages/cli-core/API.md @@ -13,7 +13,12 @@ import { WriteStream } from 'node:tty'; export class AmplifyPrompter { static input: (options: { message: string; + required?: never; defaultValue?: string; + } | { + message: string; + required: true; + defaultValue?: never; }) => Promise; static secretValue: (promptMessage?: string) => Promise; static yesOrNo: (options: { diff --git a/packages/cli-core/src/prompter/amplify_prompts.ts b/packages/cli-core/src/prompter/amplify_prompts.ts index d398687cbe..447049ef4e 100644 --- a/packages/cli-core/src/prompter/amplify_prompts.ts +++ b/packages/cli-core/src/prompter/amplify_prompts.ts @@ -43,16 +43,32 @@ export class AmplifyPrompter { * @param options for displaying the prompt * @param options.message display for the prompt * @param options.defaultValue if user submits without typing anything. Default: "." + * @param options.required if the user input is required, incompatible with options.defaultValue * @returns Promise the user input */ - static input = async (options: { - message: string; - defaultValue?: string; - }): Promise => { - const response = await input({ + static input = async ( + options: + | { + message: string; + required?: never; + defaultValue?: string; + } + | { + message: string; + required: true; + defaultValue?: never; + } + ): Promise => { + if (options.required) { + return input({ + message: options.message, + validate: (val: string) => + val && val.length > 0 ? true : 'Cannot be empty', + }); + } + return input({ message: options.message, default: options.defaultValue ?? '', }); - return response; }; } diff --git a/packages/cli/src/commands/configure/configure_profile_command.test.ts b/packages/cli/src/commands/configure/configure_profile_command.test.ts index f387069205..1c316875a2 100644 --- a/packages/cli/src/commands/configure/configure_profile_command.test.ts +++ b/packages/cli/src/commands/configure/configure_profile_command.test.ts @@ -42,7 +42,7 @@ void describe('configure command', () => { emitSuccessMock.mock.resetCalls(); }); - void it('configures a profile with an IAM user', async (contextual) => { + void it('fails to configure a profile with a name that already has a profile', async (contextual) => { const mockProfileExists = mock.method( profileController, 'profileExists', @@ -65,7 +65,7 @@ void describe('configure command', () => { }); }); - void it('configures a profile with an IAM user', async (contextual) => { + void it('configures a profile with an existing IAM user credentials', async (contextual) => { const mockProfileExists = mock.method( profileController, 'profileExists', @@ -84,10 +84,10 @@ void describe('configure command', () => { } ); - const mockInput = contextual.mock.method( + const mockRequiredInput = contextual.mock.method( AmplifyPrompter, 'input', - (options: { message: string; defaultValue?: string }) => { + (options: { message: string; required: true }) => { if (options.message.includes('Enter the AWS region to use')) { return Promise.resolve(testRegion); } @@ -105,7 +105,7 @@ void describe('configure command', () => { assert.equal(mockProfileExists.mock.callCount(), 1); assert.equal(mockSecretValue.mock.callCount(), 2); - assert.equal(mockInput.mock.callCount(), 1); + assert.equal(mockRequiredInput.mock.callCount(), 1); assert.equal(mockHasIAMUser.mock.callCount(), 1); assert.equal(mockAppendAWSFiles.mock.callCount(), 1); assert.deepStrictEqual(mockAppendAWSFiles.mock.calls[0].arguments[0], { @@ -121,7 +121,7 @@ void describe('configure command', () => { }); }); - void it('configures a profile without an IAM user', async (contextual) => { + void it('configures a profile without an existing IAM user', async (contextual) => { const mockProfileExists = mock.method( profileController, 'profileExists', diff --git a/packages/cli/src/commands/configure/configure_profile_command.ts b/packages/cli/src/commands/configure/configure_profile_command.ts index 7be59b0a49..72d3a1d785 100644 --- a/packages/cli/src/commands/configure/configure_profile_command.ts +++ b/packages/cli/src/commands/configure/configure_profile_command.ts @@ -73,6 +73,7 @@ export class ConfigureProfileCommand const region = await AmplifyPrompter.input({ message: `Enter the AWS region to use with the '${profileName}' profile (eg us-east-1, us-west-2, etc):`, + required: true, }); await this.profileController.createOrAppendAWSFiles({