or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# Redis Commands

1

2

Redis Commands is a Node.js library that provides comprehensive metadata and utilities for all Redis commands. It enables Redis client libraries and applications to programmatically validate commands, check command flags, and extract key indexes from command arguments without hardcoding command lists or properties.

3

4

## Package Information

5

6

- **Package Name**: redis-commands

7

- **Package Type**: npm

8

- **Language**: JavaScript

9

- **Installation**: `npm install redis-commands`

10

11

## Core Imports

12

13

```javascript

14

const commands = require('redis-commands');

15

```

16

17

For ES modules:

18

19

```javascript

20

import * as commands from 'redis-commands';

21

```

22

23

## Basic Usage

24

25

```javascript

26

const commands = require('redis-commands');

27

28

// Check if a command exists

29

if (commands.exists('set')) {

30

console.log('SET command is supported');

31

}

32

33

// Check command flags

34

if (commands.hasFlag('get', 'readonly')) {

35

console.log('GET is a read-only command');

36

}

37

38

// Get key indexes for proper key handling

39

const keyIndexes = commands.getKeyIndexes('mget', ['key1', 'key2', 'key3']);

40

console.log(keyIndexes); // [0, 1, 2] - all arguments are keys

41

42

// List all available commands

43

console.log(`Total commands: ${commands.list.length}`);

44

commands.list.forEach(cmd => console.log(cmd));

45

```

46

47

## Architecture

48

49

Redis Commands is built around a comprehensive command database stored in `commands.json` that contains metadata for all Redis commands. The library provides three main components:

50

51

- **Command Database**: Complete Redis command metadata including arity, flags, and key position information

52

- **Flag Processing**: Runtime flag lookup system that processes command flags into indexed structures for fast access

53

- **Key Extraction Engine**: Sophisticated algorithm that handles different Redis command patterns to extract key positions from arguments

54

55

The library supports special command patterns including:

56

- **Variable key commands** (EVAL, EVALSHA): Keys determined by count parameters

57

- **Complex commands** (SORT): Optional external key parsing with pattern matching

58

- **Multi-operation commands** (ZUNIONSTORE, ZINTERSTORE): Multiple key types (destination + sources)

59

- **Stream commands** (XREAD, XREADGROUP): Keys extracted from STREAMS arguments

60

61

## Capabilities

62

63

### Command List

64

65

Access to the complete list of Redis commands in lowercase format.

66

67

```javascript { .api }

68

/**

69

* Array containing all Redis command names in lowercase

70

* @type {string[]}

71

*/

72

list

73

```

74

75

### Command Existence Check

76

77

Verify if a Redis command exists in the supported command set.

78

79

```javascript { .api }

80

/**

81

* Check if the Redis command exists

82

* @param {string} commandName - The command name to check

83

* @returns {boolean} True if command exists, false otherwise

84

*/

85

function exists(commandName)

86

```

87

88

**Usage Examples:**

89

90

```javascript

91

// Case-sensitive - commands must be lowercase

92

commands.exists('set'); // true

93

commands.exists('get'); // true

94

commands.exists('SET'); // false - must be lowercase

95

commands.exists('unknown'); // false

96

```

97

98

### Command Flag Validation

99

100

Check if a Redis command has specific flags or properties.

101

102

```javascript { .api }

103

/**

104

* Check if the command has the specified flag

105

* @param {string} commandName - The command name

106

* @param {string} flag - The flag to check (e.g., 'readonly', 'write', 'noscript', 'loading', 'denyoom', 'fast', 'admin', etc.)

107

* @returns {boolean} True if command has the flag, false otherwise

108

* @throws {Error} When commandName is unknown

109

*/

110

function hasFlag(commandName, flag)

111

```

112

113

**Common Flags:**

114

- `readonly` - Command only reads data

115

- `write` - Command writes/modifies data

116

- `denyoom` - Command denied when Redis is out of memory

117

- `admin` - Administrative command

118

- `noscript` - Cannot be used in Lua scripts

119

- `loading` - Can be used during Redis loading

120

- `stale` - Can work with stale data

121

- `fast` - Fast command execution

122

- `skip_slowlog` - Skip slow query log

123

- `skip_monitor` - Skip monitoring

124

- `no_auth` - No authentication required

125

126

**Usage Examples:**

127

128

```javascript

129

// Check if commands are read-only

130

commands.hasFlag('get', 'readonly'); // true

131

commands.hasFlag('set', 'readonly'); // false

132

commands.hasFlag('set', 'write'); // true

133

134

// Check administrative commands

135

commands.hasFlag('flushdb', 'admin'); // true

136

137

// Error handling

138

try {

139

commands.hasFlag('unknown', 'readonly');

140

} catch (error) {

141

console.log(error.message); // "Unknown command unknown"

142

}

143

```

144

145

### Key Index Extraction

146

147

Extract the indexes of key arguments from Redis command arguments for proper key handling in Redis clusters and sharding.

148

149

```javascript { .api }

150

/**

151

* Get indexes of keys in the command arguments

152

* @param {string} commandName - The Redis command name

153

* @param {string[]} args - The command arguments array

154

* @param {object} [options] - Optional configuration

155

* @param {boolean} [options.parseExternalKey] - Parse external keys for SORT command (default: false)

156

* @returns {number[]} Array of indexes pointing to key arguments in the args array

157

* @throws {Error} When commandName is unknown

158

* @throws {Error} When args is not an array

159

*/

160

function getKeyIndexes(commandName, args, options)

161

```

