Files
dbx/apps/desktop/src/lib/redisCommandSafety.ts
T

83 lines
1.5 KiB
TypeScript

export type RedisCommandSafety = "allowed" | "confirm" | "blocked";
const BLOCKED_COMMANDS = new Set([
"KEYS",
"FLUSHALL",
"SHUTDOWN",
"CONFIG",
"SAVE",
"BGSAVE",
"SLAVEOF",
"REPLICAOF",
"MIGRATE",
"MODULE",
"SCRIPT",
"EVAL",
"EVALSHA",
]);
const CONFIRM_COMMANDS = new Set([
"DEL",
"UNLINK",
"EXPIRE",
"EXPIREAT",
"PEXPIRE",
"PEXPIREAT",
"PERSIST",
"RENAME",
"RENAMENX",
"SET",
"SETEX",
"PSETEX",
"SETNX",
"MSET",
"MSETNX",
"HSET",
"HDEL",
"LPUSH",
"RPUSH",
"LPOP",
"RPOP",
"LSET",
"LREM",
"SADD",
"SREM",
"ZADD",
"ZREM",
"XADD",
"XDEL",
"FLUSHDB",
]);
export function firstRedisCommandToken(command: string): string {
const trimmed = command.trimStart();
if (!trimmed) return "";
const quote = trimmed[0] === '"' || trimmed[0] === "'" ? trimmed[0] : "";
let token = "";
let escaping = false;
for (let i = quote ? 1 : 0; i < trimmed.length; i++) {
const ch = trimmed[i];
if (escaping) {
token += ch;
escaping = false;
continue;
}
if (ch === "\\") {
escaping = true;
continue;
}
if (quote && ch === quote) break;
if (!quote && /\s/.test(ch)) break;
token += ch;
}
return token.toUpperCase();
}
export function classifyRedisCommandSafety(command: string): RedisCommandSafety {
const token = firstRedisCommandToken(command);
if (BLOCKED_COMMANDS.has(token)) return "blocked";
if (CONFIRM_COMMANDS.has(token)) return "confirm";
return "allowed";
}