Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions redisinsight/api/src/__mocks__/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export const mockMainCommands = {
complexity: 'O(N). Where N is the number of configured users.',
since: '6.0.0',
group: 'server',
provider: 'main',
},
};

Expand All @@ -19,6 +20,7 @@ export const mockRedisearchCommands = {
],
since: '1.0.0',
group: 'search',
provider: 'search',
},
};

Expand All @@ -39,6 +41,7 @@ export const mockRedijsonCommands = {
],
since: '1.0.0',
group: 'json',
provider: 'json',
},
};

Expand Down Expand Up @@ -102,6 +105,7 @@ export const mockRedistimeseriesCommands = {
],
since: '1.0.0',
group: 'timeseries',
provider: 'timeseries',
},
};

Expand Down Expand Up @@ -143,6 +147,7 @@ export const mockRedisaiCommands = {
],
since: '1.2.5',
group: 'tensor',
provider: 'sai',
},
};

Expand All @@ -161,6 +166,7 @@ export const mockRedisgraphCommands = {
],
since: '1.0.0',
group: 'graph',
provider: 'graph',
},
};

Expand Down
15 changes: 10 additions & 5 deletions redisinsight/api/src/modules/commands/commands.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { assign } from 'lodash';
import { assign, forEach } from 'lodash';
import { Injectable, OnModuleInit } from '@nestjs/common';
import { CommandsJsonProvider } from 'src/modules/commands/commands-json.provider';

