diff --git a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/__tests__/autocomplete.command.enrich.test.ts b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/__tests__/autocomplete.command.enrich.test.ts index d046103b410b4..f3230f5705456 100644 --- a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/__tests__/autocomplete.command.enrich.test.ts +++ b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/__tests__/autocomplete.command.enrich.test.ts @@ -29,6 +29,7 @@ describe('autocomplete.suggest', () => { modes.map((mode) => `_${mode}:$0`), { triggerCharacter: '_' } ); + await assertSuggestions('from a | enrich _any: /', []); for (const mode of modes) { await assertSuggestions(`from a | enrich _${mode}:/`, expectedPolicyNameSuggestions, { triggerCharacter: ':', @@ -72,24 +73,27 @@ describe('autocomplete.suggest', () => { 'var0 = ', ...getPolicyFields('policy'), ]); - assertSuggestions(`from a | enrich policy on b with var0 /`, ['= $0', ',', '| ']); - assertSuggestions(`from a | enrich policy on b with var0 = /`, [ + await assertSuggestions(`from a | enrich policy on b with var0 /`, ['= $0', ',', '| ']); + await assertSuggestions(`from a | enrich policy on b with var0 = /`, [ ...getPolicyFields('policy'), ]); - assertSuggestions(`from a | enrich policy on b with var0 = keywordField /`, [',', '| ']); - assertSuggestions(`from a | enrich policy on b with var0 = keywordField, /`, [ + await assertSuggestions(`from a | enrich policy on b with var0 = keywordField /`, [ + ',', + '| ', + ]); + await assertSuggestions(`from a | enrich policy on b with var0 = keywordField, /`, [ 'var1 = ', ...getPolicyFields('policy'), ]); - assertSuggestions(`from a | enrich policy on b with var0 = keywordField, var1 /`, [ + await assertSuggestions(`from a | enrich policy on b with var0 = keywordField, var1 /`, [ '= $0', ',', '| ', ]); - assertSuggestions(`from a | enrich policy on b with var0 = keywordField, var1 = /`, [ + await assertSuggestions(`from a | enrich policy on b with var0 = keywordField, var1 = /`, [ ...getPolicyFields('policy'), ]); - assertSuggestions( + await assertSuggestions( `from a | enrich policy with /`, ['var0 = ', ...getPolicyFields('policy')], { triggerCharacter: ' ' } diff --git a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.ts b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.ts index ba23575931c8b..815c1c964f18f 100644 --- a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.ts +++ b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.ts @@ -23,7 +23,6 @@ import { getCommandDefinition, getCommandOption, getFunctionDefinition, - getLastNonWhitespaceChar, isAssignment, isAssignmentComplete, isColumnItem, @@ -33,7 +32,6 @@ import { isOptionItem, isRestartingExpression, isSourceCommand, - isSettingItem, isSourceItem, isTimeIntervalItem, getAllFunctions, @@ -61,14 +59,12 @@ import { buildFieldsDefinitions, buildPoliciesDefinitions, getNewVariableSuggestion, - buildNoPoliciesAvailableDefinition, getFunctionSuggestions, buildMatchingFieldsDefinition, getCompatibleLiterals, buildConstantsDefinitions, buildVariablesDefinitions, buildOptionDefinition, - buildSettingDefinitions, buildValueDefinitions, getDateLiterals, buildFieldsDefinitionsWithMetadata, @@ -225,16 +221,6 @@ export async function suggest( supportsControls ); } - if (astContext.type === 'setting') { - return getSettingArgsSuggestions( - innerText, - ast, - astContext, - getFieldsByType, - getFieldsMap, - getPolicyMetadata - ); - } if (astContext.type === 'option') { // need this wrap/unwrap thing to make TS happy const { option, ...rest } = astContext; @@ -427,6 +413,7 @@ async function getSuggestionsWithinCommandExpression( callbacks, getVariablesByType, supportsControls, + getPolicies, }); } else { // The deprecated path. @@ -870,29 +857,10 @@ async function getExpressionSuggestionsByType( } } } - if (argDef.type === 'source') { - if (argDef.innerTypes?.includes('policy')) { - // ... | ENRICH - const policies = await getPolicies(); - const lastWord = findFinalWord(innerText); - if (lastWord !== '') { - policies.forEach((suggestion) => { - suggestions.push({ - ...suggestion, - rangeToReplace: { - start: innerText.length - lastWord.length + 1, - end: innerText.length + 1, - }, - }); - }); - } - suggestions.push(...(policies.length ? policies : [buildNoPoliciesAvailableDefinition()])); - } - } } const nonOptionArgs = command.args.filter( - (arg) => !isOptionItem(arg) && !isSettingItem(arg) && !Array.isArray(arg) && !arg.incomplete + (arg) => !isOptionItem(arg) && !Array.isArray(arg) && !arg.incomplete ); // Perform some checks on mandatory arguments const mandatoryArgsAlreadyPresent = @@ -1236,35 +1204,6 @@ async function getListArgsSuggestions( return suggestions; } -async function getSettingArgsSuggestions( - innerText: string, - commands: ESQLCommand[], - { - command, - node, - }: { - command: ESQLCommand; - node: ESQLSingleAstItem | undefined; - }, - getFieldsByType: GetColumnsByTypeFn, - getFieldsMaps: GetFieldsMapFn, - getPolicyMetadata: GetPolicyMetadataFn -) { - const suggestions = []; - - const settingDefs = getCommandDefinition(command.name).modes || []; - - if (settingDefs.length) { - const lastChar = getLastNonWhitespaceChar(innerText); - const matchingSettingDefs = settingDefs.filter(({ prefix }) => lastChar === prefix); - if (matchingSettingDefs.length) { - // COMMAND _ - suggestions.push(...matchingSettingDefs.flatMap(buildSettingDefinitions)); - } - } - return suggestions; -} - /** * @deprecated — this will disappear when https://github.com/elastic/kibana/issues/195418 is complete * because "options" will be handled in imperative command-specific routines instead of being independent. diff --git a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/commands/join/index.ts b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/commands/join/index.ts index 80f98c5215aa2..5fb82556819b8 100644 --- a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/commands/join/index.ts +++ b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/commands/join/index.ts @@ -102,7 +102,6 @@ export const suggest: CommandBaseDefinition<'join'>['suggest'] = async ({ getColumnsByType, definition, callbacks, - previousCommands, }: CommandSuggestParams<'join'>): Promise => { let commandText: string = innerText; diff --git a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/factories.ts b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/factories.ts index b4ef8a84cb341..85e309b7e1221 100644 --- a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/factories.ts +++ b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/autocomplete/factories.ts @@ -18,7 +18,6 @@ import { timeUnitsToSuggest } from '../definitions/literals'; import { FunctionDefinition, CommandOptionsDefinition, - CommandModeDefinition, FunctionParameterType, } from '../definitions/types'; import { shouldBeQuotedSource, shouldBeQuotedText } from '../shared/helpers'; @@ -399,42 +398,6 @@ export const buildOptionDefinition = ( return completeItem; }; -export const buildSettingDefinitions = ( - setting: CommandModeDefinition -): SuggestionRawDefinition[] => { - // for now there's just a single setting with one argument - return setting.values.map(({ name, description }) => ({ - label: `${setting.prefix || ''}${name}`, - text: `${setting.prefix || ''}${name}:$0`, - asSnippet: true, - kind: 'Reference', - detail: description ? `${setting.description} - ${description}` : setting.description, - sortText: 'D', - command: TRIGGER_SUGGESTION_COMMAND, - })); -}; - -export const buildNoPoliciesAvailableDefinition = (): SuggestionRawDefinition => ({ - label: i18n.translate('kbn-esql-validation-autocomplete.esql.autocomplete.noPoliciesLabel', { - defaultMessage: 'No available policy', - }), - text: '', - kind: 'Issue', - detail: i18n.translate( - 'kbn-esql-validation-autocomplete.esql.autocomplete.noPoliciesLabelsFound', - { - defaultMessage: 'Click to create', - } - ), - sortText: 'D', - command: { - id: 'esql.policies.create', - title: i18n.translate('kbn-esql-validation-autocomplete.esql.autocomplete.createNewPolicy', { - defaultMessage: 'Click to create', - }), - }, -}); - export function getUnitDuration(unit: number = 1) { const filteredTimeLiteral = timeUnitsToSuggest.filter(({ name }) => { const result = /s$/.test(name); diff --git a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/definitions/commands.ts b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/definitions/commands.ts index 2c421c90fb53d..456559f75e9b7 100644 --- a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/definitions/commands.ts +++ b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/definitions/commands.ts @@ -27,7 +27,6 @@ import { isFunctionOperatorParam, isLiteralItem, } from '../shared/helpers'; -import { ENRICH_MODES } from './settings'; import { appendSeparatorOption, asOption, @@ -36,6 +35,8 @@ import { onOption, withOption, } from './options'; +import { ENRICH_MODES } from './settings'; + import type { CommandDefinition } from './types'; import { suggest as suggestForSort } from '../autocomplete/commands/sort'; import { suggest as suggestForKeep } from '../autocomplete/commands/keep'; @@ -48,6 +49,7 @@ import { suggest as suggestForRow } from '../autocomplete/commands/row'; import { suggest as suggestForShow } from '../autocomplete/commands/show'; import { suggest as suggestForGrok } from '../autocomplete/commands/grok'; import { suggest as suggestForDissect } from '../autocomplete/commands/dissect'; +import { suggest as suggestForEnrich } from '../autocomplete/commands/enrich'; const statsValidator = (command: ESQLCommand) => { const messages: ESQLMessage[] = []; @@ -517,14 +519,15 @@ export const commandDefinitions: Array> = [ multipleParams: false, params: [{ name: 'policyName', type: 'source', innerTypes: ['policy'] }], }, + suggest: suggestForEnrich, }, { name: 'hidden_command', description: 'A test fixture to test hidden-ness', hidden: true, examples: [], - modes: [], options: [], + modes: [], signature: { params: [], multipleParams: false, diff --git a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/definitions/settings.ts b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/definitions/settings.ts index a367d1cb65f7a..f2ffcab414fa4 100644 --- a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/definitions/settings.ts +++ b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/definitions/settings.ts @@ -10,6 +10,7 @@ import { i18n } from '@kbn/i18n'; import type { CommandModeDefinition } from './types'; +/** @deprecated — the concept of a "mode" will go away soon */ export const ENRICH_MODES: CommandModeDefinition = { name: 'ccq.mode', description: i18n.translate('kbn-esql-validation-autocomplete.esql.definitions.ccqModeDoc', { diff --git a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/definitions/types.ts b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/definitions/types.ts index d3db0195d172d..c67c90a46f6cb 100644 --- a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/definitions/types.ts +++ b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/definitions/types.ts @@ -234,6 +234,10 @@ export interface CommandSuggestParams { * @returns */ getSources: () => Promise; + /** + * Fetch suggestions for all available policies + */ + getPolicies: () => Promise; /** * Inspect the AST and returns the sources that are used in the query. * @param type diff --git a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/shared/context.ts b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/shared/context.ts index 2441db077af8a..d30fcd9a4f01f 100644 --- a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/shared/context.ts +++ b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/shared/context.ts @@ -18,13 +18,11 @@ import { Walker, isIdentifier, } from '@kbn/esql-ast'; -import { ENRICH_MODES } from '../definitions/settings'; import { EDITOR_MARKER } from './constants'; import { isOptionItem, isColumnItem, isSourceItem, - isSettingItem, pipePrecedesCurrentWord, getFunctionDefinition, } from './helpers'; @@ -65,10 +63,6 @@ function findOption(nodes: ESQLAstItem[], offset: number): ESQLCommandOption | u return findCommandSubType(nodes, offset, isOptionItem); } -function findSetting(nodes: ESQLAstItem[], offset: number): ESQLCommandMode | undefined { - return findCommandSubType(nodes, offset, isSettingItem); -} - function findCommandSubType( nodes: ESQLAstItem[], offset: number, @@ -130,7 +124,6 @@ function findAstPosition(ast: ESQLAst, offset: number) { command: removeMarkerArgFromArgsList(command)!, option: removeMarkerArgFromArgsList(findOption(command.args, offset)), node: removeMarkerArgFromArgsList(cleanMarkerNode(findNode(command.args, offset))), - setting: removeMarkerArgFromArgsList(findSetting(command.args, offset)), }; } @@ -170,16 +163,16 @@ export function getAstContext(queryString: string, ast: ESQLAst, offset: number) }; } - const { command, option, setting, node } = findAstPosition(ast, offset); + const { command, option, node } = findAstPosition(ast, offset); if (node) { if (node.type === 'literal' && node.literalType === 'keyword') { // command ... "" - return { type: 'value' as const, command, node, option, setting }; + return { type: 'value' as const, command, node, option }; } if (node.type === 'function') { if (['in', 'not_in'].includes(node.name) && Array.isArray(node.args[1])) { // command ... a in ( ) - return { type: 'list' as const, command, node, option, setting }; + return { type: 'list' as const, command, node, option }; } if ( isNotEnrichClauseAssigment(node, command) && @@ -190,24 +183,19 @@ export function getAstContext(queryString: string, ast: ESQLAst, offset: number) !(isBuiltinFunction(node) && command.name !== 'stats') ) { // command ... fn( ) - return { type: 'function' as const, command, node, option, setting }; + return { type: 'function' as const, command, node, option }; } } - // for now it's only an enrich thing - if (node.type === 'source' && node.text === ENRICH_MODES.prefix) { - // command _ - return { type: 'setting' as const, command, node, option, setting }; - } } if (!command || (queryString.length <= offset && pipePrecedesCurrentWord(queryString))) { // // ... | - return { type: 'newCommand' as const, command: undefined, node, option, setting }; + return { type: 'newCommand' as const, command: undefined, node, option }; } // TODO — remove this option branch once https://github.com/elastic/kibana/issues/195418 is complete if (command && isOptionItem(command.args[command.args.length - 1]) && command.name !== 'stats') { if (option) { - return { type: 'option' as const, command, node, option, setting }; + return { type: 'option' as const, command, node, option }; } } @@ -217,6 +205,5 @@ export function getAstContext(queryString: string, ast: ESQLAst, offset: number) command, option, node, - setting, }; } diff --git a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/shared/helpers.ts b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/shared/helpers.ts index 200dee245a4cc..8e3c9a83d4c7f 100644 --- a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/shared/helpers.ts +++ b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/shared/helpers.ts @@ -11,7 +11,6 @@ import { Walker, type ESQLAstItem, type ESQLColumn, - type ESQLCommandMode, type ESQLCommandOption, type ESQLFunction, type ESQLLiteral, @@ -20,6 +19,7 @@ import { type ESQLTimeInterval, } from '@kbn/esql-ast'; import { + ESQLCommandMode, ESQLIdentifier, ESQLInlineCast, ESQLParamLiteral, @@ -65,6 +65,7 @@ export function isSingleItem(arg: ESQLAstItem): arg is ESQLSingleAstItem { return arg && !Array.isArray(arg); } +/** @deprecated — a "setting" is a concept we will be getting rid of soon */ export function isSettingItem(arg: ESQLAstItem): arg is ESQLCommandMode { return isSingleItem(arg) && arg.type === 'mode'; } diff --git a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/validation/validation.ts b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/validation/validation.ts index 9a43caf8e359a..77653250c7e30 100644 --- a/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/validation/validation.ts +++ b/src/platform/packages/shared/kbn-esql-validation-autocomplete/src/validation/validation.ts @@ -709,6 +709,7 @@ function validateFunction({ return uniqBy(messages, ({ location }) => `${location.min}-${location.max}`); } +/** @deprecated — "command settings" will be removed soon */ function validateSetting( setting: ESQLCommandMode, settingDef: CommandModeDefinition | undefined,