or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-redis-commands

Redis commands library providing command metadata, validation, and key extraction utilities

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/redis-commands@1.7.x

To install, run

npx @tessl/cli install tessl/npm-redis-commands@1.7.0

index.mddocs/

Redis Commands

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.

Package Information

  • Package Name: redis-commands
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install redis-commands

Core Imports

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

For ES modules:

import * as commands from 'redis-commands';

Basic Usage

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

// Check if a command exists
if (commands.exists('set')) {
  console.log('SET command is supported');
}

// Check command flags
if (commands.hasFlag('get', 'readonly')) {
  console.log('GET is a read-only command');
}

// Get key indexes for proper key handling
const keyIndexes = commands.getKeyIndexes('mget', ['key1', 'key2', 'key3']);
console.log(keyIndexes); // [0, 1, 2] - all arguments are keys

// List all available commands
console.log(`Total commands: ${commands.list.length}`);
commands.list.forEach(cmd => console.log(cmd));

Architecture

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:

  • Command Database: Complete Redis command metadata including arity, flags, and key position information
  • Flag Processing: Runtime flag lookup system that processes command flags into indexed structures for fast access
  • Key Extraction Engine: Sophisticated algorithm that handles different Redis command patterns to extract key positions from arguments

The library supports special command patterns including:

  • Variable key commands (EVAL, EVALSHA): Keys determined by count parameters
  • Complex commands (SORT): Optional external key parsing with pattern matching
  • Multi-operation commands (ZUNIONSTORE, ZINTERSTORE): Multiple key types (destination + sources)
  • Stream commands (XREAD, XREADGROUP): Keys extracted from STREAMS arguments

Capabilities

Command List

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

/**
 * Array containing all Redis command names in lowercase
 * @type {string[]}
 */
list

Command Existence Check

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

/**
 * Check if the Redis command exists
 * @param {string} commandName - The command name to check
 * @returns {boolean} True if command exists, false otherwise
 */
function exists(commandName)

Usage Examples:

// Case-sensitive - commands must be lowercase
commands.exists('set');    // true
commands.exists('get');    // true
commands.exists('SET');    // false - must be lowercase
commands.exists('unknown'); // false

Command Flag Validation

Check if a Redis command has specific flags or properties.

/**
 * Check if the command has the specified flag
 * @param {string} commandName - The command name
 * @param {string} flag - The flag to check (e.g., 'readonly', 'write', 'noscript', 'loading', 'denyoom', 'fast', 'admin', etc.)
 * @returns {boolean} True if command has the flag, false otherwise
 * @throws {Error} When commandName is unknown
 */
function hasFlag(commandName, flag)

Common Flags:

  • readonly - Command only reads data
  • write - Command writes/modifies data
  • denyoom - Command denied when Redis is out of memory
  • admin - Administrative command
  • noscript - Cannot be used in Lua scripts
  • loading - Can be used during Redis loading
  • stale - Can work with stale data
  • fast - Fast command execution
  • skip_slowlog - Skip slow query log
  • skip_monitor - Skip monitoring
  • no_auth - No authentication required

Usage Examples:

// Check if commands are read-only
commands.hasFlag('get', 'readonly');    // true
commands.hasFlag('set', 'readonly');    // false
commands.hasFlag('set', 'write');       // true

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

// Error handling
try {
  commands.hasFlag('unknown', 'readonly');
} catch (error) {
  console.log(error.message); // "Unknown command unknown"
}

Key Index Extraction

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

/**
 * Get indexes of keys in the command arguments
 * @param {string} commandName - The Redis command name
 * @param {string[]} args - The command arguments array
 * @param {object} [options] - Optional configuration
 * @param {boolean} [options.parseExternalKey] - Parse external keys for SORT command (default: false)
 * @returns {number[]} Array of indexes pointing to key arguments in the args array
 * @throws {Error} When commandName is unknown
 * @throws {Error} When args is not an array
 */
function getKeyIndexes(commandName, args, options)

Usage Examples:

// Simple key commands
commands.getKeyIndexes('get', ['mykey']);
// Returns: [0] - first argument is the key

commands.getKeyIndexes('set', ['mykey', 'value']);
// Returns: [0] - first argument is the key

