package redis import ( "context" "errors" "apigo.cc/go/jsmod" ) func init() { jsmod.Register("redis", map[string]any{ "get": func(ctx context.Context, name string) (*jsRedis, error) { rd := GetRedis(name, nil) if rd.Error != nil { return nil, rd.Error } return &jsRedis{rd: rd, ctx: ctx}, nil }, }) } type jsRedis struct { rd *Redis ctx context.Context } var errSafeMode = errors.New("redis write operation is restricted in safe mode") func (jr *jsRedis) checkSafe() error { if jsmod.IsSafeMode(jr.ctx) { return errSafeMode } return nil } // Read Operations (Always allowed) func (jr *jsRedis) GET(key string) *Result { return jr.rd.GET(key) } func (jr *jsRedis) EXISTS(key string) bool { return jr.rd.EXISTS(key) } func (jr *jsRedis) HGET(key, field string) *Result { return jr.rd.HGET(key, field) } func (jr *jsRedis) HGETALL(key string) map[string]*Result { return jr.rd.HGETALL(key) } func (jr *jsRedis) HEXISTS(key, field string) bool { return jr.rd.HEXISTS(key, field) } func (jr *jsRedis) HLEN(key string) int { return jr.rd.HLEN(key) } func (jr *jsRedis) HKEYS(key string) []string { return jr.rd.HKEYS(key) } func (jr *jsRedis) LLEN(key string) int { return jr.rd.LLEN(key) } func (jr *jsRedis) LRANGE(key string, start, stop int) []Result { return jr.rd.LRANGE(key, start, stop) } func (jr *jsRedis) SMEMBERS(key string) []Result { return jr.rd.SMEMBERS(key) } func (jr *jsRedis) SCARD(key string) int { return jr.rd.SCARD(key) } func (jr *jsRedis) SISMEMBER(key string, value any) bool { return jr.rd.SISMEMBER(key, value) } func (jr *jsRedis) ZRANGE(key string, start, stop int) []Result { return jr.rd.ZRANGE(key, start, stop) } func (jr *jsRedis) ZREVRANGE(key string, start, stop int) []Result { return jr.rd.ZREVRANGE(key, start, stop) } func (jr *jsRedis) ZCARD(key string) int { return jr.rd.ZCARD(key) } func (jr *jsRedis) ZRANK(key string, member any) int { return jr.rd.ZRANK(key, member) } func (jr *jsRedis) ZREVRANK(key string, member any) int { return jr.rd.ZREVRANK(key, member) } func (jr *jsRedis) ZSCORE(key string, member any) float64 { return jr.rd.ZSCORE(key, member) } // Write Operations (Restricted in SafeMode) func (jr *jsRedis) SET(key string, value any) bool { if jr.checkSafe() != nil { return false } return jr.rd.SET(key, value) } func (jr *jsRedis) SETEX(key string, seconds int, value any) bool { if jr.checkSafe() != nil { return false } return jr.rd.SETEX(key, seconds, value) } func (jr *jsRedis) SETNX(key string, value any) bool { if jr.checkSafe() != nil { return false } return jr.rd.SETNX(key, value) } func (jr *jsRedis) DEL(keys ...string) int { if jr.checkSafe() != nil { return 0 } return jr.rd.DEL(keys...) } func (jr *jsRedis) EXPIRE(key string, second int) bool { if jr.checkSafe() != nil { return false } return jr.rd.EXPIRE(key, second) } func (jr *jsRedis) INCR(key string) int64 { if jr.checkSafe() != nil { return 0 } return jr.rd.INCR(key) } func (jr *jsRedis) INCRBY(key string, delta int64) int64 { if jr.checkSafe() != nil { return 0 } return jr.rd.INCRBY(key, delta) } func (jr *jsRedis) DECR(key string, delta int64) int64 { if jr.checkSafe() != nil { return 0 } return jr.rd.DECR(key, delta) } func (jr *jsRedis) HSET(key, field string, value any) bool { if jr.checkSafe() != nil { return false } return jr.rd.HSET(key, field, value) } func (jr *jsRedis) HMSET(key string, fieldAndValues ...any) bool { if jr.checkSafe() != nil { return false } return jr.rd.HMSET(key, fieldAndValues...) } func (jr *jsRedis) HDEL(key string, fields ...string) int { if jr.checkSafe() != nil { return 0 } return jr.rd.HDEL(key, fields...) } func (jr *jsRedis) HINCRBY(key, field string, delta int64) int64 { if jr.checkSafe() != nil { return 0 } return jr.rd.HINCRBY(key, field, delta) } func (jr *jsRedis) LPUSH(key string, values ...string) int { if jr.checkSafe() != nil { return 0 } return jr.rd.LPUSH(key, values...) } func (jr *jsRedis) RPUSH(key string, values ...string) int { if jr.checkSafe() != nil { return 0 } return jr.rd.RPUSH(key, values...) } func (jr *jsRedis) LPOP(key string) *Result { if jr.checkSafe() != nil { return &Result{Error: errSafeMode} } return jr.rd.LPOP(key) } func (jr *jsRedis) RPOP(key string) *Result { if jr.checkSafe() != nil { return &Result{Error: errSafeMode} } return jr.rd.RPOP(key) } func (jr *jsRedis) SADD(key string, values ...any) int { if jr.checkSafe() != nil { return 0 } return jr.rd.SADD(key, values...) } func (jr *jsRedis) SREM(key string, values ...any) int { if jr.checkSafe() != nil { return 0 } return jr.rd.SREM(key, values...) } func (jr *jsRedis) ZADD(key string, score float64, member any) bool { if jr.checkSafe() != nil { return false } return jr.rd.ZADD(key, score, member) } func (jr *jsRedis) ZREM(key string, members ...any) int { if jr.checkSafe() != nil { return 0 } return jr.rd.ZREM(key, members...) } // Special: DO command must be restricted entirely in SafeMode to prevent bypassing func (jr *jsRedis) DO(cmd string, args ...any) *Result { if jr.checkSafe() != nil { return &Result{Error: errSafeMode} } return jr.rd.Do(cmd, args...) }