From b5116fa3174b88eebee1e1901bf5f63aa391ea96 Mon Sep 17 00:00:00 2001 From: AI Engineer Date: Sat, 30 May 2026 19:44:31 +0800 Subject: [PATCH] feat: simplify redis jsmod registration and add id helpers --- js_export.go | 189 ++++++++------------------------------------------- 1 file changed, 30 insertions(+), 159 deletions(-) diff --git a/js_export.go b/js_export.go index 6952001..f5d2d72 100644 --- a/js_export.go +++ b/js_export.go @@ -4,6 +4,7 @@ import ( "context" "errors" + "apigo.cc/go/id" "apigo.cc/go/jsmod" ) @@ -20,11 +21,12 @@ func init() { } type jsRedis struct { - rd *Redis - ctx context.Context + rd *Redis + ctx context.Context + idMaker *id.IDMaker } -var errSafeMode = errors.New("redis write operation is restricted in safe mode") +var errSafeMode = errors.New("redis operation is restricted in safe mode") func (jr *jsRedis) checkSafe() error { if jsmod.IsSafeMode(jr.ctx) { @@ -33,164 +35,33 @@ func (jr *jsRedis) checkSafe() error { 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 { +// Do executes any redis command. In SafeMode, it only allows read-only commands. +// Note: Since we don't have a reliable way to categorize all redis commands as read-only, +// and 'DO' is used for everything, we strictly block 'DO' in SafeMode if it's not a known read-only command. +// For simplicity and maximum safety as requested, we block 'DO' entirely in SafeMode. +func (jr *jsRedis) Do(cmd string, args ...any) *Result { if jr.checkSafe() != nil { return &Result{Error: errSafeMode} } return jr.rd.Do(cmd, args...) } + +// ID Generation Helpers +func (jr *jsRedis) getIDMaker() *id.IDMaker { + if jr.idMaker == nil { + jr.idMaker = NewIDMaker(jr.rd) + } + return jr.idMaker +} + +func (jr *jsRedis) GetID(size int) string { + return jr.getIDMaker().Get(size) +} + +func (jr *jsRedis) GetForMysql(size int) string { + return jr.getIDMaker().GetForMysql(size) +} + +func (jr *jsRedis) GetForPostgreSQL(size int) string { + return jr.getIDMaker().GetForPostgreSQL(size) +}