// Multiple key commands
commands.getKeyIndexes('mget', ['key1', 'key2', 'key3']);
// Returns: [0, 1, 2] - all arguments are keys

commands.getKeyIndexes('mset', ['key1', 'val1', 'key2', 'val2']);
// Returns: [0, 2] - keys are at even indexes

// Complex commands with variable key patterns
commands.getKeyIndexes('eval', ['script', '2', 'key1', 'key2', 'arg1']);
// Returns: [2, 3] - keys follow the key count parameter

commands.getKeyIndexes('zunionstore', ['dest', '2', 'set1', 'set2', 'WEIGHTS', '1', '2']);
// Returns: [0, 2, 3] - destination key and source keys

// SORT command with external key parsing
commands.getKeyIndexes('sort', ['mylist', 'BY', 'weight_*', 'GET', 'name_*'], {
  parseExternalKey: true
});
// Returns key indexes including external key references

// Commands with no keys
commands.getKeyIndexes('ping', []);
// Returns: [] - PING has no key arguments

// Error handling
try {
  commands.getKeyIndexes('get', 'not-an-array');
} catch (error) {
  console.log(error.message); // "Expect args to be an array"
}

try {
  commands.getKeyIndexes('unknown', []);
} catch (error) {
  console.log(error.message); // "Unknown command unknown"
}

Special Command Handling:

The library includes special logic for complex commands:

  • EVAL/EVALSHA: Keys determined by the key count parameter
  • SORT: Supports external key parsing with parseExternalKey option
  • MIGRATE: Handles both single key and KEYS list variants
  • XREAD/XREADGROUP: Extracts keys from STREAMS arguments
  • ZUNIONSTORE/ZINTERSTORE: Includes destination and source keys

Advanced Usage Examples:

// Redis Cluster key validation
function validateKeysForCluster(commandName, args) {
  const keyIndexes = commands.getKeyIndexes(commandName, args);
  const keys = keyIndexes.map(index => args[index]);
  
  // In Redis Cluster, all keys in a multi-key command must hash to the same slot
  if (keys.length > 1) {
    console.log(`Multi-key command ${commandName} uses keys:`, keys);
    // Additional cluster slot validation would go here
  }
  
  return keys;
}

// Redis proxy command filtering
function isReadOnlyCommand(commandName) {
  return commands.exists(commandName) && commands.hasFlag(commandName, 'readonly');
}

// Route read-only commands to read replicas
function routeCommand(commandName, args) {
  if (isReadOnlyCommand(commandName)) {
    return routeToReadReplica(commandName, args);
  } else {
    return routeToMaster(commandName, args);
  }
}

// Memory usage optimization - deny commands that could cause OOM
function checkMemoryConstraints(commandName) {
  if (commands.hasFlag(commandName, 'denyoom')) {
    if (getMemoryUsage() > MEMORY_THRESHOLD) {
      throw new Error(`Command ${commandName} denied due to memory constraints`);
    }
  }
}

Types

/**
 * Configuration options for getKeyIndexes function
 * @typedef {Object} GetKeyIndexesOptions
 * @property {boolean} [parseExternalKey=false] - Parse external keys for SORT command
 */

/**
 * Redis command metadata structure (internal use)
 * @typedef {Object} CommandMetadata
 * @property {number} arity - Number of arguments (-N means at least N arguments)
 * @property {string[]} flags - Array of command flags/properties
 * @property {number} keyStart - Starting index for keys in arguments (1-based)
 * @property {number} keyStop - Ending index for keys in arguments (1-based, 0 means no keys)
 * @property {number} step - Step size for key iteration
 */

Error Handling

The library throws Error objects for invalid inputs:

  • Unknown command: When commandName doesn't exist in the command database
  • Invalid arguments: When args parameter is not an array for getKeyIndexes()
// Handle unknown commands
try {
  commands.hasFlag('invalidcmd', 'readonly');
} catch (error) {
  if (error.message.includes('Unknown command')) {
    console.log('Command not supported');
  }
}

// Handle invalid arguments
try {
  commands.getKeyIndexes('get', 'invalid');
} catch (error) {
  if (error.message.includes('Expect args to be an array')) {
    console.log('Arguments must be an array');
  }
}