Expand Down Expand Up @@ -31,10 +31,15 @@ export class CommandsService implements OnModuleInit {
* Get all commands merged into single object
*/
async getAll(): Promise<any> {
return assign(
{},
...Object.values(await this.getCommandsGroups()),
);
const commands = {};

Object.entries(await this.getCommandsGroups()).forEach(([provider, groupCommands]) => {
return forEach(groupCommands as {}, (value: {}, command) => {
commands[command] = { ...value, provider };
});
});

return commands;
}

async getCommandsGroups(): Promise<any> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,19 @@ const scanArgs = [
type: 'integer',
},
{
command: 'MATCH',
token: 'MATCH',
name: 'pattern',
type: 'pattern',
optional: true,
},
{
command: 'COUNT',
token: 'COUNT',
name: 'count',
type: 'integer',
optional: true,
},
{
command: 'TYPE',
token: 'TYPE',
name: 'type',
type: 'string',
optional: true,
Expand Down Expand Up @@ -79,8 +79,42 @@ describe('CliAutocomplete', () => {
expect(store.getActions().slice(-2)).toEqual(expectedActions)
})

it('Autocomplete should be only with optional args for "scan" command with filled in required args ', () => {
it('Autocomplete should be only with optional args for "scan" command with filled in required args (new realization)', () => {
const autocompleteOptionalText = '[MATCH pattern] [COUNT count] [TYPE type]'
const { queryByTestId } = render(
<CliAutocomplete
{...instance(mockedProps)}
provider="main"
commandName={scanCommand}
arguments={scanArgs}
wordsTyped={2}
/>
)

const autocompleteComponent = queryByTestId(CliAutocompleteTestId)

expect(autocompleteOptionalText).toEqual(autocompleteComponent?.textContent)
})

it('Autocomplete should be only with optional args for "scan" command with filled in required args (old realization)', () => {
const autocompleteOptionalText = '[pattern] [count] [type]'
const { queryByTestId } = render(
<CliAutocomplete
{...instance(mockedProps)}
provider="someprovider"
commandName={scanCommand}
arguments={scanArgs}
wordsTyped={2}
/>
)

const autocompleteComponent = queryByTestId(CliAutocompleteTestId)

expect(autocompleteOptionalText).toEqual(autocompleteComponent?.textContent)
})

it('Autocomplete should be only with optional args for "scan" command with filled in required args (old realization)', () => {
const autocompleteOptionalText = '[pattern] [count] [type]'
const { queryByTestId } = render(
<CliAutocomplete
{...instance(mockedProps)}
Expand All @@ -100,6 +134,7 @@ describe('CliAutocomplete', () => {
const { queryByTestId } = render(
<CliAutocomplete
{...instance(mockedProps)}
provider="main"
commandName={scanCommand}
arguments={scanArgs}
wordsTyped={10}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ import { setMatchedCommand, clearSearchingCommand } from 'uiSrc/slices/cli/cli-s
import styles from './styles.module.scss'

export interface Props {
provider: string;
commandName: string;
wordsTyped: number;
arguments?: ICommandArg[];
}

const CliAutocomplete = (props: Props) => {
const { commandName = '', arguments: args = [], wordsTyped } = props
const { commandName = '', provider = '', arguments: args = [], wordsTyped } = props

const dispatch = useDispatch()

Expand Down Expand Up @@ -47,7 +48,7 @@ const CliAutocomplete = (props: Props) => {
}

if (args.length) {
argsList = generateArgsNames(args)
argsList = generateArgsNames(provider, args)

untypedArgs = argsList.slice(getUntypedArgs()).join(' ')
argsList = argsList.join(' ')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useSelector } from 'react-redux'
import { getCommandRepeat } from 'uiSrc/utils'
import { appRedisCommandsSelector } from 'uiSrc/slices/app/redis-commands'
import { outputSelector } from 'uiSrc/slices/cli/cli-output'
import { CommandProvider } from 'uiSrc/constants'
import CliAutocomplete from './CliAutocomplete'

import CliInput from './CliInput'
Expand All @@ -26,7 +27,8 @@ const CliInputWrapper = (props: Props) => {
const firstCommandMatch = firstCommand.toUpperCase()
const secondCommandMatch = `${firstCommandMatch} ${secondCommand ? secondCommand.toUpperCase() : null}`

const matchedCmd = ALL_REDIS_COMMANDS[firstCommandMatch] || ALL_REDIS_COMMANDS[secondCommandMatch]
const matchedCmd = ALL_REDIS_COMMANDS[secondCommandMatch] || ALL_REDIS_COMMANDS[firstCommandMatch]
const provider = matchedCmd?.provider || CommandProvider.Unknown
const commandName = !isUndefined(ALL_REDIS_COMMANDS[secondCommandMatch])
? `${firstCommand} ${secondCommand}`
: firstCommand
Expand All @@ -42,6 +44,7 @@ const CliInputWrapper = (props: Props) => {
/>
{matchedCmd && (
<CliAutocomplete
provider={provider}
commandName={commandName}
wordsTyped={repeatCommand === 1 ? wordsTyped : wordsTyped - 1}
{...matchedCmd}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,8 @@ const mockedCommands: IMockedCommands[] = [
{
matchedCommand: 'xgroup',
argStr:
'XGROUP [CREATE key groupname ID|$ [MKSTREAM]] [SETID key groupname ID|$] [DESTROY key groupname] [CREATECONSUMER key groupname consumername] [DELCONSUMER key groupname consumername]',
argListText:
'Arguments:Optional[CREATE key groupname id [MKSTREAM]]Optional[SETID key groupname id]Optional[DESTROY key groupname]Optional[CREATECONSUMER key groupname consumername]Optional[DELCONSUMER key groupname consumername]',
'XGROUP',
argListText: '',
},
{
matchedCommand: 'hset',
Expand All @@ -68,28 +67,28 @@ const mockedCommands: IMockedCommands[] = [
{
matchedCommand: 'bitfield',
argStr:
'BITFIELD key [GET type offset] [SET type offset value] [INCRBY type offset increment] [OVERFLOW WRAP|SAT|FAIL]',
'BITFIELD key [GET encoding offset | [OVERFLOW WRAP | SAT | FAIL] SET encoding offset value | INCRBY encoding offset increment [GET encoding offset | [OVERFLOW WRAP | SAT | FAIL] SET encoding offset value | INCRBY encoding offset increment ...]]',
argListText:
'Arguments:RequiredkeyOptional[GET type offset]Optional[SET type offset value]Optional[INCRBY type offset increment]Optional[OVERFLOW WRAP|SAT|FAIL]',
'Arguments:RequiredkeyMultiple[GET encoding offset | [OVERFLOW WRAP | SAT | FAIL] SET encoding offset value | INCRBY encoding offset increment]',
},
{
matchedCommand: 'client kill',
argStr:
'CLIENT KILL [ip:port] [ID client-id] [TYPE normal|master|slave|pubsub] [USER username] [ADDR ip:port] [LADDR ip:port] [SKIPME yes/no]',
'CLIENT KILL ip:port | [ID client-id] | [TYPE NORMAL | MASTER | SLAVE | REPLICA | PUBSUB] | [USER username] | [ADDR ip:port] | [LADDR ip:port] | [SKIPME YES | NO] [[ID client-id] | [TYPE NORMAL | MASTER | SLAVE | REPLICA | PUBSUB] | [USER username] | [ADDR ip:port] | [LADDR ip:port] | [SKIPME YES | NO] ...]',
argListText:
'Arguments:Optional[ip:port]Optional[ID client-id]Optional[TYPE normal|master|slave|pubsub]Optional[USER username]Optional[ADDR ip:port]Optional[LADDR ip:port]Optional[SKIPME yes/no]',
'Arguments:Requiredip:port | [ID client-id] | [TYPE NORMAL | MASTER | SLAVE | REPLICA | PUBSUB] | [USER username] | [ADDR ip:port] | [LADDR ip:port] | [SKIPME YES | NO] [[ID client-id] | [TYPE NORMAL | MASTER | SLAVE | REPLICA | PUBSUB] | [USER username] | [ADDR ip:port] | [LADDR ip:port] | [SKIPME YES | NO] ...]',
},
{
matchedCommand: 'geoadd',
argStr: 'GEOADD key [NX|XX] [CH] longitude latitude member [longitude latitude member ...]',
argStr: 'GEOADD key [NX | XX] [CH] longitude latitude member [longitude latitude member ...]',
argListText:
'Arguments:RequiredkeyOptional[condition]Optional[change]Multiplelongitude latitude member',
'Arguments:RequiredkeyOptional[NX | XX]Optional[CH]Multiplelongitude latitude member',
},
{
matchedCommand: 'zadd',
argStr: 'ZADD key [NX|XX] [GT|LT] [CH] [INCR] score member [score member ...]',
argStr: 'ZADD key [NX | XX] [GT | LT] [CH] [INCR] score member [score member ...]',
argListText:
'Arguments:RequiredkeyOptional[condition]Optional[comparison]Optional[change]Optional[increment]Multiplescore member',
'Arguments:RequiredkeyOptional[NX | XX]Optional[GT | LT]Optional[CH]Optional[INCR]Multiplescore member',
},
]

Expand Down Expand Up @@ -127,8 +126,10 @@ describe('CliBodyWrapper', () => {

const { unmount } = render(<CommandHelperWrapper />)

expect(screen.getByTestId(cliHelperTestId)).toBeInTheDocument()
expect(screen.getByTestId(argsId)).toHaveTextContent(argListText)
if (argListText) {
expect(screen.getByTestId(cliHelperTestId)).toBeInTheDocument()
expect(screen.getByTestId(argsId)).toHaveTextContent(argListText)
}

unmount()
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const CommandHelperWrapper = () => {
group = CommandGroup.Generic,
complexity = '',
since = '',
provider,
}: ICommand = ALL_REDIS_COMMANDS[lastMatchedCommand.toUpperCase()] ?? {}

if (isSearching) {
Expand All @@ -61,9 +62,9 @@ const CommandHelperWrapper = () => {
})
}

const generatedArgs = generateArgs(args)
const generatedArgs = generateArgs(provider, args)
const complexityShort = getComplexityShortNotation(complexity)
const argString = [lastMatchedCommand.toUpperCase(), ...generateArgsNames(args)].join(' ')
const argString = [lastMatchedCommand.toUpperCase(), ...generateArgsNames(provider, args)].join(' ')

const generateArgData = (arg: ICommandArgGenerated, i: number): ReactElement => {
const type = arg.multiple ? 'Multiple' : arg.optional ? 'Optional' : 'Required'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const CHSearchOutput = ({ searchedCommands }: Props) => {
const renderDescription = (command: string) => {
const args = ALL_REDIS_COMMANDS[command].arguments || []
if (args.length) {
const argString = generateArgsNames(args).join(' ')
const argString = generateArgsNames(ALL_REDIS_COMMANDS[command]?.provider, args).join(' ')
return (
<EuiText
size="s"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ const mockedCommands: IMockedCommands[] = [
},
{
matchedCommand: 'GEOADD',
argStr: 'key [NX|XX] [CH] longitude latitude member [longitude latitude member ...]',
argStr: 'key [NX | XX] [CH] longitude latitude member [longitude latitude member ...]',
},
{
matchedCommand: 'ZADD',
argStr: 'key [NX|XX] [GT|LT] [CH] [INCR] score member [score member ...]',
argStr: 'key [NX | XX] [GT | LT] [CH] [INCR] score member [score member ...]',
},
{
matchedCommand: 'RESET',
Expand Down
6 changes: 6 additions & 0 deletions redisinsight/ui/src/constants/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ export interface ICommand {
arguments?: ICommandArg[];
since: string;
group: CommandGroup | string;
provider?: string;
}

export enum CommandProvider {
Main = 'main',
Unknown = 'unknown',
}

export interface ICommandArg {
Expand Down
Loading