From 38d4deecb109232669238678c888efb12686d1ed Mon Sep 17 00:00:00 2001 From: Karen Grigoryan Date: Tue, 26 May 2026 15:22:04 +0200 Subject: [PATCH] [Console] Fix method suggestion order (#270787) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #259251 ## Summary - Pins Console HTTP method completion ordering with explicit `sortText` values so Monaco does not fall back to alphabetical label sorting. - Keeps the existing method set unchanged while ordering `GET` first and `DELETE` last. ## Root Cause - Monaco uses `sortText` for completion ordering and falls back to the item label when `sortText` is missing, which can put `DELETE` before safer/default verbs. ## Fix - Assign stable `sortText` values to method completion items based on the intended canonical order. - Add a focused unit test that sorts method suggestions the same way and verifies `GET` is first and `DELETE` is last. ## Before image ## After image ## Test Plan - `node scripts/jest --config=src/platform/plugins/shared/console/jest.config.js src/platform/plugins/shared/console/public/application/containers/editor/monaco_editor_actions_provider.test.ts` — passed. - `node scripts/check_changes.ts` — passed. ## Release Note - Fixes Console autocomplete so `GET` is shown before `DELETE` when suggesting HTTP methods on an empty request line. Assisted with Cursor using GPT-5.5 Made with [Cursor](https://cursor.com) Co-authored-by: Cursor (cherry picked from commit 8849fcf6623fc7d917db93caba0c18d5e8f16b34) # Conflicts: # src/platform/plugins/shared/console/public/application/containers/editor/monaco_editor_actions_provider.test.ts --- .../monaco_editor_actions_provider.test.ts | 18 ++++++++++++++++++ .../editor/utils/autocomplete_utils.ts | 12 +++++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/platform/plugins/shared/console/public/application/containers/editor/monaco_editor_actions_provider.test.ts b/src/platform/plugins/shared/console/public/application/containers/editor/monaco_editor_actions_provider.test.ts index 29a194c45aae4..f044b8f1ca484 100644 --- a/src/platform/plugins/shared/console/public/application/containers/editor/monaco_editor_actions_provider.test.ts +++ b/src/platform/plugins/shared/console/public/application/containers/editor/monaco_editor_actions_provider.test.ts @@ -287,6 +287,24 @@ describe('Editor actions provider', () => { ); }); + it('orders method suggestions with GET first and DELETE last using sortText', async () => { + // Monaco sorts completion items by sortText, falling back to label. Without + // an explicit sortText, alphabetical sorting puts DELETE first (#259251). + mockGetParsedRequests.mockResolvedValue([]); + const completionItems = await editorActionsProvider.provideCompletionItems( + mockModel, + mockPosition, + mockContext + ); + const sortedByMonaco = [...(completionItems?.suggestions ?? [])].sort((a, b) => + String(a.sortText ?? a.label).localeCompare(String(b.sortText ?? b.label)) + ); + const orderedLabels = sortedByMonaco.map((s) => s.label); + expect(orderedLabels[0]).toBe('GET'); + expect(orderedLabels[orderedLabels.length - 1]).toBe('DELETE'); + expect(orderedLabels).toEqual(['GET', 'POST', 'PUT', 'PATCH', 'HEAD', 'DELETE']); + }); + it('returns completion items for url path if method already typed in', async () => { // mock a parsed request that only has a method mockGetParsedRequests.mockResolvedValue([ diff --git a/src/platform/plugins/shared/console/public/application/containers/editor/utils/autocomplete_utils.ts b/src/platform/plugins/shared/console/public/application/containers/editor/utils/autocomplete_utils.ts index f9485ab631518..e8e81703d0c60 100644 --- a/src/platform/plugins/shared/console/public/application/containers/editor/utils/autocomplete_utils.ts +++ b/src/platform/plugins/shared/console/public/application/containers/editor/utils/autocomplete_utils.ts @@ -60,21 +60,27 @@ const filterTermsWithoutName = (terms: ResultTerm[]): ResultTerm[] => terms.filter((term) => term.name !== undefined && term.name !== ''); /* - * This function returns an array of completion items for the request method + * This function returns an array of completion items for the request method. + * + * The order is deliberate: Monaco sorts completion items by `sortText` and + * falls back to alphabetical label sorting, which would otherwise put DELETE + * first (#259251). GET is the safest verb to accept by default and DELETE + * the most destructive, so we pin GET first and DELETE last. */ -const autocompleteMethods = ['GET', 'PUT', 'POST', 'DELETE', 'HEAD', 'PATCH']; +const autocompleteMethods = ['GET', 'POST', 'PUT', 'PATCH', 'HEAD', 'DELETE']; export const getMethodCompletionItems = ( model: monaco.editor.ITextModel, position: monaco.Position ): monaco.languages.CompletionItem[] => { // get the word before suggestions to replace when selecting a suggestion from the list const wordUntilPosition = model.getWordUntilPosition(position); - return autocompleteMethods.map((method) => ({ + return autocompleteMethods.map((method, index) => ({ label: method, insertText: method, detail: i18nTexts.method, // only used to configure the icon kind: monaco.languages.CompletionItemKind.Constant, + sortText: String(index), range: { // replace the whole word with the suggestion startColumn: wordUntilPosition.startColumn,