From 92158f0d882ec672aec4a59fbd6d717155403f0b Mon Sep 17 00:00:00 2001 From: lte_z Date: Mon, 25 May 2026 14:08:47 +0800 Subject: [PATCH 1/2] fix: improve delete confirmation word handling --- .../deleteCollection/deleteCollection.ts | 1 + src/commands/deleteDatabase/deleteDatabase.ts | 1 + src/commands/index.dropIndex/dropIndex.ts | 2 +- src/utils/dialogs/getConfirmation.ts | 54 +++++++++++++++++-- 4 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/commands/deleteCollection/deleteCollection.ts b/src/commands/deleteCollection/deleteCollection.ts index 0445acb21..8fa4c90f4 100644 --- a/src/commands/deleteCollection/deleteCollection.ts +++ b/src/commands/deleteCollection/deleteCollection.ts @@ -45,6 +45,7 @@ export async function deleteCollection(context: IActionContext, node: Collection l10n.t('Delete "{nodeName}"?', { nodeName: node.collectionInfo.name }), message + '\n' + l10n.t('This cannot be undone.'), node.collectionInfo.name, + { fallbackWord: 'delete' }, ); if (!confirmed) { diff --git a/src/commands/deleteDatabase/deleteDatabase.ts b/src/commands/deleteDatabase/deleteDatabase.ts index 4ad5deb45..be392733a 100644 --- a/src/commands/deleteDatabase/deleteDatabase.ts +++ b/src/commands/deleteDatabase/deleteDatabase.ts @@ -44,6 +44,7 @@ export async function deleteDatabase(context: IActionContext, node: DatabaseItem '\n' + l10n.t('This cannot be undone.'), databaseId, + { fallbackWord: 'delete' }, ); if (!confirmed) { diff --git a/src/commands/index.dropIndex/dropIndex.ts b/src/commands/index.dropIndex/dropIndex.ts index 321703788..e67cadc70 100644 --- a/src/commands/index.dropIndex/dropIndex.ts +++ b/src/commands/index.dropIndex/dropIndex.ts @@ -32,7 +32,7 @@ export async function dropIndex(context: IActionContext, node: IndexItem): Promi l10n.t('Delete index "{indexName}" from collection "{collectionName}"?', { indexName, collectionName }) + '\n' + l10n.t('This cannot be undone.'), - indexName, + 'delete', ); if (!confirmed) { diff --git a/src/utils/dialogs/getConfirmation.ts b/src/utils/dialogs/getConfirmation.ts index 9d5e357ec..4600208a4 100644 --- a/src/utils/dialogs/getConfirmation.ts +++ b/src/utils/dialogs/getConfirmation.ts @@ -14,25 +14,56 @@ enum ConfirmationStyle { buttonConfirmation = 'buttonConfirmation', } +export interface WordConfirmationOptions { + /** + * Fallback word to use when the challenge word is too complex to type comfortably. + * Applied when the word exceeds maxLength or contains characters outside [a-zA-Z]. + */ + fallbackWord?: string; + + /** Maximum allowed length before the fallback is used. Defaults to 16. */ + maxLength?: number; +} + +function resolveConfirmationWord(word: string, options?: WordConfirmationOptions): string { + const fallback = options?.fallbackWord; + + if (!fallback) { + return word; + } + + const limit = options?.maxLength ?? 16; + + if (word.length > limit || !/^[a-zA-Z]+$/.test(word)) { + return fallback; + } + + return word; +} + /** * Prompts the user for a confirmation based on the configured confirmation style. * * @param title - The title of the confirmation dialog. * @param message - The message to display in the confirmation dialog. This message will be suffixed with instructions for a specific prompt. * @param expectedConfirmationWord - The word that the user must type to confirm the action when the confirmation style is set to 'Word Confirmation'. + * @param options - Optional settings for word confirmations. Only takes effect when the + * confirmation style is set to 'Word Confirmation'. When fallbackWord is provided, + * it is used if the expected word exceeds maxLength or contains characters outside [a-zA-Z]. * @returns A promise that resolves to a boolean indicating whether the user confirmed the action. */ export async function getConfirmationAsInSettings( title: string, message: string, expectedConfirmationWord: string, + options?: WordConfirmationOptions, ): Promise { const deleteConfirmation: ConfirmationStyle = vscode.workspace .getConfiguration() .get(ext.settingsKeys.confirmationStyle, ConfirmationStyle.wordConfirmation); if (deleteConfirmation === ConfirmationStyle.wordConfirmation) { - return await getConfirmationWithWordQuestion(title, message, expectedConfirmationWord); + return await getConfirmationWithWordQuestion(title, message, expectedConfirmationWord, options); } else if (deleteConfirmation === ConfirmationStyle.challengeConfirmation) { return await getConfirmationWithNumberQuiz(title, message); } @@ -40,18 +71,31 @@ export async function getConfirmationAsInSettings( return await getConfirmationWithClick(title, message); } +/** + * Prompts the user to type a confirmation word. + * + * @param title - The title of the confirmation dialog. + * @param message - The message to display in the confirmation dialog. This message will be suffixed with word confirmation instructions. + * @param expectedConfirmationWord - The word that the user must type to confirm the action. + * @param options - Optional settings for word confirmations. When fallbackWord is provided, + * it is used if the expected word exceeds maxLength or contains characters outside [a-zA-Z]. + * @returns A promise that resolves to a boolean indicating whether the user entered the confirmation word. + */ export async function getConfirmationWithWordQuestion( title: string, message: string, expectedConfirmationWord: string, + options?: WordConfirmationOptions, ): Promise { + const effectiveWord = resolveConfirmationWord(expectedConfirmationWord, options); + const result = await vscode.window.showInputBox({ title: title, prompt: message + '\n\n' + l10n.t('Please enter the word "{expectedConfirmationWord}" to confirm the operation.', { - expectedConfirmationWord, + expectedConfirmationWord: effectiveWord, }) + '\n\n' + l10n.t('Note: This confirmation type can be configured in the extension settings.'), @@ -61,14 +105,14 @@ export async function getConfirmationWithWordQuestion( if ( val && 0 === - val.localeCompare(expectedConfirmationWord, undefined, { + val.localeCompare(effectiveWord, undefined, { sensitivity: 'accent', }) ) { return undefined; } return l10n.t('Please enter the word "{expectedConfirmationWord}" to confirm the operation.', { - expectedConfirmationWord, + expectedConfirmationWord: effectiveWord, }); }, }); @@ -79,7 +123,7 @@ export async function getConfirmationWithWordQuestion( return ( 0 === - result.localeCompare(expectedConfirmationWord, undefined, { + result.localeCompare(effectiveWord, undefined, { sensitivity: 'accent', }) ); From 99cf4417468a6968e316f31c68c7718f25c58cd8 Mon Sep 17 00:00:00 2001 From: lte_z Date: Mon, 25 May 2026 14:43:51 +0800 Subject: [PATCH 2/2] docs: clarify confirmation word fallback behavior --- src/utils/dialogs/getConfirmation.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/dialogs/getConfirmation.ts b/src/utils/dialogs/getConfirmation.ts index 4600208a4..5f15eb817 100644 --- a/src/utils/dialogs/getConfirmation.ts +++ b/src/utils/dialogs/getConfirmation.ts @@ -46,7 +46,7 @@ function resolveConfirmationWord(word: string, options?: WordConfirmationOptions * * @param title - The title of the confirmation dialog. * @param message - The message to display in the confirmation dialog. This message will be suffixed with instructions for a specific prompt. - * @param expectedConfirmationWord - The word that the user must type to confirm the action when the confirmation style is set to 'Word Confirmation'. + * @param expectedConfirmationWord - The default word used for word confirmation. It may be replaced by fallbackWord when the configured fallback rules apply. * @param options - Optional settings for word confirmations. Only takes effect when the * confirmation style is set to 'Word Confirmation'. When fallbackWord is provided, * it is used if the expected word exceeds maxLength or contains characters outside [a-zA-Z]. @@ -76,7 +76,7 @@ export async function getConfirmationAsInSettings( * * @param title - The title of the confirmation dialog. * @param message - The message to display in the confirmation dialog. This message will be suffixed with word confirmation instructions. - * @param expectedConfirmationWord - The word that the user must type to confirm the action. + * @param expectedConfirmationWord - The default word used for word confirmation. It may be replaced by fallbackWord when the configured fallback rules apply. * @param options - Optional settings for word confirmations. When fallbackWord is provided, * it is used if the expected word exceeds maxLength or contains characters outside [a-zA-Z]. * @returns A promise that resolves to a boolean indicating whether the user entered the confirmation word.