162

163

**Usage Examples:**

164

165

```javascript

166

// Simple key commands

167

commands.getKeyIndexes('get', ['mykey']);

168

// Returns: [0] - first argument is the key

169

170

commands.getKeyIndexes('set', ['mykey', 'value']);

171

// Returns: [0] - first argument is the key

172

173

// Multiple key commands

174

commands.getKeyIndexes('mget', ['key1', 'key2', 'key3']);

175

// Returns: [0, 1, 2] - all arguments are keys

176

177

commands.getKeyIndexes('mset', ['key1', 'val1', 'key2', 'val2']);

178

// Returns: [0, 2] - keys are at even indexes

179

180

// Complex commands with variable key patterns

181

commands.getKeyIndexes('eval', ['script', '2', 'key1', 'key2', 'arg1']);

182

// Returns: [2, 3] - keys follow the key count parameter

183

184

commands.getKeyIndexes('zunionstore', ['dest', '2', 'set1', 'set2', 'WEIGHTS', '1', '2']);

185

// Returns: [0, 2, 3] - destination key and source keys

186

187

// SORT command with external key parsing

188

commands.getKeyIndexes('sort', ['mylist', 'BY', 'weight_*', 'GET', 'name_*'], {

189

parseExternalKey: true

190

});

191

// Returns key indexes including external key references

192

193

// Commands with no keys

194

commands.getKeyIndexes('ping', []);

195

// Returns: [] - PING has no key arguments

196

197

// Error handling

198

try {

199

commands.getKeyIndexes('get', 'not-an-array');

200

} catch (error) {

201

console.log(error.message); // "Expect args to be an array"

202

}

203

204

try {

205

commands.getKeyIndexes('unknown', []);

206

} catch (error) {

207

console.log(error.message); // "Unknown command unknown"

208

}

209

```

210

211

**Special Command Handling:**

212

213

The library includes special logic for complex commands:

214

215

- **EVAL/EVALSHA**: Keys determined by the key count parameter

216

- **SORT**: Supports external key parsing with `parseExternalKey` option

217

- **MIGRATE**: Handles both single key and KEYS list variants

218

- **XREAD/XREADGROUP**: Extracts keys from STREAMS arguments

219

- **ZUNIONSTORE/ZINTERSTORE**: Includes destination and source keys

220

221

**Advanced Usage Examples:**

222

223

```javascript

224

// Redis Cluster key validation

225

function validateKeysForCluster(commandName, args) {

226

const keyIndexes = commands.getKeyIndexes(commandName, args);

227

const keys = keyIndexes.map(index => args[index]);

228

229

// In Redis Cluster, all keys in a multi-key command must hash to the same slot

230

if (keys.length > 1) {

231

console.log(`Multi-key command ${commandName} uses keys:`, keys);

232

// Additional cluster slot validation would go here

233

}

234

235

return keys;

236

}

237

238

// Redis proxy command filtering

239

function isReadOnlyCommand(commandName) {

240

return commands.exists(commandName) && commands.hasFlag(commandName, 'readonly');

241

}

242

243

// Route read-only commands to read replicas

244

function routeCommand(commandName, args) {

245

if (isReadOnlyCommand(commandName)) {

246

return routeToReadReplica(commandName, args);

247

} else {

248

return routeToMaster(commandName, args);

249

}

250

}

251

252

// Memory usage optimization - deny commands that could cause OOM

253

function checkMemoryConstraints(commandName) {

254

if (commands.hasFlag(commandName, 'denyoom')) {

255

if (getMemoryUsage() > MEMORY_THRESHOLD) {

256

throw new Error(`Command ${commandName} denied due to memory constraints`);

257

}

258

}

259

}

260

```

261

262

## Types

263

264

```javascript { .api }

265

/**

266

* Configuration options for getKeyIndexes function

267

* @typedef {Object} GetKeyIndexesOptions

268

* @property {boolean} [parseExternalKey=false] - Parse external keys for SORT command

269

*/

270

271

/**

272

* Redis command metadata structure (internal use)

273

* @typedef {Object} CommandMetadata

274

* @property {number} arity - Number of arguments (-N means at least N arguments)

275

* @property {string[]} flags - Array of command flags/properties

276

* @property {number} keyStart - Starting index for keys in arguments (1-based)

277

* @property {number} keyStop - Ending index for keys in arguments (1-based, 0 means no keys)

278

* @property {number} step - Step size for key iteration

279

*/

280

```

281

282

## Error Handling

283

284

The library throws `Error` objects for invalid inputs:

285

286

- **Unknown command**: When `commandName` doesn't exist in the command database

287

- **Invalid arguments**: When `args` parameter is not an array for `getKeyIndexes()`

288

289

```javascript

290

// Handle unknown commands

291

try {

292

commands.hasFlag('invalidcmd', 'readonly');

293

} catch (error) {

294

if (error.message.includes('Unknown command')) {

295

console.log('Command not supported');

296

}

297

}

298

299

// Handle invalid arguments

300

try {

301

commands.getKeyIndexes('get', 'invalid');

302

} catch (error) {

303

if (error.message.includes('Expect args to be an array')) {

304

console.log('Arguments must be an array');

305

}

306

}

307

```